Merge "Remove unnecessary query in IMMS#switchUserOnHandlerLocked() (2nd try)" into main
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 553d9f7..5a0f3db 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -164,15 +164,9 @@
     void getFeature(IBinder token, int userId, int feature, IFaceServiceReceiver receiver,
             String opPackageName);
 
-    // Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
-    // AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
-    // hidlSensors must be non-null and empty. See AuthService.java
-    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void registerAuthenticators(in List<FaceSensorPropertiesInternal> hidlSensors);
-
     //Register all available face sensors.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void registerAuthenticatorsLegacy(in FaceSensorConfigurations faceSensorConfigurations);
+    void registerAuthenticators(in FaceSensorConfigurations faceSensorConfigurations);
 
     // Adds a callback which gets called when the service registers all of the face
     // authenticators. The callback is automatically removed after it's invoked.
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 8b37c24..6a96ac4 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -177,13 +177,7 @@
 
     //Register all available fingerprint sensors.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void registerAuthenticatorsLegacy(in FingerprintSensorConfigurations fingerprintSensorConfigurations);
-
-    // Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
-    // AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
-    // hidlSensors must be non-null and empty. See AuthService.java
-    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void registerAuthenticators(in List<FingerprintSensorPropertiesInternal> hidlSensors);
+    void registerAuthenticators(in FingerprintSensorConfigurations fingerprintSensorConfigurations);
 
     // Adds a callback which gets called when the service registers all of the fingerprint
     // authenticators. The callback is automatically removed after it's invoked.
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 8f1b72e..1034479 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -40,6 +40,7 @@
 import android.util.AndroidRuntimeException;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Slog;
 
 import java.io.File;
 import java.lang.reflect.Method;
@@ -609,7 +610,7 @@
             startedRelroProcesses = WebViewLibraryLoader.prepareNativeLibraries(packageInfo);
         } catch (Throwable t) {
             // Log and discard errors at this stage as we must not crash the system server.
-            Log.e(LOGTAG, "error preparing webview native library", t);
+            Slog.wtf(LOGTAG, "error preparing webview native library", t);
         }
 
         WebViewZygote.onWebViewProviderChanged(packageInfo);
diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java
index a68a577..1a8745c 100644
--- a/core/java/android/webkit/WebViewLibraryLoader.java
+++ b/core/java/android/webkit/WebViewLibraryLoader.java
@@ -25,6 +25,7 @@
 import android.os.Build;
 import android.os.Process;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
@@ -137,7 +138,7 @@
             if (!success) throw new Exception("Failed to start the relro file creator process");
         } catch (Throwable t) {
             // Log and discard errors as we must not crash the system server.
-            Log.e(LOGTAG, "error starting relro file creator for abi " + abi, t);
+            Slog.wtf(LOGTAG, "error starting relro file creator for abi " + abi, t);
             crashHandler.run();
         }
     }
diff --git a/core/java/android/window/IRemoteTransition.aidl b/core/java/android/window/IRemoteTransition.aidl
index ec8b66d..33421ba 100644
--- a/core/java/android/window/IRemoteTransition.aidl
+++ b/core/java/android/window/IRemoteTransition.aidl
@@ -19,6 +19,7 @@
 import android.view.SurfaceControl;
 import android.window.IRemoteTransitionFinishedCallback;
 import android.window.TransitionInfo;
+import android.window.WindowAnimationState;
 
 /**
  * Interface allowing remote processes to play transition animations.
@@ -61,6 +62,19 @@
             in IRemoteTransitionFinishedCallback finishCallback);
 
     /**
+     * Takes over the animation of the windows from an existing transition. Once complete, the
+     * implementation should call `finishCallback`.
+     *
+     * @param transition An identifier for the transition to be taken over.
+     * @param states The animation states of the windows involved in the transition. These must be
+     *               sorted in the same way as the Changes inside `info`, and each state may be
+     *               null.
+     */
+    void takeOverAnimation(in IBinder transition, in TransitionInfo info,
+            in SurfaceControl.Transaction t, in IRemoteTransitionFinishedCallback finishCallback,
+            in WindowAnimationState[] states);
+
+    /**
      * Called when a different handler has consumed the transition
      *
      * @param transition An identifier for the transition that was consumed.
diff --git a/core/java/android/window/RemoteTransitionStub.java b/core/java/android/window/RemoteTransitionStub.java
index c9932ab..4a97b1e 100644
--- a/core/java/android/window/RemoteTransitionStub.java
+++ b/core/java/android/window/RemoteTransitionStub.java
@@ -31,6 +31,16 @@
             SurfaceControl.Transaction t, IBinder mergeTarget,
             IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {}
 
+
+    @Override
+    public void takeOverAnimation(IBinder transition, TransitionInfo info,
+            SurfaceControl.Transaction startTransaction,
+            IRemoteTransitionFinishedCallback finishCallback,
+            WindowAnimationState[] states) throws RemoteException {
+        throw new RemoteException("Takeovers are not supported by this IRemoteTransition");
+    }
+
+
     @Override
     public void onTransitionConsumed(IBinder transition, boolean aborted)
             throws RemoteException {}
diff --git a/core/java/android/window/WindowAnimationState.aidl b/core/java/android/window/WindowAnimationState.aidl
new file mode 100644
index 0000000..e662860
--- /dev/null
+++ b/core/java/android/window/WindowAnimationState.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+/**
+ * Properties of a window animation at a given point in time.
+ *
+ * {@hide}
+ */
+parcelable WindowAnimationState {
+    long timestamp;
+    RectF bounds;
+    float scale;
+    float topLeftRadius;
+    float topRightRadius;
+    float bottomRightRadius;
+    float bottomLeftRadius;
+    PointF velocityPxPerMs;
+}
diff --git a/core/res/res/drawable/ic_private_profile_badge.xml b/core/res/res/drawable/ic_private_profile_badge.xml
index b042c39..8f7bbb5 100644
--- a/core/res/res/drawable/ic_private_profile_badge.xml
+++ b/core/res/res/drawable/ic_private_profile_badge.xml
@@ -20,6 +20,10 @@
         android:viewportWidth="24"
         android:viewportHeight="24">
         <path
-            android:pathData="M5,3H19C20.1,3 21,3.9 21,5V19C21,20.1 20.1,21 19,21H5C3.9,21 3,20.1 3,19V5C3,3.9 3.9,3 5,3ZM13.5,15.501L12.93,12.271C13.57,11.941 14,11.271 14,10.501C14,9.401 13.1,8.501 12,8.501C10.9,8.501 10,9.401 10,10.501C10,11.271 10.43,11.941 11.07,12.271L10.5,15.501H13.5Z"
+            android:pathData="M12,2L4,5V11.09C4,16.14 7.41,20.85 12,22C16.59,20.85 20,16.14 20,11.09V5L12,2ZM15,15V17H13V18H11V12.84C9.56,12.41 8.5,11.09 8.5,9.5C8.5,7.57 10.07,6 12,6C13.93,6 15.5,7.57 15.5,9.5C15.5,11.08 14.44,12.41 13,12.84V15H15Z"
+            android:fillColor="#3C4043"
+            android:fillType="evenOdd"/>
+        <path
+            android:pathData="M12,11C12.828,11 13.5,10.328 13.5,9.5C13.5,8.672 12.828,8 12,8C11.172,8 10.5,8.672 10.5,9.5C10.5,10.328 11.172,11 12,11Z"
             android:fillColor="#3C4043"/>
 </vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_private_profile_icon_badge.xml b/core/res/res/drawable/ic_private_profile_icon_badge.xml
index 5f1f1b7..4143c3b 100644
--- a/core/res/res/drawable/ic_private_profile_icon_badge.xml
+++ b/core/res/res/drawable/ic_private_profile_icon_badge.xml
@@ -24,8 +24,12 @@
         android:scaleY=".66"
         android:translateX="42"
         android:translateY="42">
-            <path
-                android:pathData="M5,3H19C20.1,3 21,3.9 21,5V19C21,20.1 20.1,21 19,21H5C3.9,21 3,20.1 3,19V5C3,3.9 3.9,3 5,3ZM13.5,15.501L12.93,12.271C13.57,11.941 14,11.271 14,10.501C14,9.401 13.1,8.501 12,8.501C10.9,8.501 10,9.401 10,10.501C10,11.271 10.43,11.941 11.07,12.271L10.5,15.501H13.5Z"
-                android:fillColor="#3C4043"/>
+        <path
+            android:pathData="M12,2L4,5V11.09C4,16.14 7.41,20.85 12,22C16.59,20.85 20,16.14 20,11.09V5L12,2ZM15,15V17H13V18H11V12.84C9.56,12.41 8.5,11.09 8.5,9.5C8.5,7.57 10.07,6 12,6C13.93,6 15.5,7.57 15.5,9.5C15.5,11.08 14.44,12.41 13,12.84V15H15Z"
+            android:fillColor="#3C4043"
+            android:fillType="evenOdd"/>
+        <path
+            android:pathData="M12,11C12.828,11 13.5,10.328 13.5,9.5C13.5,8.672 12.828,8 12,8C11.172,8 10.5,8.672 10.5,9.5C10.5,10.328 11.172,11 12,11Z"
+            android:fillColor="#3C4043"/>
     </group>
 </vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/stat_sys_private_profile_status.xml b/core/res/res/drawable/stat_sys_private_profile_status.xml
index 429070e..958a4d7 100644
--- a/core/res/res/drawable/stat_sys_private_profile_status.xml
+++ b/core/res/res/drawable/stat_sys_private_profile_status.xml
@@ -20,6 +20,10 @@
         android:viewportWidth="24"
         android:viewportHeight="24">
     <path
+        android:pathData="M12,2L4,5V11.09C4,16.14 7.41,20.85 12,22C16.59,20.85 20,16.14 20,11.09V5L12,2ZM15,15V17H13V18H11V12.84C9.56,12.41 8.5,11.09 8.5,9.5C8.5,7.57 10.07,6 12,6C13.93,6 15.5,7.57 15.5,9.5C15.5,11.08 14.44,12.41 13,12.84V15H15Z"
         android:fillColor="@android:color/white"
-        android:pathData="M5,3H19C20.1,3 21,3.9 21,5V19C21,20.1 20.1,21 19,21H5C3.9,21 3,20.1 3,19V5C3,3.9 3.9,3 5,3ZM13.5,15.501L12.93,12.271C13.57,11.941 14,11.271 14,10.501C14,9.401 13.1,8.501 12,8.501C10.9,8.501 10,9.401 10,10.501C10,11.271 10.43,11.941 11.07,12.271L10.5,15.501H13.5Z"/>
+        android:fillType="evenOdd"/>
+    <path
+        android:pathData="M12,11C12.828,11 13.5,10.328 13.5,9.5C13.5,8.672 12.828,8 12,8C11.172,8 10.5,8.672 10.5,9.5C10.5,10.328 11.172,11 12,11Z"
+        android:fillColor="@android:color/white"/>
 </vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
index b8ac191..0a5a81b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -25,8 +25,8 @@
 import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_DECOR_SURFACE_BOOSTED;
 
-import static androidx.window.extensions.embedding.DividerAttributes.RATIO_UNSET;
-import static androidx.window.extensions.embedding.DividerAttributes.WIDTH_UNSET;
+import static androidx.window.extensions.embedding.DividerAttributes.RATIO_SYSTEM_DEFAULT;
+import static androidx.window.extensions.embedding.DividerAttributes.WIDTH_SYSTEM_DEFAULT;
 import static androidx.window.extensions.embedding.SplitAttributesHelper.isReversedLayout;
 import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
 import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
@@ -64,6 +64,9 @@
 import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.window.extensions.core.util.function.Consumer;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType.ExpandContainersSplitType;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -76,12 +79,13 @@
  * Manages the rendering and interaction of the divider.
  */
 class DividerPresenter implements View.OnTouchListener {
+    static final float RATIO_EXPANDED_PRIMARY = 1.0f;
+    static final float RATIO_EXPANDED_SECONDARY = 0.0f;
     private static final String WINDOW_NAME = "AE Divider";
     private static final int VEIL_LAYER = 0;
     private static final int DIVIDER_LAYER = 1;
 
     // TODO(b/327067596) Update based on UX guidance.
-    private static final Color DEFAULT_DIVIDER_COLOR = Color.valueOf(Color.BLACK);
     private static final Color DEFAULT_PRIMARY_VEIL_COLOR = Color.valueOf(Color.BLACK);
     private static final Color DEFAULT_SECONDARY_VEIL_COLOR = Color.valueOf(Color.GRAY);
     @VisibleForTesting
@@ -162,54 +166,55 @@
                 return;
             }
 
+            final SplitAttributes splitAttributes = topSplitContainer.getCurrentSplitAttributes();
+            final DividerAttributes dividerAttributes = splitAttributes.getDividerAttributes();
+
             // Clean up the decor surface if DividerAttributes is null.
-            final DividerAttributes dividerAttributes =
-                    topSplitContainer.getCurrentSplitAttributes().getDividerAttributes();
             if (dividerAttributes == null) {
                 removeDecorSurfaceAndDivider(wct);
                 return;
             }
 
-            if (topSplitContainer.getCurrentSplitAttributes().getSplitType()
-                    instanceof SplitAttributes.SplitType.ExpandContainersSplitType) {
-                // No divider is needed for ExpandContainersSplitType.
-                removeDivider();
-                return;
-            }
+            // At this point, a divider is required.
 
-            // Skip updating when the TFs have not been updated to match the SplitAttributes.
-            if (topSplitContainer.getPrimaryContainer().getLastRequestedBounds().isEmpty()
-                    || topSplitContainer.getSecondaryContainer().getLastRequestedBounds()
-                    .isEmpty()) {
-                return;
-            }
-
+            // Create the decor surface if one is not available yet.
             final SurfaceControl decorSurface = parentInfo.getDecorSurface();
             if (decorSurface == null) {
                 // Clean up when the decor surface is currently unavailable.
                 removeDivider();
                 // Request to create the decor surface
-                createOrMoveDecorSurface(wct, topSplitContainer.getPrimaryContainer());
+                createOrMoveDecorSurfaceLocked(wct, topSplitContainer.getPrimaryContainer());
                 return;
             }
 
-            // make the top primary container the owner of the decor surface.
-            if (!Objects.equals(mDecorSurfaceOwner,
-                    topSplitContainer.getPrimaryContainer().getTaskFragmentToken())) {
-                createOrMoveDecorSurface(wct, topSplitContainer.getPrimaryContainer());
+            // Update the decor surface owner if needed.
+            boolean isDraggableExpandType =
+                    SplitAttributesHelper.isDraggableExpandType(splitAttributes);
+            final TaskFragmentContainer decorSurfaceOwnerContainer = isDraggableExpandType
+                    ? topSplitContainer.getSecondaryContainer()
+                    : topSplitContainer.getPrimaryContainer();
+
+            if (!Objects.equals(
+                    mDecorSurfaceOwner, decorSurfaceOwnerContainer.getTaskFragmentToken())) {
+                createOrMoveDecorSurfaceLocked(wct, decorSurfaceOwnerContainer);
             }
+            final boolean isVerticalSplit = isVerticalSplit(topSplitContainer);
+            final boolean isReversedLayout = isReversedLayout(
+                    topSplitContainer.getCurrentSplitAttributes(),
+                    parentInfo.getConfiguration());
 
             updateProperties(
                     new Properties(
                             parentInfo.getConfiguration(),
                             dividerAttributes,
                             decorSurface,
-                            getInitialDividerPosition(topSplitContainer),
-                            isVerticalSplit(topSplitContainer),
-                            isReversedLayout(
-                                    topSplitContainer.getCurrentSplitAttributes(),
-                                    parentInfo.getConfiguration()),
-                            parentInfo.getDisplayId()));
+                            getInitialDividerPosition(
+                                    topSplitContainer, isVerticalSplit, isReversedLayout),
+                            isVerticalSplit,
+                            isReversedLayout,
+                            parentInfo.getDisplayId(),
+                            isDraggableExpandType
+                    ));
         }
     }
 
@@ -242,14 +247,21 @@
      *
      * See {@link TaskFragmentOperation#OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE}.
      */
-    @GuardedBy("mLock")
-    private void createOrMoveDecorSurface(
+    void createOrMoveDecorSurface(
             @NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container) {
+        synchronized (mLock) {
+            createOrMoveDecorSurfaceLocked(wct, container);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void createOrMoveDecorSurfaceLocked(
+            @NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container) {
+        mDecorSurfaceOwner = container.getTaskFragmentToken();
         final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
                 OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE)
                 .build();
-        wct.addTaskFragmentOperation(container.getTaskFragmentToken(), operation);
-        mDecorSurfaceOwner = container.getTaskFragmentToken();
+        wct.addTaskFragmentOperation(mDecorSurfaceOwner, operation);
     }
 
     @GuardedBy("mLock")
@@ -274,15 +286,28 @@
     }
 
     @VisibleForTesting
-    static int getInitialDividerPosition(@NonNull SplitContainer splitContainer) {
+    static int getInitialDividerPosition(
+            @NonNull SplitContainer splitContainer,
+            boolean isVerticalSplit,
+            boolean isReversedLayout) {
         final Rect primaryBounds =
                 splitContainer.getPrimaryContainer().getLastRequestedBounds();
         final Rect secondaryBounds =
                 splitContainer.getSecondaryContainer().getLastRequestedBounds();
-        if (isVerticalSplit(splitContainer)) {
-            return Math.min(primaryBounds.right, secondaryBounds.right);
+        final SplitAttributes splitAttributes = splitContainer.getCurrentSplitAttributes();
+
+        if (SplitAttributesHelper.isDraggableExpandType(splitAttributes)) {
+            // If the container is fully expanded by dragging the divider, we display the divider
+            // on the edge.
+            final int dividerWidth = getDividerWidthPx(splitAttributes.getDividerAttributes());
+            final int fullyExpandedPosition = isVerticalSplit
+                    ? primaryBounds.right - dividerWidth
+                    : primaryBounds.bottom - dividerWidth;
+            return isReversedLayout ? fullyExpandedPosition : 0;
         } else {
-            return Math.min(primaryBounds.bottom, secondaryBounds.bottom);
+            return isVerticalSplit
+                    ? Math.min(primaryBounds.right, secondaryBounds.right)
+                    : Math.min(primaryBounds.bottom, secondaryBounds.bottom);
         }
     }
 
@@ -359,14 +384,14 @@
     @VisibleForTesting
     static int getBoundsOffsetForDivider(
             int dividerWidthPx,
-            @NonNull SplitAttributes.SplitType splitType,
+            @NonNull SplitType splitType,
             @SplitPresenter.ContainerPosition int position) {
-        if (splitType instanceof SplitAttributes.SplitType.ExpandContainersSplitType) {
-            // No divider is needed for the ExpandContainersSplitType.
+        if (splitType instanceof ExpandContainersSplitType) {
+            // No divider offset is needed for the ExpandContainersSplitType.
             return 0;
         }
         int primaryOffset;
-        if (splitType instanceof final SplitAttributes.SplitType.RatioSplitType splitRatio) {
+        if (splitType instanceof final RatioSplitType splitRatio) {
             // When a divider is present, both containers shrink by an amount proportional to their
             // split ratio and sum to the width of the divider, so that the ending sizing of the
             // containers still maintain the same ratio.
@@ -393,7 +418,8 @@
      * Sanitizes and sets default values in the {@link DividerAttributes}.
      *
      * Unset values will be set with system default values. See
-     * {@link DividerAttributes#WIDTH_UNSET} and {@link DividerAttributes#RATIO_UNSET}.
+     * {@link DividerAttributes#WIDTH_SYSTEM_DEFAULT} and
+     * {@link DividerAttributes#RATIO_SYSTEM_DEFAULT}.
      *
      * @param dividerAttributes input {@link DividerAttributes}
      * @return a {@link DividerAttributes} that has all values properly set.
@@ -405,7 +431,7 @@
             return null;
         }
         int widthDp = dividerAttributes.getWidthDp();
-        if (widthDp == WIDTH_UNSET) {
+        if (widthDp == WIDTH_SYSTEM_DEFAULT) {
             widthDp = DEFAULT_DIVIDER_WIDTH_DP;
         }
 
@@ -416,12 +442,12 @@
         }
 
         float minRatio = dividerAttributes.getPrimaryMinRatio();
-        if (minRatio == RATIO_UNSET) {
+        if (minRatio == RATIO_SYSTEM_DEFAULT) {
             minRatio = DEFAULT_MIN_RATIO;
         }
 
         float maxRatio = dividerAttributes.getPrimaryMaxRatio();
-        if (maxRatio == RATIO_UNSET) {
+        if (maxRatio == RATIO_SYSTEM_DEFAULT) {
             maxRatio = DEFAULT_MAX_RATIO;
         }
 
@@ -438,7 +464,7 @@
             final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
             mDividerPosition = calculateDividerPosition(
                     event, taskBounds, mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
-                    mProperties.mIsVerticalSplit, mProperties.mIsReversedLayout);
+                    mProperties.mIsVerticalSplit, calculateMinPosition(), calculateMaxPosition());
             mRenderer.setDividerPosition(mDividerPosition);
             switch (event.getAction()) {
                 case MotionEvent.ACTION_DOWN:
@@ -456,23 +482,27 @@
             }
         }
 
-        // Returns false so that the default button click callback is still triggered, i.e. the
-        // button UI transitions into the "pressed" state.
-        return false;
+        // Returns true to prevent the default button click callback. The button pressed state is
+        // set/unset when starting/finishing dragging.
+        return true;
     }
 
     @GuardedBy("mLock")
     private void onStartDragging() {
         mRenderer.mIsDragging = true;
+        mRenderer.mDragHandle.setPressed(mRenderer.mIsDragging);
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         mRenderer.updateSurface(t);
         mRenderer.showVeils(t);
-        final IBinder decorSurfaceOwner = mDecorSurfaceOwner;
 
         // Callbacks must be executed on the executor to release mLock and prevent deadlocks.
         mCallbackExecutor.execute(() -> {
             mDragEventCallback.onStartDragging(
-                    wct -> setDecorSurfaceBoosted(wct, decorSurfaceOwner, true /* boosted */, t));
+                    wct -> {
+                        synchronized (mLock) {
+                            setDecorSurfaceBoosted(wct, mDecorSurfaceOwner, true /* boosted */, t);
+                        }
+                    });
         });
     }
 
@@ -485,18 +515,62 @@
 
     @GuardedBy("mLock")
     private void onFinishDragging() {
+        mDividerPosition = adjustDividerPositionForSnapPoints(mDividerPosition);
+        mRenderer.setDividerPosition(mDividerPosition);
+
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         mRenderer.updateSurface(t);
         mRenderer.hideVeils(t);
-        final IBinder decorSurfaceOwner = mDecorSurfaceOwner;
 
         // Callbacks must be executed on the executor to release mLock and prevent deadlocks.
+        // mDecorSurfaceOwner may change between here and when the callback is executed,
+        // e.g. when the decor surface owner becomes the secondary container when it is expanded to
+        // fullscreen.
         mCallbackExecutor.execute(() -> {
             mDragEventCallback.onFinishDragging(
                     mTaskId,
-                    wct -> setDecorSurfaceBoosted(wct, decorSurfaceOwner, false /* boosted */, t));
+                    wct -> {
+                        synchronized (mLock) {
+                            setDecorSurfaceBoosted(wct, mDecorSurfaceOwner, false /* boosted */, t);
+                        }
+                    });
         });
         mRenderer.mIsDragging = false;
+        mRenderer.mDragHandle.setPressed(mRenderer.mIsDragging);
+    }
+
+    /**
+     * Returns the divider position adjusted for the min max ratio and fullscreen expansion.
+     *
+     * If the dragging position is above the {@link DividerAttributes#getPrimaryMaxRatio()} or below
+     * {@link DividerAttributes#getPrimaryMinRatio()} and
+     * {@link DividerAttributes#isDraggingToFullscreenAllowed} is {@code true}, the system will
+     * choose a snap algorithm to adjust the ending position to either fully expand one container or
+     * move the divider back to the specified min/max ratio.
+     *
+     * TODO(b/327067596) implement snap algorithm
+     *
+     * The adjusted divider position is in the range of [minPosition, maxPosition] for a split, 0
+     * for expanded right (bottom) container, or task width (height) minus the divider width for
+     * expanded left (top) container.
+     */
+    @GuardedBy("mLock")
+    private int adjustDividerPositionForSnapPoints(int dividerPosition) {
+        final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
+        final int minPosition = calculateMinPosition();
+        final int maxPosition = calculateMaxPosition();
+        final int fullyExpandedPosition = mProperties.mIsVerticalSplit
+                ? taskBounds.right - mRenderer.mDividerWidthPx
+                : taskBounds.bottom - mRenderer.mDividerWidthPx;
+        if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) {
+            if (dividerPosition < minPosition) {
+                return 0;
+            }
+            if (dividerPosition > maxPosition) {
+                return fullyExpandedPosition;
+            }
+        }
+        return Math.clamp(dividerPosition, minPosition, maxPosition);
     }
 
     private static void setDecorSurfaceBoosted(
@@ -520,7 +594,7 @@
     @VisibleForTesting
     static int calculateDividerPosition(@NonNull MotionEvent event, @NonNull Rect taskBounds,
             int dividerWidthPx, @NonNull DividerAttributes dividerAttributes,
-            boolean isVerticalSplit, boolean isReversedLayout) {
+            boolean isVerticalSplit, int minPosition, int maxPosition) {
         // The touch event is in display space. Converting it into the task window space.
         final int touchPositionInTaskSpace = isVerticalSplit
                 ? (int) (event.getRawX()) - taskBounds.left
@@ -530,15 +604,31 @@
         // position is offset by half of the divider width.
         int dividerPosition = touchPositionInTaskSpace - dividerWidthPx / 2;
 
-        // Limit the divider position to the min and max ratios set in DividerAttributes.
-        // TODO(b/327536303) Handle when the divider is dragged to the edge.
-        dividerPosition = Math.max(dividerPosition, calculateMinPosition(
-                taskBounds, dividerWidthPx, dividerAttributes, isVerticalSplit, isReversedLayout));
-        dividerPosition = Math.min(dividerPosition, calculateMaxPosition(
-                taskBounds, dividerWidthPx, dividerAttributes, isVerticalSplit, isReversedLayout));
+        // If dragging to fullscreen is not allowed, limit the divider position to the min and max
+        // ratios set in DividerAttributes. Otherwise, dragging beyond the min and max ratios is
+        // temporarily allowed and the final ratio will be adjusted in onFinishDragging.
+        if (!isDraggingToFullscreenAllowed(dividerAttributes)) {
+            dividerPosition = Math.clamp(dividerPosition, minPosition, maxPosition);
+        }
         return dividerPosition;
     }
 
+    @GuardedBy("mLock")
+    private int calculateMinPosition() {
+        return calculateMinPosition(
+                mProperties.mConfiguration.windowConfiguration.getBounds(),
+                mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
+                mProperties.mIsVerticalSplit, mProperties.mIsReversedLayout);
+    }
+
+    @GuardedBy("mLock")
+    private int calculateMaxPosition() {
+        return calculateMaxPosition(
+                mProperties.mConfiguration.windowConfiguration.getBounds(),
+                mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
+                mProperties.mIsVerticalSplit, mProperties.mIsReversedLayout);
+    }
+
     /** Calculates the min position of the divider that the user is allowed to drag to. */
     @VisibleForTesting
     static int calculateMinPosition(@NonNull Rect taskBounds, int dividerWidthPx,
@@ -581,13 +671,24 @@
                     mProperties.mConfiguration.windowConfiguration.getBounds(),
                     mRenderer.mDividerWidthPx,
                     mProperties.mIsVerticalSplit,
-                    mProperties.mIsReversedLayout);
+                    mProperties.mIsReversedLayout,
+                    calculateMinPosition(),
+                    calculateMaxPosition(),
+                    isDraggingToFullscreenAllowed(mProperties.mDividerAttributes));
         }
     }
 
+    private static boolean isDraggingToFullscreenAllowed(
+            @NonNull DividerAttributes dividerAttributes) {
+        // TODO(b/293654166) Use DividerAttributes.isDraggingToFullscreenAllowed when extension is
+        // updated.
+        return true;
+    }
+
     /**
      * Returns the new split ratio of the {@link SplitContainer} based on the current divider
      * position.
+     *
      * @param topSplitContainer the {@link SplitContainer} for which to compute the split ratio.
      * @param dividerPosition the divider position. See {@link #mDividerPosition}.
      * @param taskBounds the task bounds
@@ -599,7 +700,9 @@
      *                         bottom-to-top. If {@code false}, the split is not reversed, i.e.
      *                         left-to-right or top-to-bottom. See
      *                         {@link SplitAttributesHelper#isReversedLayout}
-     * @return the computed split ratio of the primary container.
+     * @return the computed split ratio of the primary container. If the primary container is fully
+     * expanded, {@link #RATIO_EXPANDED_PRIMARY} is returned. If the secondary container is fully
+     * expanded, {@link #RATIO_EXPANDED_SECONDARY} is returned.
      */
     @VisibleForTesting
     static float calculateNewSplitRatio(
@@ -608,15 +711,33 @@
             @NonNull Rect taskBounds,
             int dividerWidthPx,
             boolean isVerticalSplit,
-            boolean isReversedLayout) {
+            boolean isReversedLayout,
+            int minPosition,
+            int maxPosition,
+            boolean isDraggingToFullscreenAllowed) {
+
+        // Handle the fully expanded cases.
+        if (isDraggingToFullscreenAllowed) {
+            // The divider position is already adjusted by the snap algorithm in onFinishDragging.
+            // If the divider position is not in the range [minPosition, maxPosition], then one of
+            // the containers is fully expanded.
+            if (dividerPosition < minPosition) {
+                return isReversedLayout ? RATIO_EXPANDED_PRIMARY : RATIO_EXPANDED_SECONDARY;
+            }
+            if (dividerPosition > maxPosition) {
+                return isReversedLayout ? RATIO_EXPANDED_SECONDARY : RATIO_EXPANDED_PRIMARY;
+            }
+        } else {
+            dividerPosition = Math.clamp(dividerPosition, minPosition, maxPosition);
+        }
+
+        final TaskFragmentContainer primaryContainer = topSplitContainer.getPrimaryContainer();
+        final Rect origPrimaryBounds = primaryContainer.getLastRequestedBounds();
         final int usableSize = isVerticalSplit
                 ? taskBounds.width() - dividerWidthPx
                 : taskBounds.height() - dividerWidthPx;
 
-        final TaskFragmentContainer primaryContainer = topSplitContainer.getPrimaryContainer();
-        final Rect origPrimaryBounds = primaryContainer.getLastRequestedBounds();
-
-        float newRatio;
+        final float newRatio;
         if (isVerticalSplit) {
             final int newPrimaryWidth = isReversedLayout
                     ? (origPrimaryBounds.right - (dividerPosition + dividerWidthPx))
@@ -677,6 +798,7 @@
 
         private final int mDisplayId;
         private final boolean mIsReversedLayout;
+        private final boolean mIsDraggableExpandType;
 
         @VisibleForTesting
         Properties(
@@ -686,7 +808,8 @@
                 int initialDividerPosition,
                 boolean isVerticalSplit,
                 boolean isReversedLayout,
-                int displayId) {
+                int displayId,
+                boolean isDraggableExpandType) {
             mConfiguration = configuration;
             mDividerAttributes = dividerAttributes;
             mDecorSurface = decorSurface;
@@ -694,6 +817,7 @@
             mIsVerticalSplit = isVerticalSplit;
             mIsReversedLayout = isReversedLayout;
             mDisplayId = displayId;
+            mIsDraggableExpandType = isDraggableExpandType;
         }
 
         /**
@@ -714,7 +838,8 @@
                     && a.mInitialDividerPosition == b.mInitialDividerPosition
                     && a.mIsVerticalSplit == b.mIsVerticalSplit
                     && a.mDisplayId == b.mDisplayId
-                    && a.mIsReversedLayout == b.mIsReversedLayout;
+                    && a.mIsReversedLayout == b.mIsReversedLayout
+                    && a.mIsDraggableExpandType == b.mIsDraggableExpandType;
         }
 
         private static boolean areSameSurfaces(
@@ -761,6 +886,7 @@
         private SurfaceControl mSecondaryVeil;
         private boolean mIsDragging;
         private int mDividerPosition;
+        private View mDragHandle;
 
         private Renderer(@NonNull Properties properties, @NonNull View.OnTouchListener listener) {
             mProperties = properties;
@@ -857,6 +983,7 @@
                             PixelFormat.TRANSLUCENT);
             lp.setTitle(WINDOW_NAME);
             mViewHost.setView(mDividerLayout, lp);
+            mViewHost.relayout(lp);
         }
 
         /**
@@ -867,7 +994,12 @@
          */
         private void updateDivider(@NonNull SurfaceControl.Transaction t) {
             mDividerLayout.removeAllViews();
-            mDividerLayout.setBackgroundColor(DEFAULT_DIVIDER_COLOR.toArgb());
+            if (mProperties.mIsDraggableExpandType) {
+                // If a container is fully expanded, the divider overlays on the expanded container.
+                mDividerLayout.setBackgroundColor(Color.TRANSPARENT);
+            } else {
+                mDividerLayout.setBackgroundColor(mProperties.mDividerAttributes.getDividerColor());
+            }
             if (mProperties.mDividerAttributes.getDividerType()
                     == DividerAttributes.DIVIDER_TYPE_DRAGGABLE) {
                 createVeils();
@@ -916,6 +1048,7 @@
             }
 
             button.setOnTouchListener(mListener);
+            mDragHandle = button;
             mDividerLayout.addView(button);
         }
 
@@ -928,7 +1061,7 @@
                     .setHidden(!visible)
                     .setCallsite("DividerManager.createChildSurface")
                     .setBufferSize(bounds.width(), bounds.height())
-                    .setColorLayer()
+                    .setEffectLayer()
                     .build();
         }
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitAttributesHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitAttributesHelper.java
index 042a68a6..4541a84 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitAttributesHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitAttributesHelper.java
@@ -20,6 +20,7 @@
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType.ExpandContainersSplitType;
 
 /** Helper functions for {@link SplitAttributes} */
 class SplitAttributesHelper {
@@ -43,4 +44,17 @@
                         "Invalid layout direction:" + splitAttributes.getLayoutDirection());
         }
     }
+
+    /**
+     * Returns whether the {@link SplitAttributes} is an {@link ExpandContainersSplitType} and it
+     * should show a draggable handle that allows the user to drag and restore it into a split.
+     * This state is a result of user dragging the divider to fully expand the secondary container.
+     */
+    static boolean isDraggableExpandType(@NonNull SplitAttributes splitAttributes) {
+        final DividerAttributes dividerAttributes = splitAttributes.getDividerAttributes();
+        return splitAttributes.getSplitType() instanceof ExpandContainersSplitType
+                && dividerAttributes != null
+                && dividerAttributes.getDividerType() == DividerAttributes.DIVIDER_TYPE_DRAGGABLE;
+
+    }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 5f389c9..0f04321 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -2168,6 +2168,10 @@
             return false;
         }
 
+        if (container != null && container.getTaskContainer().isPlaceholderRuleSuppressed()) {
+            return false;
+        }
+
         final TaskContainer.TaskProperties taskProperties = mPresenter.getTaskProperties(activity);
         final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(activity,
                 placeholderRule.getPlaceholderIntent());
@@ -2263,6 +2267,9 @@
         if (SplitPresenter.shouldShowSplit(splitAttributes)) {
             return false;
         }
+        if (SplitPresenter.shouldShowPlaceholderWhenExpanded(splitAttributes)) {
+            return false;
+        }
 
         mTransactionManager.getCurrentTransactionRecord()
                 .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE);
@@ -3194,7 +3201,12 @@
             if (taskContainer != null) {
                 final DividerPresenter dividerPresenter =
                         mDividerPresenters.get(taskContainer.getTaskId());
-                taskContainer.updateTopSplitContainerForDivider(dividerPresenter);
+                final List<TaskFragmentContainer> containersToFinish = new ArrayList<>();
+                taskContainer.updateTopSplitContainerForDivider(
+                        dividerPresenter, containersToFinish);
+                for (final TaskFragmentContainer container : containersToFinish) {
+                    mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */);
+                }
                 updateContainersInTask(wct, taskContainer);
             }
             action.accept(wct);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index a11796e..b56f671 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -721,6 +721,12 @@
         return !(splitAttributes.getSplitType() instanceof ExpandContainersSplitType);
     }
 
+    static boolean shouldShowPlaceholderWhenExpanded(@NonNull SplitAttributes splitAttributes) {
+        // The placeholder should be kept if the expand split type is a result of user dragging
+        // the divider.
+        return SplitAttributesHelper.isDraggableExpandType(splitAttributes);
+    }
+
     @NonNull
     SplitAttributes computeSplitAttributes(@NonNull TaskProperties taskProperties,
             @NonNull SplitRule rule, @NonNull SplitAttributes defaultSplitAttributes,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index 30fb79f..3dd96c4 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -22,6 +22,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.inMultiWindowMode;
 
+import static androidx.window.extensions.embedding.DividerPresenter.RATIO_EXPANDED_PRIMARY;
+import static androidx.window.extensions.embedding.DividerPresenter.RATIO_EXPANDED_SECONDARY;
+
 import android.app.Activity;
 import android.app.ActivityClient;
 import android.app.WindowConfiguration;
@@ -40,6 +43,9 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType.ExpandContainersSplitType;
+import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -89,6 +95,25 @@
     final Set<IBinder> mFinishedContainer = new ArraySet<>();
 
     /**
+     * The {@link RatioSplitType} that will be applied to newly added containers. This is to ensure
+     * the required UX that, after user dragging the divider, the split ratio is persistent after
+     * launching a new activity into a new TaskFragment in the same Task.
+     */
+    private RatioSplitType mOverrideSplitType;
+
+    /**
+     * If {@code true}, suppress the placeholder rules in the {@link TaskContainer}.
+     * <p>
+     * This is used in case the user drags the divider to fully expand the primary container and
+     * dismiss the secondary container while a {@link SplitPlaceholderRule} is used. Without this
+     * flag, after dismissing the secondary container, a placeholder will be launched again.
+     * <p>
+     * This flag is set true when the primary container is fully expanded and cleared when a new
+     * split is added to the {@link TaskContainer}.
+     */
+    private boolean mPlaceholderRuleSuppressed;
+
+    /**
      * The {@link TaskContainer} constructor
      *
      * @param taskId         The ID of the Task, which must match {@link Activity#getTaskId()} with
@@ -322,6 +347,11 @@
     }
 
     void addSplitContainer(@NonNull SplitContainer splitContainer) {
+        // Reset the placeholder rule suppression when a new split container is added.
+        mPlaceholderRuleSuppressed = false;
+
+        applyOverrideSplitTypeIfNeeded(splitContainer);
+
         if (splitContainer instanceof SplitPinContainer) {
             mSplitPinContainer = (SplitPinContainer) splitContainer;
             mSplitContainers.add(splitContainer);
@@ -336,6 +366,39 @@
         }
     }
 
+    boolean isPlaceholderRuleSuppressed() {
+        return mPlaceholderRuleSuppressed;
+    }
+
+    // If there is an override SplitType due to user dragging the divider, the split ratio should
+    // be applied to newly added SplitContainers.
+    private void applyOverrideSplitTypeIfNeeded(@NonNull SplitContainer splitContainer) {
+        if (mOverrideSplitType == null) {
+            return;
+        }
+        final SplitAttributes splitAttributes = splitContainer.getCurrentSplitAttributes();
+        final DividerAttributes dividerAttributes = splitAttributes.getDividerAttributes();
+        if (!(splitAttributes.getSplitType() instanceof RatioSplitType)) {
+            // Skip if the original split type is not a ratio type.
+            return;
+        }
+        if (dividerAttributes == null
+                || dividerAttributes.getDividerType() != DividerAttributes.DIVIDER_TYPE_DRAGGABLE) {
+            // Skip if the split does not have a draggable divider.
+            return;
+        }
+        updateDefaultSplitAttributes(splitContainer, mOverrideSplitType);
+    }
+
+    private static void updateDefaultSplitAttributes(
+            @NonNull SplitContainer splitContainer, @NonNull SplitType overrideSplitType) {
+        splitContainer.updateDefaultSplitAttributes(
+                new SplitAttributes.Builder(splitContainer.getDefaultSplitAttributes())
+                        .setSplitType(overrideSplitType)
+                        .build()
+        );
+    }
+
     void removeSplitContainers(@NonNull List<SplitContainer> containers) {
         mSplitContainers.removeAll(containers);
     }
@@ -407,18 +470,47 @@
         return mContainers;
     }
 
-    void updateTopSplitContainerForDivider(@NonNull DividerPresenter dividerPresenter) {
+    void updateTopSplitContainerForDivider(
+            @NonNull DividerPresenter dividerPresenter,
+            @NonNull List<TaskFragmentContainer> outContainersToFinish) {
         final SplitContainer topSplitContainer = getTopNonFinishingSplitContainer();
         if (topSplitContainer == null) {
             return;
         }
-
+        final TaskFragmentContainer primaryContainer = topSplitContainer.getPrimaryContainer();
         final float newRatio = dividerPresenter.calculateNewSplitRatio(topSplitContainer);
-        topSplitContainer.updateDefaultSplitAttributes(
-                new SplitAttributes.Builder(topSplitContainer.getDefaultSplitAttributes())
-                        .setSplitType(new SplitAttributes.SplitType.RatioSplitType(newRatio))
-                        .build()
-        );
+
+        // If the primary container is fully expanded, we should finish all the associated
+        // secondary containers.
+        if (newRatio == RATIO_EXPANDED_PRIMARY) {
+            for (final SplitContainer splitContainer : mSplitContainers) {
+                if (primaryContainer == splitContainer.getPrimaryContainer()) {
+                    outContainersToFinish.add(splitContainer.getSecondaryContainer());
+                }
+            }
+
+            // Temporarily suppress the placeholder rule in the TaskContainer. This will be restored
+            // if a new split is added into the TaskContainer.
+            mPlaceholderRuleSuppressed = true;
+
+            mOverrideSplitType = null;
+            return;
+        }
+
+        final SplitType newSplitType;
+        if (newRatio == RATIO_EXPANDED_SECONDARY) {
+            newSplitType = new ExpandContainersSplitType();
+            // We do not want to apply ExpandContainersSplitType to new split containers.
+            mOverrideSplitType = null;
+        } else {
+            // We save the override RatioSplitType and apply to new split containers.
+            newSplitType = mOverrideSplitType = new RatioSplitType(newRatio);
+        }
+        for (final SplitContainer splitContainer : mSplitContainers) {
+            if (primaryContainer == splitContainer.getPrimaryContainer()) {
+                updateDefaultSplitAttributes(splitContainer, newSplitType);
+            }
+        }
     }
 
     @Nullable
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
index 47d01da..de0171d 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -144,10 +144,12 @@
                 new Configuration(),
                 DEFAULT_DIVIDER_ATTRIBUTES,
                 mSurfaceControl,
-                getInitialDividerPosition(mSplitContainer),
+                getInitialDividerPosition(
+                        mSplitContainer, true /* isVerticalSplit */, false /* isReversedLayout */),
                 true /* isVerticalSplit */,
                 false /* isReversedLayout */,
-                Display.DEFAULT_DISPLAY);
+                Display.DEFAULT_DISPLAY,
+                false /* isDraggableExpandType */);
 
         mDividerPresenter = new DividerPresenter(
                 MOCK_TASK_ID, mDragEventCallback, mock(Executor.class));
@@ -348,7 +350,8 @@
                         dividerWidthPx,
                         dividerAttributes,
                         true /* isVerticalSplit */,
-                        false /* isReversedLayout */));
+                        0 /* minPosition */,
+                        900 /* maxPosition */));
 
         // Top-to-bottom split
         when(event.getRawY()).thenReturn(1000f); // Touch event is in display space
@@ -361,7 +364,8 @@
                         dividerWidthPx,
                         dividerAttributes,
                         false /* isVerticalSplit */,
-                        false /* isReversedLayout */));
+                        0 /* minPosition */,
+                        900 /* maxPosition */));
     }
 
     @Test
@@ -453,7 +457,6 @@
         final Rect primaryBounds = new Rect(0, 0, 500, 2000);
         final Rect secondaryBounds = new Rect(600, 0, 1100, 2000);
         final int dividerWidthPx = 100;
-        final int dividerPosition = 300;
 
         final TaskFragmentContainer mockPrimaryContainer =
                 createMockTaskFragmentContainer(mPrimaryContainerToken, primaryBounds);
@@ -462,6 +465,8 @@
         when(mSplitContainer.getPrimaryContainer()).thenReturn(mockPrimaryContainer);
         when(mSplitContainer.getSecondaryContainer()).thenReturn(mockSecondaryContainer);
 
+        // Test the normal case
+        int dividerPosition = 300;
         assertEquals(
                 0.3f, // Primary is 300px after dragging.
                 DividerPresenter.calculateNewSplitRatio(
@@ -470,7 +475,43 @@
                         taskBounds,
                         dividerWidthPx,
                         true /* isVerticalSplit */,
-                        false /* isReversedLayout */),
+                        false /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        false /* isDraggingToFullscreenAllowed */),
+                0.0001 /* delta */);
+
+        // Test the case when dragging to fullscreen is allowed and divider is dragged to the edge
+        dividerPosition = 0;
+        assertEquals(
+                DividerPresenter.RATIO_EXPANDED_SECONDARY,
+                DividerPresenter.calculateNewSplitRatio(
+                        mSplitContainer,
+                        dividerPosition,
+                        taskBounds,
+                        dividerWidthPx,
+                        true /* isVerticalSplit */,
+                        false /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        true /* isDraggingToFullscreenAllowed */),
+                0.0001 /* delta */);
+
+        // Test the case when dragging to fullscreen is not allowed and divider is dragged to the
+        // edge.
+        dividerPosition = 0;
+        assertEquals(
+                0.2f, // Adjusted to the minPosition 200
+                DividerPresenter.calculateNewSplitRatio(
+                        mSplitContainer,
+                        dividerPosition,
+                        taskBounds,
+                        dividerWidthPx,
+                        true /* isVerticalSplit */,
+                        false /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        false /* isDraggingToFullscreenAllowed */),
                 0.0001 /* delta */);
     }
 
@@ -482,7 +523,6 @@
         final Rect primaryBounds = new Rect(0, 0, 2000, 1100);
         final Rect secondaryBounds = new Rect(0, 0, 2000, 500);
         final int dividerWidthPx = 100;
-        final int dividerPosition = 300;
 
         final TaskFragmentContainer mockPrimaryContainer =
                 createMockTaskFragmentContainer(mPrimaryContainerToken, primaryBounds);
@@ -491,6 +531,8 @@
         when(mSplitContainer.getPrimaryContainer()).thenReturn(mockPrimaryContainer);
         when(mSplitContainer.getSecondaryContainer()).thenReturn(mockSecondaryContainer);
 
+        // Test the normal case
+        int dividerPosition = 300;
         assertEquals(
                 // After dragging, secondary is [0, 0, 2000, 300]. Primary is [0, 400, 2000, 1100].
                 0.7f,
@@ -500,7 +542,46 @@
                         taskBounds,
                         dividerWidthPx,
                         false /* isVerticalSplit */,
-                        true /* isReversedLayout */),
+                        true /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        true /* isDraggingToFullscreenAllowed */),
+                0.0001 /* delta */);
+
+        // Test the case when dragging to fullscreen is not allowed and divider is dragged to the
+        // edge.
+        dividerPosition = 0;
+        assertEquals(
+                // The primary (bottom) container is expanded
+                DividerPresenter.RATIO_EXPANDED_PRIMARY,
+                DividerPresenter.calculateNewSplitRatio(
+                        mSplitContainer,
+                        dividerPosition,
+                        taskBounds,
+                        dividerWidthPx,
+                        false /* isVerticalSplit */,
+                        true /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        true /* isDraggingToFullscreenAllowed */),
+                0.0001 /* delta */);
+
+        // Test the case when dragging to fullscreen is not allowed and divider is dragged to the
+        // edge.
+        dividerPosition = 0;
+        assertEquals(
+                // Adjusted to minPosition 200, so the primary (bottom) container is 800.
+                0.8f,
+                DividerPresenter.calculateNewSplitRatio(
+                        mSplitContainer,
+                        dividerPosition,
+                        taskBounds,
+                        dividerWidthPx,
+                        false /* isVerticalSplit */,
+                        true /* isReversedLayout */,
+                        200 /* minPosition */,
+                        1000 /* maxPosition */,
+                        false /* isDraggingToFullscreenAllowed */),
                 0.0001 /* delta */);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 58942ec..ec2e670 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -588,7 +588,7 @@
             if (taskBoundsBeforeMaximize != null) {
                 destinationBounds.set(taskBoundsBeforeMaximize)
             } else {
-                getDefaultDesktopTaskBounds(displayLayout, destinationBounds)
+                destinationBounds.set(getDefaultDesktopTaskBounds(displayLayout))
             }
         } else {
             // Save current bounds so that task can be restored back to original bounds if necessary
@@ -624,18 +624,14 @@
         }
     }
 
-    private fun getDefaultDesktopTaskBounds(displayLayout: DisplayLayout, outBounds: Rect) {
+    private fun getDefaultDesktopTaskBounds(displayLayout: DisplayLayout): Rect {
         // TODO(b/319819547): Account for app constraints so apps do not become letterboxed
-        val screenBounds = Rect(0, 0, displayLayout.width(), displayLayout.height())
-        // Update width and height with default desktop mode values
-        val desiredWidth = screenBounds.width().times(DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
-        val desiredHeight = screenBounds.height().times(DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
-        outBounds.set(0, 0, desiredWidth, desiredHeight)
-        // Center the task in screen bounds
-        outBounds.offset(
-            screenBounds.centerX() - outBounds.centerX(),
-            screenBounds.centerY() - outBounds.centerY()
-        )
+        val desiredWidth = (displayLayout.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
+        val desiredHeight = (displayLayout.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
+        val heightOffset = (displayLayout.height() - desiredHeight) / 2
+        val widthOffset = (displayLayout.width() - desiredWidth) / 2
+        return Rect(widthOffset, heightOffset,
+            desiredWidth + widthOffset, desiredHeight + heightOffset)
     }
 
     private fun getSnapBounds(taskInfo: RunningTaskInfo, position: SnapPosition): Rect {
@@ -1090,17 +1086,14 @@
      * @param taskInfo the task being dragged.
      * @param y height of drag, to be checked against status bar height.
      */
-    fun onDragPositioningEndThroughStatusBar(
-            inputCoordinates: PointF,
-            taskInfo: RunningTaskInfo,
-            freeformBounds: Rect
-    ) {
+    fun onDragPositioningEndThroughStatusBar(inputCoordinates: PointF, taskInfo: RunningTaskInfo) {
         val indicator = visualIndicator ?: return
         val indicatorType = indicator
             .updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
         when (indicatorType) {
             DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
-                finalizeDragToDesktop(taskInfo, freeformBounds)
+                val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
+                finalizeDragToDesktop(taskInfo, getDefaultDesktopTaskBounds(displayLayout))
             }
             DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR,
                     DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
index e8f58fe..62d195e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
@@ -37,4 +37,9 @@
      * Called when a running task vanishes.
      */
     void onRunningTaskVanished(in RunningTaskInfo taskInfo);
+
+    /**
+     * Called when a running task changes.
+     */
+    void onRunningTaskChanged(in RunningTaskInfo taskInfo);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index f9fcfac..0c99aed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.content.pm.PackageManager.FEATURE_PC;
 
+import static com.android.window.flags.Flags.enableDesktopWindowingTaskbarRunningApps;
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
 
@@ -26,7 +27,6 @@
 import android.app.ActivityTaskManager;
 import android.app.IApplicationThread;
 import android.app.PendingIntent;
-import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -86,7 +86,7 @@
     private final ActivityTaskManager mActivityTaskManager;
     private RecentsTransitionHandler mTransitionHandler = null;
     private IRecentTasksListener mListener;
-    private final boolean mIsDesktopMode;
+    private final boolean mPcFeatureEnabled;
 
     // Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
     // pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
@@ -133,7 +133,7 @@
         mShellController = shellController;
         mShellCommandHandler = shellCommandHandler;
         mActivityTaskManager = activityTaskManager;
-        mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
+        mPcFeatureEnabled = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
         mTaskStackListener = taskStackListener;
         mDesktopModeTaskRepository = desktopModeTaskRepository;
         mMainExecutor = mainExecutor;
@@ -252,8 +252,10 @@
         notifyRunningTaskVanished(taskInfo);
     }
 
-    public void onTaskWindowingModeChanged(TaskInfo taskInfo) {
+    /** Notify listeners that the windowing mode of the given Task was updated. */
+    public void onTaskWindowingModeChanged(ActivityManager.RunningTaskInfo taskInfo) {
         notifyRecentTasksChanged();
+        notifyRunningTaskChanged(taskInfo);
     }
 
     @Override
@@ -278,7 +280,9 @@
      * Notify the running task listener that a task appeared on desktop environment.
      */
     private void notifyRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
-        if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+        if (mListener == null
+                || !shouldEnableRunningTasksForDesktopMode()
+                || taskInfo.realActivity == null) {
             return;
         }
         try {
@@ -292,7 +296,9 @@
      * Notify the running task listener that a task was removed on desktop environment.
      */
     private void notifyRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+        if (mListener == null
+                || !shouldEnableRunningTasksForDesktopMode()
+                || taskInfo.realActivity == null) {
             return;
         }
         try {
@@ -302,6 +308,27 @@
         }
     }
 
+    /**
+     * Notify the running task listener that a task was changed on desktop environment.
+     */
+    private void notifyRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+        if (mListener == null
+                || !shouldEnableRunningTasksForDesktopMode()
+                || taskInfo.realActivity == null) {
+            return;
+        }
+        try {
+            mListener.onRunningTaskChanged(taskInfo);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed call onRunningTaskChanged", e);
+        }
+    }
+
+    private boolean shouldEnableRunningTasksForDesktopMode() {
+        return mPcFeatureEnabled
+                || (DesktopModeStatus.isEnabled() && enableDesktopWindowingTaskbarRunningApps());
+    }
+
     @VisibleForTesting
     void registerRecentTasksListener(IRecentTasksListener listener) {
         mListener = listener;
@@ -476,6 +503,11 @@
             public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
                 mListener.call(l -> l.onRunningTaskVanished(taskInfo));
             }
+
+            @Override
+            public void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+                mListener.call(l -> l.onRunningTaskChanged(taskInfo));
+            }
         };
 
         public IRecentTasksImpl(RecentTasksController controller) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index a0f9c6b..7649a782 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -858,10 +858,7 @@
                         // as it likely will change.
                         relevantDecor.updateHoverAndPressStatus(ev);
                         mDesktopTasksController.onDragPositioningEndThroughStatusBar(
-                                new PointF(ev.getRawX(), ev.getRawY()),
-                                relevantDecor.mTaskInfo,
-                                calculateFreeformBounds(ev.getDisplayId(),
-                                        DesktopTasksController.DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
+                                new PointF(ev.getRawX(), ev.getRawY()), relevantDecor.mTaskInfo);
                         mMoveToDesktopAnimator = null;
                         return;
                     } else {
@@ -913,23 +910,6 @@
         }
     }
 
-    /**
-     * Gets bounds of a scaled window centered relative to the screen bounds
-     * @param scale the amount to scale to relative to the Screen Bounds
-     */
-    private Rect calculateFreeformBounds(int displayId, float scale) {
-        // TODO(b/319819547): Account for app constraints so apps do not become letterboxed
-        final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(displayId);
-        final int screenWidth = displayLayout.width();
-        final int screenHeight = displayLayout.height();
-
-        final float adjustmentPercentage = (1f - scale) / 2;
-        return new Rect((int) (screenWidth * adjustmentPercentage),
-                (int) (screenHeight * adjustmentPercentage),
-                (int) (screenWidth * (adjustmentPercentage + scale)),
-                (int) (screenHeight * (adjustmentPercentage + scale)));
-    }
-
     @Nullable
     private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
         final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index d64bfed..b85d793 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -33,7 +33,7 @@
 /**
  * Test entering pip from an app via auto-enter property when navigating to home.
  *
- * To run this test: `atest WMShellFlickerTests:AutoEnterPipOnGoToHomeTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:AutoEnterPipOnGoToHomeTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
index 371fee2..d059211 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
@@ -30,7 +30,7 @@
 /**
  * Test auto entering pip using a source rect hint.
  *
- * To run this test: `atest AutoEnterPipWithSourceRectHintTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:AutoEnterPipWithSourceRectHintTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index 1c0820a..a5e0550 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -31,7 +31,7 @@
 /**
  * Test closing a pip window by swiping it to the bottom-center of the screen
  *
- * To run this test: `atest WMShellFlickerTests:ExitPipWithSwipeDownTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:ClosePipBySwipingDownTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
index 860307f..d177624 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
@@ -30,7 +30,7 @@
 /**
  * Test closing a pip window via the dismiss button
  *
- * To run this test: `atest WMShellFlickerTests:ExitPipWithDismissButtonTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:ClosePipWithDismissButtonTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index c554161..a86803d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -31,7 +31,7 @@
 /**
  * Test entering pip from an app via [onUserLeaveHint] and by navigating to home.
  *
- * To run this test: `atest WMShellFlickerTests:EnterPipOnUserLeaveHintTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:EnterPipOnUserLeaveHintTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index 270ebf5..a0a61fe2 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -46,7 +46,7 @@
 /**
  * Test entering pip while changing orientation (from app in landscape to pip window in portrait)
  *
- * To run this test: `atest WMShellFlickerTests:EnterPipToOtherOrientationTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:EnterPipToOtherOrientation`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
index f97d8d1..d92f55a 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
@@ -28,7 +28,7 @@
 /**
  * Test entering pip from an app by interacting with the app UI
  *
- * To run this test: `atest WMShellFlickerTests:EnterPipTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:EnterPipViaAppUiButtonTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
index 47bf418..8c0817d6 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
@@ -28,7 +28,7 @@
 /**
  * Test expanding a pip window back to full screen via the expand button
  *
- * To run this test: `atest WMShellFlickerTests:ExitPipViaExpandButtonClickTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:ExitPipToAppViaExpandButtonTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index a356e68..90a9623 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
@@ -28,7 +28,7 @@
 /**
  * Test expanding a pip window back to full screen via an intent
  *
- * To run this test: `atest WMShellFlickerTests:ExitPipViaIntentTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:ExitPipToAppViaIntentTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index eeff167..9306c77 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -33,7 +33,7 @@
 /**
  * Test expanding a pip window by double-clicking it
  *
- * To run this test: `atest WMShellFlickerTests:ExpandPipOnDoubleClickTest`
+ * To run this test: `atest WMShellFlickerTestsPip2:ExpandPipOnDoubleClickTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
index 12e395d..cb8ee27 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
@@ -39,7 +39,7 @@
 /**
  * Test entering pip from an app via auto-enter property when navigating to home from split screen.
  *
- * To run this test: `atest WMShellFlickerTests:AutoEnterPipOnGoToHomeTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:FromSplitScreenAutoEnterPipOnGoToHomeTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
index f81e849..f2f10ae 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
@@ -40,7 +40,7 @@
 /**
  * Test entering pip from an app via auto-enter property when navigating to home from split screen.
  *
- * To run this test: `atest WMShellFlickerTests:AutoEnterPipOnGoToHomeTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:FromSplitScreenEnterPipOnUserLeaveHintTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
index 9b74622..265eb44 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
@@ -32,7 +32,7 @@
 /**
  * Test Pip movement with Launcher shelf height change (increase).
  *
- * To run this test: `atest WMShellFlickerTests:MovePipUpShelfHeightChangeTest`
+ * To run this test: `atest WMShellFlickerTestsPip3:MovePipDownOnShelfHeightChange`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index ad3c69e..04fedf4 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
@@ -34,7 +34,10 @@
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
 
-/** Test Pip launch. To run this test: `atest WMShellFlickerTests:PipKeyboardTest` */
+/**
+ * Test Pip launch. To run this test:
+ * `atest WMShellFlickerTestsPip3:MovePipOnImeVisibilityChangeTest`
+ */
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
index 490ebd1..8d6be64 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
@@ -32,7 +32,7 @@
 /**
  * Test Pip movement with Launcher shelf height change (decrease).
  *
- * To run this test: `atest WMShellFlickerTests:MovePipDownShelfHeightChangeTest`
+ * To run this test: `atest WMShellFlickerTestsPip3:MovePipUpOnShelfHeightChangeTest`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
index 9a6dacb..ed2a0a7 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
@@ -41,8 +41,8 @@
 import org.junit.runners.Parameterized
 
 /**
- * Test exiting Pip with orientation changes. To run this test: `atest
- * WMShellFlickerTests:SetRequestedOrientationWhilePinnedTest`
+ * Test exiting Pip with orientation changes. To run this test:
+ * `atest WMShellFlickerTestsPip1:SetRequestedOrientationWhilePinned`
  */
 @RequiresDevice
 @RunWith(Parameterized::class)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
index d2f803e..9109eaf 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
@@ -35,7 +35,7 @@
 /**
  * Test Pip Stack in bounds after rotations.
  *
- * To run this test: `atest WMShellFlickerTests:PipRotationTest`
+ * To run this test: `atest WMShellFlickerTestsPip1:ShowPipAndRotateDisplay`
  *
  * Actions:
  * ```
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index d38e97f..40b59c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -45,16 +46,21 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.view.SurfaceControl;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
@@ -70,6 +76,7 @@
 import com.android.wm.shell.util.SplitBounds;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -99,6 +106,11 @@
     private ActivityTaskManager mActivityTaskManager;
     @Mock
     private DisplayInsetsController mDisplayInsetsController;
+    @Mock
+    private IRecentTasksListener mRecentTasksListener;
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private ShellTaskOrganizer mShellTaskOrganizer;
     private RecentTasksController mRecentTasksController;
@@ -426,6 +438,85 @@
     }
 
     @Test
+    @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+            Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+    public void onTaskAdded_desktopModeRunningAppsEnabled_triggersOnRunningTaskAppeared()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskAdded(taskInfo);
+
+        verify(mRecentTasksListener).onRunningTaskAppeared(taskInfo);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS)
+    public void onTaskAdded_desktopModeRunningAppsDisabled_doesNotTriggerOnRunningTaskAppeared()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskAdded(taskInfo);
+
+        verify(mRecentTasksListener, never()).onRunningTaskAppeared(any());
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+            Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+    public void taskWindowingModeChanged_desktopRunningAppsEnabled_triggersOnRunningTaskChanged()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskWindowingModeChanged(taskInfo);
+
+        verify(mRecentTasksListener).onRunningTaskChanged(taskInfo);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS)
+    public void
+            taskWindowingModeChanged_desktopRunningAppsDisabled_doesNotTriggerOnRunningTaskChanged()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskWindowingModeChanged(taskInfo);
+
+        verify(mRecentTasksListener, never()).onRunningTaskChanged(any());
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+            Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS})
+    public void onTaskRemoved_desktopModeRunningAppsEnabled_triggersOnRunningTaskVanished()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskRemoved(taskInfo);
+
+        verify(mRecentTasksListener).onRunningTaskVanished(taskInfo);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS)
+    public void onTaskRemoved_desktopModeRunningAppsDisabled_doesNotTriggerOnRunningTaskVanished()
+            throws Exception {
+        mRecentTasksControllerReal.registerRecentTasksListener(mRecentTasksListener);
+        ActivityManager.RunningTaskInfo taskInfo = makeRunningTaskInfo(/* taskId= */10);
+
+        mRecentTasksControllerReal.onTaskRemoved(taskInfo);
+
+        verify(mRecentTasksListener, never()).onRunningTaskVanished(any());
+    }
+
+    @Test
     public void getNullSplitBoundsNonSplitTask() {
         SplitBounds sb = mRecentTasksController.getSplitBoundsForTaskId(3);
         assertNull("splitBounds should be null for non-split task", sb);
@@ -471,6 +562,7 @@
     private ActivityManager.RunningTaskInfo makeRunningTaskInfo(int taskId) {
         ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
         info.taskId = taskId;
+        info.realActivity = new ComponentName("testPackage", "testClass");
         return info;
     }
 
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 5aa006b..c664d3d 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -2713,7 +2713,7 @@
 
             List<RoutingSessionInfo> sessionInfos = getRoutingSessions();
             RoutingSessionInfo targetSession = sessionInfos.get(sessionInfos.size() - 1);
-            transfer(targetSession, route, Process.myUserHandle(), mContext.getPackageName());
+            transfer(targetSession, route, mClientUser, mContext.getPackageName());
         }
 
         @Override
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 888777e..36f6ad2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -30,6 +30,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.lifecycle.ViewModel
+import com.android.credentialmanager.common.BiometricError
 import com.android.credentialmanager.common.BiometricFlowType
 import com.android.credentialmanager.common.BiometricPromptState
 import com.android.credentialmanager.common.BiometricResult
@@ -128,13 +129,22 @@
             uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
             val entryIntent = entry.fillInIntent
             entryIntent?.putExtra(Constants.IS_AUTO_SELECTED_KEY, uiState.isAutoSelectFlow)
-            if (biometricState.biometricResult != null) {
+            if (biometricState.biometricResult != null || biometricState.biometricError != null) {
                 if (uiState.isAutoSelectFlow) {
                     Log.w(Constants.LOG_TAG, "Unexpected biometric result exists when " +
                             "autoSelect is preferred.")
                 }
-                entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_TYPE,
-                    biometricState.biometricResult.biometricAuthenticationResult.authenticationType)
+                // TODO(b/333445754) : Decide whether to propagate info on prompt launch
+                if (biometricState.biometricResult != null) {
+                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_RESULT,
+                        biometricState.biometricResult.biometricAuthenticationResult
+                            .authenticationType)
+                } else if (biometricState.biometricError != null){
+                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_ERROR_CODE,
+                        biometricState.biometricError.errorCode)
+                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_ERROR_MESSAGE,
+                        biometricState.biometricError.errorMessage)
+                }
             }
             val intentSenderRequest = IntentSenderRequest.Builder(pendingIntent)
                 .setFillInIntent(entryIntent).build()
@@ -219,7 +229,8 @@
     /**************************************************************************/
     fun getFlowOnEntrySelected(
         entry: EntryInfo,
-        authResult: BiometricPrompt.AuthenticationResult? = null
+        authResult: BiometricPrompt.AuthenticationResult? = null,
+        authError: BiometricError? = null,
     ) {
         Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
             ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
@@ -227,10 +238,11 @@
             uiState.copy(
                 selectedEntry = entry,
                 providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
-                biometricState = if (authResult == null) uiState.biometricState else uiState
+                biometricState = if (authResult == null && authError == null)
+                    uiState.biometricState else if (authResult != null) uiState
                     .biometricState.copy(biometricResult = BiometricResult(
-                            biometricAuthenticationResult = authResult)
-                )
+                            biometricAuthenticationResult = authResult)) else uiState
+                    .biometricState.copy(biometricError = authError)
             )
         } else {
             credManRepo.onOptionSelected(entry.providerId, entry.entryKey, entry.entrySubkey)
@@ -350,7 +362,8 @@
 
     fun createFlowOnEntrySelected(
         selectedEntry: EntryInfo,
-        authResult: AuthenticationResult? = null
+        authResult: AuthenticationResult? = null,
+        authError: BiometricError? = null,
     ) {
         val providerId = selectedEntry.providerId
         val entryKey = selectedEntry.entryKey
@@ -362,9 +375,11 @@
             uiState = uiState.copy(
                 selectedEntry = selectedEntry,
                 providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
-                biometricState = if (authResult == null) uiState.biometricState else uiState
+                biometricState = if (authResult == null && authError == null)
+                    uiState.biometricState else if (authResult != null) uiState
                     .biometricState.copy(biometricResult = BiometricResult(
-                        biometricAuthenticationResult = authResult))
+                        biometricAuthenticationResult = authResult)) else uiState
+                    .biometricState.copy(biometricError = authError)
             )
         } else {
             credManRepo.onOptionSelected(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
index be3e043..e088d3a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
@@ -76,6 +76,7 @@
  */
 data class BiometricState(
     val biometricResult: BiometricResult? = null,
+    val biometricError: BiometricError? = null,
     val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE
 )
 
@@ -92,7 +93,7 @@
  */
 data class BiometricError(
     val errorCode: Int,
-    val errString: CharSequence? = null
+    val errorMessage: CharSequence? = null
 )
 
 /**
@@ -113,7 +114,7 @@
     biometricEntry: EntryInfo,
     context: Context,
     openMoreOptionsPage: () -> Unit,
-    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
+    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
     onCancelFlowAndFinish: () -> Unit,
     onIllegalStateAndFinish: (String) -> Unit,
     getBiometricPromptState: () -> BiometricPromptState,
@@ -158,7 +159,7 @@
     biometricEntry: EntryInfo,
     context: Context,
     openMoreOptionsPage: () -> Unit,
-    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
+    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
     onCancelFlowAndFinish: () -> Unit,
     onIllegalStateAndFinish: (String) -> Unit,
     getBiometricPromptState: () -> BiometricPromptState,
@@ -285,7 +286,7 @@
  * Sets up the biometric authentication callback.
  */
 private fun setupBiometricAuthenticationCallback(
-    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
+    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
     selectedEntry: EntryInfo,
     onCancelFlowAndFinish: () -> Unit,
     onIllegalStateAndFinish: (String) -> Unit,
@@ -301,7 +302,7 @@
                 try {
                     if (authResult != null) {
                         onBiometricPromptStateChange(BiometricPromptState.COMPLETE)
-                        sendDataToProvider(selectedEntry, authResult)
+                        sendDataToProvider(selectedEntry, authResult, /*authError=*/null)
                     } else {
                         onIllegalStateAndFinish("The biometric flow succeeded but unexpectedly " +
                                 "returned a null value.")
@@ -326,8 +327,10 @@
                     // into the selector, parity applies to the selector's cancellation instead
                     // of the provider's biometric prompt cancellation.
                     onCancelFlowAndFinish()
+                } else {
+                    sendDataToProvider(selectedEntry, /*authResult=*/null, /*authError=*/
+                        BiometricError(errorCode, errString))
                 }
-                // TODO(b/333445772) : Propagate to provider
             }
 
             override fun onAuthenticationFailed() {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/Constants.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/Constants.kt
index 7e7a74f..3c80113 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/Constants.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/Constants.kt
@@ -22,7 +22,9 @@
         const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
             "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED"
         const val IS_AUTO_SELECTED_KEY = "IS_AUTO_SELECTED"
-        const val BIOMETRIC_AUTH_TYPE = "BIOMETRIC_AUTH_TYPE"
-        const val BIOMETRIC_AUTH_FAILURE = "BIOMETRIC_AUTH_FAILURE"
+        // TODO(b/333445772) : Qualify error codes fully for propagation
+        const val BIOMETRIC_AUTH_RESULT = "BIOMETRIC_AUTH_RESULT"
+        const val BIOMETRIC_AUTH_ERROR_CODE = "BIOMETRIC_AUTH_ERROR_CODE"
+        const val BIOMETRIC_AUTH_ERROR_MESSAGE = "BIOMETRIC_AUTH_ERROR_MESSAGE"
     }
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 122b896..a0915d2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -46,6 +46,7 @@
 import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
+import com.android.credentialmanager.common.BiometricError
 import com.android.credentialmanager.common.BiometricFlowType
 import com.android.credentialmanager.common.BiometricPromptState
 import com.android.credentialmanager.model.EntryInfo
@@ -581,7 +582,11 @@
     onMoreOptionSelected: () -> Unit,
     requestDisplayInfo: RequestDisplayInfo,
     enabledProviderInfo: EnabledProviderInfo,
-    onBiometricEntrySelected: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
+    onBiometricEntrySelected: (
+        EntryInfo,
+        BiometricPrompt.AuthenticationResult?,
+        BiometricError?
+    ) -> Unit,
     onCancelFlowAndFinish: () -> Unit,
     onIllegalScreenStateAndFinish: (String) -> Unit,
     fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 72b7814..c1120bb3 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -52,6 +52,7 @@
 import androidx.core.graphics.drawable.toBitmap
 import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
+import com.android.credentialmanager.common.BiometricError
 import com.android.credentialmanager.common.BiometricFlowType
 import com.android.credentialmanager.common.BiometricPromptState
 import com.android.credentialmanager.common.ProviderActivityState
@@ -223,7 +224,11 @@
     requestDisplayInfo: RequestDisplayInfo,
     providerInfoList: List<ProviderInfo>,
     providerDisplayInfo: ProviderDisplayInfo,
-    onBiometricEntrySelected: (EntryInfo, BiometricPrompt.AuthenticationResult?) -> Unit,
+    onBiometricEntrySelected: (
+        EntryInfo,
+        BiometricPrompt.AuthenticationResult?,
+        BiometricError?
+    ) -> Unit,
     fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
     getBiometricPromptState: () -> BiometricPromptState,
     onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
diff --git a/packages/PrintSpooler/res/values-night/themes.xml b/packages/PrintSpooler/res/values-night/themes.xml
index 4428dbb..3cc64a6 100644
--- a/packages/PrintSpooler/res/values-night/themes.xml
+++ b/packages/PrintSpooler/res/values-night/themes.xml
@@ -30,6 +30,7 @@
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
+        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
     </style>
 
 </resources>
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 4dcad10..bd96025 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -31,6 +31,7 @@
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowLightStatusBar">true</item>
+        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
     </style>
 
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index 34c60a1..9faebe2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -381,6 +381,14 @@
                 });
     }
 
+    /** Gets devices with matched connection states. */
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[] states) {
+        if (mService == null) {
+            return new ArrayList<BluetoothDevice>(0);
+        }
+        return mService.getDevicesMatchingConnectionStates(states);
+    }
+
     public boolean isEnabled(BluetoothDevice device) {
         if (mService == null || device == null) {
             return false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 9b1e4b7..3e29872 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -52,6 +52,7 @@
 import android.media.RouteListingPreference;
 import android.media.RoutingSessionInfo;
 import android.os.Build;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -131,6 +132,7 @@
     protected final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
     @NonNull protected final Context mContext;
     @NonNull protected final String mPackageName;
+    @NonNull protected final UserHandle mUserHandle;
     private final Collection<MediaDeviceCallback> mCallbacks = new CopyOnWriteArrayList<>();
     private MediaDevice mCurrentConnectedDevice;
     private final LocalBluetoothManager mBluetoothManager;
@@ -140,16 +142,19 @@
     /* package */ InfoMediaManager(
             @NonNull Context context,
             @NonNull String packageName,
+            @NonNull UserHandle userHandle,
             @NonNull LocalBluetoothManager localBluetoothManager) {
         mContext = context;
         mBluetoothManager = localBluetoothManager;
         mPackageName = packageName;
+        mUserHandle = userHandle;
     }
 
     /** Creates an instance of InfoMediaManager. */
     public static InfoMediaManager createInstance(
             Context context,
             @Nullable String packageName,
+            @Nullable UserHandle userHandle,
             LocalBluetoothManager localBluetoothManager) {
 
         // The caller is only interested in system routes (headsets, built-in speakers, etc), and is
@@ -159,16 +164,23 @@
             packageName = context.getPackageName();
         }
 
+        if (userHandle == null) {
+            userHandle = android.os.Process.myUserHandle();
+        }
+
         if (Flags.useMediaRouter2ForInfoMediaManager()) {
             try {
-                return new RouterInfoMediaManager(context, packageName, localBluetoothManager);
+                return new RouterInfoMediaManager(
+                        context, packageName, userHandle, localBluetoothManager);
             } catch (PackageNotAvailableException ex) {
                 // TODO: b/293578081 - Propagate this exception to callers for proper handling.
                 Log.w(TAG, "Returning a no-op InfoMediaManager for package " + packageName);
-                return new NoOpInfoMediaManager(context, packageName, localBluetoothManager);
+                return new NoOpInfoMediaManager(
+                        context, packageName, userHandle, localBluetoothManager);
             }
         } else {
-            return new ManagerInfoMediaManager(context, packageName, localBluetoothManager);
+            return new ManagerInfoMediaManager(
+                    context, packageName, userHandle, localBluetoothManager);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 63056b6..0c2414c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -138,7 +138,10 @@
         }
 
         mInfoMediaManager =
-                InfoMediaManager.createInstance(context, packageName, mLocalBluetoothManager);
+                // TODO: b/321969740 - Take the userHandle as a parameter and pass it through. The
+                // package name is not sufficient to unambiguously identify an app.
+                InfoMediaManager.createInstance(
+                        context, packageName, /* userHandle */ null, mLocalBluetoothManager);
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
index 23063da..d621751 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
@@ -21,6 +21,7 @@
 import android.media.MediaRouter2Manager;
 import android.media.RouteListingPreference;
 import android.media.RoutingSessionInfo;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -53,8 +54,9 @@
     /* package */ ManagerInfoMediaManager(
             Context context,
             @NonNull String packageName,
+            @NonNull UserHandle userHandle,
             LocalBluetoothManager localBluetoothManager) {
-        super(context, packageName, localBluetoothManager);
+        super(context, packageName, userHandle, localBluetoothManager);
 
         mRouterManager = MediaRouter2Manager.getInstance(context);
     }
@@ -87,8 +89,7 @@
 
     @Override
     protected void transferToRoute(@NonNull MediaRoute2Info route) {
-        // TODO: b/279555229 - provide real user handle of a caller.
-        mRouterManager.transfer(mPackageName, route, android.os.Process.myUserHandle());
+        mRouterManager.transfer(mPackageName, route, mUserHandle);
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
index cf11c6d..d2b018c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
@@ -20,6 +20,7 @@
 import android.media.MediaRoute2Info;
 import android.media.RouteListingPreference;
 import android.media.RoutingSessionInfo;
+import android.os.UserHandle;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -58,8 +59,9 @@
     NoOpInfoMediaManager(
             Context context,
             @NonNull String packageName,
+            @NonNull UserHandle userHandle,
             LocalBluetoothManager localBluetoothManager) {
-        super(context, packageName, localBluetoothManager);
+        super(context, packageName, userHandle, localBluetoothManager);
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
index 0dceeba..045c60d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
@@ -25,7 +25,7 @@
 import android.media.RouteDiscoveryPreference;
 import android.media.RouteListingPreference;
 import android.media.RoutingSessionInfo;
-import android.os.Process;
+import android.os.UserHandle;
 import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
@@ -70,15 +70,16 @@
     /* package */ RouterInfoMediaManager(
             Context context,
             @NonNull String packageName,
+            @NonNull UserHandle userHandle,
             LocalBluetoothManager localBluetoothManager)
             throws PackageNotAvailableException {
-        super(context, packageName, localBluetoothManager);
+        super(context, packageName, userHandle, localBluetoothManager);
 
         MediaRouter2 router = null;
 
         if (Flags.enableCrossUserRoutingInMediaRouter2()) {
             try {
-                router = MediaRouter2.getInstance(context, packageName, Process.myUserHandle());
+                router = MediaRouter2.getInstance(context, packageName, userHandle);
             } catch (IllegalArgumentException ex) {
                 // Do nothing
             }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/InfoMediaManagerIntegTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/InfoMediaManagerIntegTest.java
index f0185b9..3bd37a2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/InfoMediaManagerIntegTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/InfoMediaManagerIntegTest.java
@@ -64,21 +64,23 @@
     @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
     public void createInstance_withMR2FlagOn_returnsRouterInfoMediaManager() {
         InfoMediaManager manager =
-                InfoMediaManager.createInstance(mContext, mContext.getPackageName(), null);
+                InfoMediaManager.createInstance(
+                        mContext, mContext.getPackageName(), mContext.getUser(), null);
         assertThat(manager).isInstanceOf(RouterInfoMediaManager.class);
     }
 
     @Test
     @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
     public void createInstance_withMR2FlagOn_withFakePackage_returnsNoOpInfoMediaManager() {
-        InfoMediaManager manager = InfoMediaManager.createInstance(mContext, FAKE_PACKAGE, null);
+        InfoMediaManager manager =
+                InfoMediaManager.createInstance(mContext, FAKE_PACKAGE, null, null);
         assertThat(manager).isInstanceOf(NoOpInfoMediaManager.class);
     }
 
     @Test
     @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
     public void createInstance_withMR2FlagOn_withNullPackage_returnsRouterInfoMediaManager() {
-        InfoMediaManager manager = InfoMediaManager.createInstance(mContext, null, null);
+        InfoMediaManager manager = InfoMediaManager.createInstance(mContext, null, null, null);
         assertThat(manager).isInstanceOf(RouterInfoMediaManager.class);
     }
 
@@ -86,7 +88,8 @@
     @RequiresFlagsDisabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
     public void createInstance_withMR2FlagOff_returnsManagerInfoMediaManager() {
         InfoMediaManager manager =
-                InfoMediaManager.createInstance(mContext, mContext.getPackageName(), null);
+                InfoMediaManager.createInstance(
+                        mContext, mContext.getPackageName(), mContext.getUser(), null);
         assertThat(manager).isInstanceOf(ManagerInfoMediaManager.class);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index d793867..a4b87da 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -144,7 +144,8 @@
         doReturn(mMediaSessionManager).when(mContext).getSystemService(
                 Context.MEDIA_SESSION_SERVICE);
         mInfoMediaManager =
-                new ManagerInfoMediaManager(mContext, TEST_PACKAGE_NAME, mLocalBluetoothManager);
+                new ManagerInfoMediaManager(
+                        mContext, TEST_PACKAGE_NAME, mContext.getUser(), mLocalBluetoothManager);
         mShadowRouter2Manager = ShadowRouter2Manager.getShadow();
         mInfoMediaManager.mRouterManager = MediaRouter2Manager.getInstance(mContext);
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java
index d630301..908f50d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java
@@ -46,6 +46,7 @@
                 new NoOpInfoMediaManager(
                         mContext,
                         /* packageName */ "FAKE_PACKAGE_NAME",
+                        mContext.getUser(),
                         /* localBluetoothManager */ null);
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 2d4b63e..ae9794a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
@@ -65,8 +66,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.scene.shared.model.FakeSceneDataSource
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
@@ -87,7 +86,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.GlobalSettings
 import com.google.common.truth.Truth
-import dagger.Lazy
 import java.util.Optional
 import junit.framework.Assert
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -171,7 +169,7 @@
     private lateinit var sceneInteractor: SceneInteractor
     private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
     private lateinit var deviceEntryInteractor: DeviceEntryInteractor
-    @Mock private lateinit var primaryBouncerInteractor: Lazy<PrimaryBouncerInteractor>
+    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
     private lateinit var sceneTransitionStateFlow: MutableStateFlow<ObservableTransitionState>
     private lateinit var fakeSceneDataSource: FakeSceneDataSource
 
@@ -217,9 +215,13 @@
         )
         mSetFlagsRule.disableFlags(
             FLAG_SIDEFPS_CONTROLLER_REFACTOR,
-            AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
-            AConfigFlags.FLAG_REFACTOR_KEYGUARD_DISMISS_INTENT,
         )
+        if (!com.android.systemui.Flags.sceneContainer()) {
+            mSetFlagsRule.disableFlags(
+                AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
+                AConfigFlags.FLAG_REFACTOR_KEYGUARD_DISMISS_INTENT,
+            )
+        }
 
         keyguardPasswordViewController =
             KeyguardPasswordViewController(
@@ -268,7 +270,6 @@
                 falsingManager,
                 userSwitcherController,
                 featureFlags,
-                kosmos.sceneContainerFlags,
                 globalSettings,
                 sessionTracker,
                 Optional.of(sideFpsController),
@@ -283,7 +284,7 @@
                 deviceProvisionedController,
                 faceAuthAccessibilityDelegate,
                 keyguardTransitionInteractor,
-                primaryBouncerInteractor,
+                { primaryBouncerInteractor },
             ) {
                 deviceEntryInteractor
             }
@@ -804,17 +805,17 @@
     }
 
     @Test
+    @EnableSceneContainer
     fun dismissesKeyguard_whenSceneChangesToGone() =
         kosmos.testScope.runTest {
-            kosmos.fakeSceneContainerFlags.enabled = true
             // Upon init, we have never dismisses the keyguard.
             underTest.onInit()
             runCurrent()
-            verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor, never())
+                .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // Once the view is attached, we start listening but simply going to the bouncer scene
-            // is
-            // not enough to trigger a dismissal of the keyguard.
+            // is not enough to trigger a dismissal of the keyguard.
             underTest.onViewAttached()
             fakeSceneDataSource.pause()
             sceneInteractor.changeScene(Scenes.Bouncer, "reason")
@@ -830,7 +831,8 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
             runCurrent()
-            verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor, never())
+                .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // While listening, going from the bouncer scene to the gone scene, does dismiss the
             // keyguard.
@@ -852,11 +854,11 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
             runCurrent()
-            verify(viewMediatorCallback).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor).notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // While listening, moving back to the bouncer scene does not dismiss the keyguard
             // again.
-            clearInvocations(viewMediatorCallback)
+            clearInvocations(primaryBouncerInteractor)
             fakeSceneDataSource.pause()
             sceneInteractor.changeScene(Scenes.Bouncer, "reason")
             sceneTransitionStateFlow.value =
@@ -871,7 +873,8 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
             runCurrent()
-            verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor, never())
+                .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // Detaching the view stops listening, so moving from the bouncer scene to the gone
             // scene
@@ -891,7 +894,8 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
             runCurrent()
-            verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor, never())
+                .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // While not listening, moving to the lockscreen does not dismiss the keyguard.
             fakeSceneDataSource.pause()
@@ -908,7 +912,8 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Lockscreen)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
             runCurrent()
-            verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor, never())
+                .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
 
             // Reattaching the view starts listening again so moving from the bouncer scene to the
             // gone scene now does dismiss the keyguard again, this time from lockscreen.
@@ -927,7 +932,7 @@
             fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
             sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
             runCurrent()
-            verify(viewMediatorCallback).keyguardDone(anyInt())
+            verify(primaryBouncerInteractor).notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index caf9219..1cd9d76 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.testKosmos
@@ -86,7 +85,6 @@
             AuthenticationRepositoryImpl(
                 applicationScope = testScope.backgroundScope,
                 backgroundDispatcher = kosmos.testDispatcher,
-                flags = kosmos.sceneContainerFlags,
                 clock = clock,
                 getSecurityMode = getSecurityMode,
                 userRepository = userRepository,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
index 741cde8..d850f17 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
@@ -29,10 +29,10 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags.REFACTOR_GETCURRENTUSER
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
 import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
@@ -56,6 +56,7 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class BouncerActionButtonInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
@@ -75,7 +76,6 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        kosmos.fakeSceneContainerFlags.enabled = true
 
         mobileConnectionsRepository = kosmos.fakeMobileConnectionsRepository
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index cbdb71b..361b078 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -30,11 +30,11 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
@@ -50,9 +50,10 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class BouncerInteractorTest : SysuiTestCase() {
 
-    private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val authenticationInteractor = kosmos.authenticationInteractor
     private val uiEventLoggerFake = kosmos.uiEventLoggerFake
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 0db0e07..b83c0ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -34,10 +34,10 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Sim
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
@@ -60,6 +60,7 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class BouncerViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -70,7 +71,6 @@
 
     @Before
     fun setUp() {
-        kosmos.fakeSceneContainerFlags.enabled = true
         underTest = kosmos.bouncerViewModel
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index f21e969..497180b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -52,6 +52,7 @@
 import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
 import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -61,7 +62,6 @@
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.fakeUserTracker
@@ -698,10 +698,9 @@
         }
 
     @Test
+    @EnableSceneContainer
     fun isCommunalShowing_whenSceneContainerEnabled() =
         testScope.runTest {
-            kosmos.fakeSceneContainerFlags.enabled = true
-
             // Verify default is false
             val isCommunalShowing by collectLastValue(underTest.isCommunalShowing)
             runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 5caf35b..37a6ac6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.TrustAgentDisabled
 import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UnattendedUpdate
 import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UserLockdown
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.fakeSystemPropertiesHelper
 import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
@@ -47,7 +48,6 @@
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -62,6 +62,7 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class DeviceEntryInteractorTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -74,7 +75,6 @@
 
     @Before
     fun setUp() {
-        kosmos.fakeSceneContainerFlags.enabled = true
         underTest = kosmos.deviceEntryInteractor
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index 1dd5d07..12f8918 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeCommandQueue
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -37,8 +38,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.data.repository.FakeShadeRepository
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -76,7 +75,6 @@
             repository = repository,
             commandQueue = commandQueue,
             powerInteractor = PowerInteractorFactory.create().powerInteractor,
-            sceneContainerFlags = kosmos.sceneContainerFlags,
             bouncerRepository = bouncerRepository,
             configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()),
             shadeRepository = shadeRepository,
@@ -249,9 +247,9 @@
         }
 
     @Test
+    @EnableSceneContainer
     fun animationDozingTransitions() =
         testScope.runTest {
-            kosmos.fakeSceneContainerFlags.enabled = true
             val isAnimate by collectLastValue(underTest.animateDozingTransitions)
 
             underTest.setAnimateDozingTransitions(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
index 33eb90a..f685058 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.MediaTestHelper
+import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
@@ -172,12 +173,147 @@
             val recommendationsLoadingModel =
                 SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
 
-            underTest.setRecommedationsLoadingState(recommendationsLoadingModel)
+            underTest.setRecommendationsLoadingState(recommendationsLoadingModel)
 
             assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel)
         }
 
+    @Test
+    fun addMediaControlPlayingThenRemote() =
+        testScope.runTest {
+            val sortedMedia by collectLastValue(underTest.sortedMedia)
+            val playingInstanceId = InstanceId.fakeInstanceId(123)
+            val remoteInstanceId = InstanceId.fakeInstanceId(321)
+            val playingData = createMediaData("app1", true, LOCAL, false, playingInstanceId)
+            val remoteData = createMediaData("app2", true, REMOTE, false, remoteInstanceId)
+
+            underTest.addSelectedUserMediaEntry(playingData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId))
+            underTest.addSelectedUserMediaEntry(remoteData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(remoteInstanceId))
+
+            assertThat(sortedMedia?.size).isEqualTo(2)
+            assertThat(sortedMedia?.values)
+                .containsExactly(
+                    MediaCommonModel.MediaControl(playingInstanceId),
+                    MediaCommonModel.MediaControl(remoteInstanceId)
+                )
+        }
+
+    @Test
+    fun switchMediaControlsPlaying() =
+        testScope.runTest {
+            val sortedMedia by collectLastValue(underTest.sortedMedia)
+            val playingInstanceId1 = InstanceId.fakeInstanceId(123)
+            val playingInstanceId2 = InstanceId.fakeInstanceId(321)
+            var playingData1 = createMediaData("app1", true, LOCAL, false, playingInstanceId1)
+            var playingData2 = createMediaData("app2", false, LOCAL, false, playingInstanceId2)
+
+            underTest.addSelectedUserMediaEntry(playingData1)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId1))
+            underTest.addSelectedUserMediaEntry(playingData2)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId2))
+
+            assertThat(sortedMedia?.size).isEqualTo(2)
+            assertThat(sortedMedia?.values)
+                .containsExactly(
+                    MediaCommonModel.MediaControl(playingInstanceId1),
+                    MediaCommonModel.MediaControl(playingInstanceId2)
+                )
+                .inOrder()
+
+            playingData1 = createMediaData("app1", false, LOCAL, false, playingInstanceId1)
+            playingData2 = createMediaData("app2", true, LOCAL, false, playingInstanceId2)
+
+            underTest.addSelectedUserMediaEntry(playingData1)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId1))
+            underTest.addSelectedUserMediaEntry(playingData2)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId2))
+
+            assertThat(sortedMedia?.size).isEqualTo(2)
+            assertThat(sortedMedia?.values)
+                .containsExactly(
+                    MediaCommonModel.MediaControl(playingInstanceId2),
+                    MediaCommonModel.MediaControl(playingInstanceId1)
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun fullOrderTest() =
+        testScope.runTest {
+            val sortedMedia by collectLastValue(underTest.sortedMedia)
+            val instanceId1 = InstanceId.fakeInstanceId(123)
+            val instanceId2 = InstanceId.fakeInstanceId(456)
+            val instanceId3 = InstanceId.fakeInstanceId(321)
+            val instanceId4 = InstanceId.fakeInstanceId(654)
+            val instanceId5 = InstanceId.fakeInstanceId(124)
+            val playingAndLocalData = createMediaData("app1", true, LOCAL, false, instanceId1)
+            val playingAndRemoteData = createMediaData("app2", true, REMOTE, false, instanceId2)
+            val stoppedAndLocalData = createMediaData("app3", false, LOCAL, false, instanceId3)
+            val stoppedAndRemoteData = createMediaData("app4", false, REMOTE, false, instanceId4)
+            val canResumeData = createMediaData("app5", false, LOCAL, true, instanceId5)
+
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
+            val mediaRecommendations =
+                SmartspaceMediaData(
+                    targetId = KEY_MEDIA_SMARTSPACE,
+                    isActive = true,
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
+                )
+
+            underTest.addSelectedUserMediaEntry(stoppedAndLocalData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId3))
+
+            underTest.addSelectedUserMediaEntry(stoppedAndRemoteData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId4))
+
+            underTest.addSelectedUserMediaEntry(canResumeData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId5))
+
+            underTest.addSelectedUserMediaEntry(playingAndLocalData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1))
+
+            underTest.addSelectedUserMediaEntry(playingAndRemoteData)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2))
+
+            underTest.setRecommendation(mediaRecommendations)
+            underTest.setRecommendationsLoadingState(
+                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+            )
+
+            assertThat(sortedMedia?.size).isEqualTo(6)
+            assertThat(sortedMedia?.values)
+                .containsExactly(
+                    MediaCommonModel.MediaControl(instanceId1),
+                    MediaCommonModel.MediaControl(instanceId2),
+                    MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE),
+                    MediaCommonModel.MediaControl(instanceId4),
+                    MediaCommonModel.MediaControl(instanceId3),
+                    MediaCommonModel.MediaControl(instanceId5),
+                )
+                .inOrder()
+        }
+
+    private fun createMediaData(
+        app: String,
+        playing: Boolean,
+        playbackLocation: Int,
+        isResume: Boolean,
+        instanceId: InstanceId,
+    ): MediaData {
+        return MediaData(
+            playbackLocation = playbackLocation,
+            resumption = isResume,
+            notificationKey = "key: $app",
+            isPlaying = playing,
+            instanceId = instanceId
+        )
+    }
+
     companion object {
+        private const val LOCAL = MediaData.PLAYBACK_LOCAL
+        private const val REMOTE = MediaData.PLAYBACK_CAST_LOCAL
         private const val KEY = "KEY"
         private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
index a0a1eb3..c15776e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
 import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
 import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
+import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
@@ -94,22 +95,29 @@
                 collectLastValue(underTest.hasActiveMediaOrRecommendation)
             val hasActiveMedia by collectLastValue(underTest.hasActiveMedia)
             val hasAnyMedia by collectLastValue(underTest.hasAnyMedia)
+            val sortedMedia by collectLastValue(underTest.sortedMedia)
 
             val userMedia = MediaData(active = false)
             val instanceId = userMedia.instanceId
 
             mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
 
             assertThat(hasActiveMediaOrRecommendation).isFalse()
             assertThat(hasActiveMedia).isFalse()
             assertThat(hasAnyMedia).isTrue()
+            assertThat(sortedMedia).containsExactly(MediaCommonModel.MediaControl(instanceId))
 
             assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia))
                 .isTrue()
+            mediaFilterRepository.addMediaDataLoadingState(
+                MediaDataLoadingModel.Removed(instanceId)
+            )
 
             assertThat(hasActiveMediaOrRecommendation).isFalse()
             assertThat(hasActiveMedia).isFalse()
             assertThat(hasAnyMedia).isFalse()
+            assertThat(sortedMedia).isEmpty()
         }
 
     @Test
@@ -119,6 +127,7 @@
                 collectLastValue(underTest.hasActiveMediaOrRecommendation)
             val hasAnyMediaOrRecommendation by
                 collectLastValue(underTest.hasAnyMediaOrRecommendation)
+            val sortedMedia by collectLastValue(underTest.sortedMedia)
             kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
 
             val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
@@ -131,14 +140,28 @@
             val userMedia = MediaData(active = false)
 
             mediaFilterRepository.setRecommendation(userMediaRecommendation)
+            mediaFilterRepository.setRecommendationsLoadingState(
+                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+            )
 
             assertThat(hasActiveMediaOrRecommendation).isTrue()
             assertThat(hasAnyMediaOrRecommendation).isTrue()
+            assertThat(sortedMedia)
+                .containsExactly(MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE))
 
             mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+            mediaFilterRepository.addMediaDataLoadingState(
+                MediaDataLoadingModel.Loaded(userMedia.instanceId)
+            )
 
             assertThat(hasActiveMediaOrRecommendation).isTrue()
             assertThat(hasAnyMediaOrRecommendation).isTrue()
+            assertThat(sortedMedia)
+                .containsExactly(
+                    MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE),
+                    MediaCommonModel.MediaControl(userMedia.instanceId)
+                )
+                .inOrder()
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
index 1cba185..d9224d7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
@@ -187,7 +187,12 @@
         underTest.startMediaOutputDialog(expandable, PACKAGE_NAME)
 
         verify(kosmos.mediaOutputDialogManager)
-            .createAndShowWithController(eq(PACKAGE_NAME), eq(true), eq(dialogTransitionController))
+            .createAndShowWithController(
+                eq(PACKAGE_NAME),
+                eq(true),
+                eq(dialogTransitionController),
+                eq(null)
+            )
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index a277fe0..470d342 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -51,6 +51,7 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
@@ -69,7 +70,6 @@
 import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.startable.SceneContainerStartable
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -128,9 +128,10 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
+@EnableSceneContainer
 class SceneFrameworkIntegrationTest : SysuiTestCase() {
 
-    private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneContainerConfig by lazy { kosmos.sceneContainerConfig }
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
@@ -236,15 +237,15 @@
                 applicationScope = testScope.backgroundScope,
                 sceneInteractor = sceneInteractor,
                 deviceEntryInteractor = deviceEntryInteractor,
+                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
+                bouncerInteractor = bouncerInteractor,
                 keyguardInteractor = keyguardInteractor,
-                flags = kosmos.fakeSceneContainerFlags,
                 sysUiState = sysUiState,
                 displayId = displayTracker.defaultDisplayId,
                 sceneLogger = mock(),
                 falsingCollector = kosmos.falsingCollector,
                 falsingManager = kosmos.falsingManager,
                 powerInteractor = powerInteractor,
-                bouncerInteractor = bouncerInteractor,
                 simBouncerInteractor = dagger.Lazy { kosmos.simBouncerInteractor },
                 authenticationInteractor = dagger.Lazy { kosmos.authenticationInteractor },
                 windowController = mock(),
@@ -253,7 +254,6 @@
                 headsUpInteractor = kosmos.headsUpNotificationInteractor,
                 occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
                 faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
-                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
                 shadeInteractor = kosmos.shadeInteractor,
             )
         startable.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 7f7c24e..8e2eea1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -23,10 +23,10 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.sceneContainerConfig
 import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -39,9 +39,10 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class SceneContainerRepositoryTest : SysuiTestCase() {
 
-    private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index b179c30..63f4816 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -23,13 +23,13 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.sceneContainerRepository
 import com.android.systemui.scene.sceneContainerConfig
 import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
@@ -45,6 +45,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class SceneInteractorTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -55,7 +56,6 @@
 
     @Before
     fun setUp() {
-        kosmos.fakeSceneContainerFlags.enabled = true
         underTest = kosmos.sceneInteractor
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
index d5e43f4..bfe5ef7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
 import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.statusbar.NotificationPresenter
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
 import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
@@ -82,7 +81,6 @@
                 headsUpManager,
                 powerInteractor,
                 activeNotificationsInteractor,
-                kosmos.sceneContainerFlags,
                 kosmos::sceneInteractor,
             )
             .apply { setUp(notificationPresenter, notificationsController) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 61adcd2..1472a4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -54,7 +54,6 @@
 import com.android.systemui.power.shared.model.WakefulnessState
 import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -102,7 +101,6 @@
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
-    private val sceneContainerFlags by lazy { kosmos.fakeSceneContainerFlags }
     private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
     private val bouncerInteractor by lazy { kosmos.bouncerInteractor }
     private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository }
@@ -124,15 +122,15 @@
                 applicationScope = testScope.backgroundScope,
                 sceneInteractor = sceneInteractor,
                 deviceEntryInteractor = deviceEntryInteractor,
+                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
+                bouncerInteractor = bouncerInteractor,
                 keyguardInteractor = keyguardInteractor,
-                flags = sceneContainerFlags,
                 sysUiState = sysUiState,
                 displayId = Display.DEFAULT_DISPLAY,
                 sceneLogger = mock(),
                 falsingCollector = falsingCollector,
                 falsingManager = kosmos.falsingManager,
                 powerInteractor = powerInteractor,
-                bouncerInteractor = bouncerInteractor,
                 simBouncerInteractor = { kosmos.simBouncerInteractor },
                 authenticationInteractor = { authenticationInteractor },
                 windowController = windowController,
@@ -141,7 +139,6 @@
                 headsUpInteractor = kosmos.headsUpNotificationInteractor,
                 occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
                 faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
-                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
                 shadeInteractor = kosmos.shadeInteractor,
             )
     }
@@ -1245,7 +1242,6 @@
             "Cannot start on the Gone scene and have the device be locked at the same time."
         }
 
-        sceneContainerFlags.enabled = true
         kosmos.fakeDeviceEntryRepository.setBypassEnabled(isBypassEnabled)
         authenticationMethod?.let {
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authenticationMethod)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
index 2938acf..ae5bf07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.EnableSceneContainer
-import com.android.systemui.kosmos.Kosmos
 import com.google.common.truth.Truth
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -34,15 +33,11 @@
     @DisableSceneContainer
     fun isNotEnabled_withoutAconfigFlags() {
         Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false)
-        Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false)
-        Truth.assertThat(Kosmos().sceneContainerFlags.isEnabled()).isEqualTo(false)
     }
 
     @Test
     @EnableSceneContainer
     fun isEnabled_withAconfigFlags() {
         Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(true)
-        Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(true)
-        Truth.assertThat(Kosmos().sceneContainerFlags.isEnabled()).isEqualTo(true)
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 7b0127e..427b66b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -23,13 +23,13 @@
 import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.classifier.fakeFalsingManager
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.sceneContainerConfig
 import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
@@ -45,6 +45,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class SceneContainerViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -58,7 +59,6 @@
 
     @Before
     fun setUp() {
-        kosmos.fakeSceneContainerFlags.enabled = true
         underTest =
             SceneContainerViewModel(
                 sceneInteractor = sceneInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
index cbbcce9..420418b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
@@ -22,6 +22,7 @@
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
@@ -30,7 +31,6 @@
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -52,6 +52,7 @@
 @ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class ShadeControllerSceneImplTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val testScope = kosmos.testScope
@@ -64,7 +65,6 @@
     @Before
     fun setup() {
         kosmos.testCase = this
-        kosmos.fakeSceneContainerFlags.enabled = true
         kosmos.fakeFeatureFlagsClassic.apply {
             set(Flags.FULL_SCREEN_USER_SWITCHER, false)
             set(Flags.NSSL_DEBUG_LINES, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
index e759b50..26f342a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
@@ -22,9 +22,9 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shared.recents.utilities.Utilities
 import com.android.systemui.testKosmos
@@ -43,8 +43,9 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @Ignore("b/328827631")
+@EnableSceneContainer
 class ShadeBackActionInteractorImplTest : SysuiTestCase() {
-    val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+    val kosmos = testKosmos()
     val testScope = kosmos.testScope
     val sceneInteractor = kosmos.sceneInteractor
     val underTest = kosmos.shadeBackActionInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index a3cf929..01e1aa59 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -23,11 +23,11 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
@@ -46,11 +46,11 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
 class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
 
     private val kosmos =
         testKosmos().apply {
-            fakeSceneContainerFlags.enabled = true
             fakeFeatureFlagsClassic.apply {
                 set(Flags.FULL_SCREEN_USER_SWITCHER, false)
                 set(Flags.NSSL_DEBUG_LINES, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 8f7a56d..a023033 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -52,7 +52,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.mockLargeScreenHeaderHelper
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -128,7 +127,7 @@
 
     @Before
     fun setUp() {
-        assertThat(kosmos.sceneContainerFlags.isEnabled()).isEqualTo(SceneContainerFlag.isEnabled)
+        assertThat(SceneContainerFlag.isEnabled).isEqualTo(SceneContainerFlag.isEnabled)
         overrideResource(R.bool.config_use_split_notification_shade, false)
         movementFlow = MutableStateFlow(BurnInModel())
         whenever(aodBurnInViewModel.movement(any())).thenReturn(movementFlow)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index c509356..e8e1cab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -90,7 +90,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -134,7 +134,6 @@
     private final UserSwitcherController mUserSwitcherController;
     private final GlobalSettings mGlobalSettings;
     private final FeatureFlags mFeatureFlags;
-    private final SceneContainerFlags mSceneContainerFlags;
     private final SessionTracker mSessionTracker;
     private final Optional<SideFpsController> mSideFpsController;
     private final FalsingA11yDelegate mFalsingA11yDelegate;
@@ -456,7 +455,6 @@
             FalsingManager falsingManager,
             UserSwitcherController userSwitcherController,
             FeatureFlags featureFlags,
-            SceneContainerFlags sceneContainerFlags,
             GlobalSettings globalSettings,
             SessionTracker sessionTracker,
             Optional<SideFpsController> sideFpsController,
@@ -491,7 +489,6 @@
         mFalsingManager = falsingManager;
         mUserSwitcherController = userSwitcherController;
         mFeatureFlags = featureFlags;
-        mSceneContainerFlags = sceneContainerFlags;
         mGlobalSettings = globalSettings;
         mSessionTracker = sessionTracker;
         if (SideFpsControllerRefactor.isEnabled()) {
@@ -534,7 +531,7 @@
 
         showPrimarySecurityScreen(false);
 
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             // When the scene framework says that the lockscreen has been dismissed, dismiss the
             // keyguard here, revealing the underlying app or launcher:
             mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow(
diff --git a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
index 4e5df35..cf2675b 100644
--- a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
@@ -74,7 +74,7 @@
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -131,7 +131,6 @@
     @NonNull private final KeyguardInteractor mKeyguardInteractor;
     @NonNull private final View.AccessibilityDelegate mAccessibilityDelegate;
     @NonNull private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractor;
-    @NonNull private final SceneContainerFlags mSceneContainerFlags;
 
     // Tracks the velocity of a touch to help filter out the touches that move too fast.
     private VelocityTracker mVelocityTracker;
@@ -208,8 +207,7 @@
             @NonNull FeatureFlags featureFlags,
             PrimaryBouncerInteractor primaryBouncerInteractor,
             Context context,
-            Lazy<DeviceEntryInteractor> deviceEntryInteractor,
-            SceneContainerFlags sceneContainerFlags
+            Lazy<DeviceEntryInteractor> deviceEntryInteractor
     ) {
         mStatusBarStateController = statusBarStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -236,7 +234,6 @@
         mResources = resources;
         mContext = context;
         mDeviceEntryInteractor = deviceEntryInteractor;
-        mSceneContainerFlags = sceneContainerFlags;
 
         mAccessibilityDelegate = new View.AccessibilityDelegate() {
             private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint =
@@ -746,7 +743,7 @@
         // play device entry haptic (consistent with UDFPS controller longpress)
         vibrateOnLongPress();
 
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             mDeviceEntryInteractor.get().attemptDeviceEntry();
         } else {
             mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index 454ed27..a9f985f 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -36,7 +36,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.kotlin.onSubscriberAdded
@@ -186,7 +186,6 @@
 constructor(
     @Application private val applicationScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
-    flags: SceneContainerFlags,
     private val clock: SystemClock,
     private val getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>,
     private val userRepository: UserRepository,
@@ -255,7 +254,7 @@
     override val hasLockoutOccurred: StateFlow<Boolean> = _hasLockoutOccurred.asStateFlow()
 
     init {
-        if (flags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             // Hydrate failedAuthenticationAttempts initially and whenever the selected user
             // changes.
             applicationScope.launch {
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogDelegate.java
index 66aeda6..207f7db 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogDelegate.java
@@ -217,10 +217,13 @@
         mSwitchBroadcast.setText(mContext.getString(
                 R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp), null);
         mSwitchBroadcast.setOnClickListener((view) -> startSwitchBroadcast());
-        changeOutput.setOnClickListener((view) -> {
-            mMediaOutputDialogManager.createAndShow(mOutputPackageName, true, null);
-            dialog.dismiss();
-        });
+        changeOutput.setOnClickListener(
+                (view) -> {
+                    // TODO: b/321969740 - Take the userHandle as a parameter and pass it through.
+                    //  The package name is not sufficient to unambiguously identify an app.
+                    mMediaOutputDialogManager.createAndShow(mOutputPackageName, true, null, null);
+                    dialog.dismiss();
+                });
         cancelBtn.setOnClickListener((view) -> {
             if (DEBUG) {
                 Log.d(TAG, "BroadcastDialog dismiss.");
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
index e789475..62ef365 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.Flags
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import dagger.Module
 import dagger.Provides
 
@@ -42,11 +42,10 @@
     fun isOnlyComposeBouncerEnabled(): Boolean
 }
 
-class ComposeBouncerFlagsImpl(private val sceneContainerFlags: SceneContainerFlags) :
-    ComposeBouncerFlags {
+class ComposeBouncerFlagsImpl() : ComposeBouncerFlags {
 
     override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
-        return sceneContainerFlags.isEnabled() || Flags.composeBouncer()
+        return SceneContainerFlag.isEnabled || Flags.composeBouncer()
     }
 
     @Deprecated(
@@ -55,7 +54,7 @@
         replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()")
     )
     override fun isOnlyComposeBouncerEnabled(): Boolean {
-        return !sceneContainerFlags.isEnabled() && Flags.composeBouncer()
+        return !SceneContainerFlag.isEnabled && Flags.composeBouncer()
     }
 }
 
@@ -63,7 +62,7 @@
 object ComposeBouncerFlagsModule {
     @Provides
     @SysUISingleton
-    fun impl(sceneContainerFlags: SceneContainerFlags): ComposeBouncerFlags {
-        return ComposeBouncerFlagsImpl(sceneContainerFlags)
+    fun impl(): ComposeBouncerFlags {
+        return ComposeBouncerFlagsImpl()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index af467ef..613280c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -22,7 +22,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.phone.NotificationTapHelper;
 
 import dagger.Binds;
@@ -51,9 +51,8 @@
     @SysUISingleton
     static FalsingCollector providesFalsingCollectorLegacy(
             FalsingCollectorImpl impl,
-            FalsingCollectorNoOp noOp,
-            SceneContainerFlags flags) {
-        return flags.isEnabled() ? noOp : impl;
+            FalsingCollectorNoOp noOp) {
+        return SceneContainerFlag.isEnabled() ? noOp : impl;
     }
 
     /** Provides the actual {@link FalsingCollector}. */
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 373e1c9..619e052 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -55,7 +55,7 @@
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.smartspace.data.repository.SmartspaceRepository
@@ -107,7 +107,6 @@
     private val userManager: UserManager,
     private val dockManager: DockManager,
     sceneInteractor: SceneInteractor,
-    sceneContainerFlags: SceneContainerFlags,
     @CommunalLog logBuffer: LogBuffer,
     @CommunalTableLog tableLogBuffer: TableLogBuffer,
 ) {
@@ -216,7 +215,7 @@
      */
     // TODO(b/323215860): rename to something more appropriate after cleaning up usages
     val isCommunalShowing: Flow<Boolean> =
-        flow { emit(sceneContainerFlags.isEnabled()) }
+        flow { emit(SceneContainerFlag.isEnabled) }
             .flatMapLatest { sceneContainerEnabled ->
                 if (sceneContainerEnabled) {
                     sceneInteractor.currentScene.map { it == Scenes.Communal }
diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
deleted file mode 100644
index 989b0de..0000000
--- a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.display.ui.view
-
-import android.content.Context
-import android.os.Bundle
-import android.view.View
-import android.view.WindowInsets
-import android.widget.TextView
-import androidx.core.view.updatePadding
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.phone.SystemUIBottomSheetDialog
-import com.android.systemui.statusbar.policy.ConfigurationController
-import kotlin.math.max
-
-/**
- * Dialog used to decide what to do with a connected display.
- *
- * [onCancelMirroring] is called **only** if mirroring didn't start, or when the dismiss button is
- * pressed.
- */
-class MirroringConfirmationDialog(
-    context: Context,
-    private val onStartMirroringClickListener: View.OnClickListener,
-    private val onCancelMirroring: View.OnClickListener,
-    private val navbarBottomInsetsProvider: () -> Int,
-    configurationController: ConfigurationController? = null,
-    private val showConcurrentDisplayInfo: Boolean = false,
-    theme: Int = R.style.Theme_SystemUI_Dialog,
-) : SystemUIBottomSheetDialog(context, configurationController, theme) {
-
-    private lateinit var mirrorButton: TextView
-    private lateinit var dismissButton: TextView
-    private lateinit var dualDisplayWarning: TextView
-    private lateinit var bottomSheet: View
-    private var enabledPressed = false
-    private val defaultDialogBottomInset =
-        context.resources.getDimensionPixelSize(R.dimen.dialog_bottom_padding)
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContentView(R.layout.connected_display_dialog)
-
-        mirrorButton =
-            requireViewById<TextView>(R.id.enable_display).apply {
-                setOnClickListener(onStartMirroringClickListener)
-                enabledPressed = true
-            }
-        dismissButton =
-            requireViewById<TextView>(R.id.cancel).apply { setOnClickListener(onCancelMirroring) }
-
-        dualDisplayWarning =
-            requireViewById<TextView>(R.id.dual_display_warning).apply {
-                visibility = if (showConcurrentDisplayInfo) View.VISIBLE else View.GONE
-            }
-
-        bottomSheet = requireViewById(R.id.cd_bottom_sheet)
-
-        setOnDismissListener {
-            if (!enabledPressed) {
-                onCancelMirroring.onClick(null)
-            }
-        }
-        setupInsets()
-    }
-
-    private fun setupInsets(navbarInsets: Int = navbarBottomInsetsProvider()) {
-        // This avoids overlap between dialog content and navigation bars.
-        // we only care about the bottom inset as in all other configuration where navigations
-        // are in other display sides there is no overlap with the dialog.
-        bottomSheet.updatePadding(bottom = max(navbarInsets, defaultDialogBottomInset))
-    }
-
-    override fun onInsetsChanged(changedTypes: Int, insets: WindowInsets) {
-        val navbarType = WindowInsets.Type.navigationBars()
-        if (changedTypes and navbarType != 0) {
-            setupInsets(insets.getInsets(navbarType).bottom)
-        }
-    }
-
-    override fun onConfigurationChanged() {
-        super.onConfigurationChanged()
-        setupInsets()
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegate.kt
new file mode 100644
index 0000000..19b2673
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegate.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.display.ui.view
+
+import android.app.Dialog
+import android.content.Context
+import android.content.res.Configuration
+import android.os.Bundle
+import android.view.View
+import android.view.WindowInsets
+import android.view.WindowInsetsAnimation
+import android.widget.TextView
+import androidx.annotation.StyleRes
+import androidx.annotation.VisibleForTesting
+import androidx.core.view.updatePadding
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.DialogDelegate
+import com.android.systemui.statusbar.phone.SystemUIBottomSheetDialog
+import javax.inject.Inject
+import kotlin.math.max
+
+/**
+ * Dialog used to decide what to do with a connected display.
+ *
+ * [onCancelMirroring] is called **only** if mirroring didn't start, or when the dismiss button is
+ * pressed.
+ */
+class MirroringConfirmationDialogDelegate
+@VisibleForTesting
+constructor(
+    context: Context,
+    private val showConcurrentDisplayInfo: Boolean = false,
+    private val onStartMirroringClickListener: View.OnClickListener,
+    private val onCancelMirroring: View.OnClickListener,
+    private val navbarBottomInsetsProvider: () -> Int,
+) : DialogDelegate<Dialog> {
+
+    private lateinit var mirrorButton: TextView
+    private lateinit var dismissButton: TextView
+    private lateinit var dualDisplayWarning: TextView
+    private lateinit var bottomSheet: View
+    private var enabledPressed = false
+    private val defaultDialogBottomInset =
+        context.resources.getDimensionPixelSize(R.dimen.dialog_bottom_padding)
+
+    override fun onCreate(dialog: Dialog, savedInstanceState: Bundle?) {
+        dialog.setContentView(R.layout.connected_display_dialog)
+
+        mirrorButton =
+            dialog.requireViewById<TextView>(R.id.enable_display).apply {
+                setOnClickListener(onStartMirroringClickListener)
+                enabledPressed = true
+            }
+        dismissButton =
+            dialog.requireViewById<TextView>(R.id.cancel).apply {
+                setOnClickListener(onCancelMirroring)
+            }
+
+        dualDisplayWarning =
+            dialog.requireViewById<TextView>(R.id.dual_display_warning).apply {
+                visibility = if (showConcurrentDisplayInfo) View.VISIBLE else View.GONE
+            }
+
+        bottomSheet = dialog.requireViewById(R.id.cd_bottom_sheet)
+
+        dialog.setOnDismissListener {
+            if (!enabledPressed) {
+                onCancelMirroring.onClick(null)
+            }
+        }
+        setupInsets()
+    }
+
+    override fun onStart(dialog: Dialog) {
+        dialog.window?.decorView?.setWindowInsetsAnimationCallback(insetsAnimationCallback)
+    }
+
+    override fun onStop(dialog: Dialog) {
+        dialog.window?.decorView?.setWindowInsetsAnimationCallback(null)
+    }
+
+    private fun setupInsets(navbarInsets: Int = navbarBottomInsetsProvider()) {
+        // This avoids overlap between dialog content and navigation bars.
+        // we only care about the bottom inset as in all other configuration where navigations
+        // are in other display sides there is no overlap with the dialog.
+        bottomSheet.updatePadding(bottom = max(navbarInsets, defaultDialogBottomInset))
+    }
+
+    override fun onConfigurationChanged(dialog: Dialog, configuration: Configuration) {
+        setupInsets()
+    }
+
+    private val insetsAnimationCallback =
+        object : WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+
+            private var lastInsets: WindowInsets? = null
+
+            override fun onEnd(animation: WindowInsetsAnimation) {
+                lastInsets?.let { onInsetsChanged(animation.typeMask, it) }
+            }
+
+            override fun onProgress(
+                insets: WindowInsets,
+                animations: MutableList<WindowInsetsAnimation>,
+            ): WindowInsets {
+                lastInsets = insets
+                onInsetsChanged(changedTypes = allAnimationMasks(animations), insets)
+                return insets
+            }
+
+            private fun allAnimationMasks(animations: List<WindowInsetsAnimation>): Int =
+                animations.fold(0) { acc: Int, it -> acc or it.typeMask }
+
+            private fun onInsetsChanged(changedTypes: Int, insets: WindowInsets) {
+                val navbarType = WindowInsets.Type.navigationBars()
+                if (changedTypes and navbarType != 0) {
+                    setupInsets(insets.getInsets(navbarType).bottom)
+                }
+            }
+        }
+
+    class Factory
+    @Inject
+    constructor(
+        @Application private val context: Context,
+        private val dialogFactory: SystemUIBottomSheetDialog.Factory,
+    ) {
+
+        fun createDialog(
+            showConcurrentDisplayInfo: Boolean = false,
+            onStartMirroringClickListener: View.OnClickListener,
+            onCancelMirroring: View.OnClickListener,
+            navbarBottomInsetsProvider: () -> Int,
+            @StyleRes theme: Int = R.style.Theme_SystemUI_Dialog,
+        ): Dialog =
+            dialogFactory.create(
+                delegate =
+                    MirroringConfirmationDialogDelegate(
+                        context = context,
+                        showConcurrentDisplayInfo = showConcurrentDisplayInfo,
+                        onStartMirroringClickListener = onStartMirroringClickListener,
+                        onCancelMirroring = onCancelMirroring,
+                        navbarBottomInsetsProvider = navbarBottomInsetsProvider,
+                    ),
+                theme = theme,
+            )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt
index fbf0538..81ea2e7 100644
--- a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt
@@ -25,8 +25,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.PendingDisplay
-import com.android.systemui.display.ui.view.MirroringConfirmationDialog
-import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.display.ui.view.MirroringConfirmationDialogDelegate
 import dagger.Binds
 import dagger.Module
 import dagger.multibindings.ClassKey
@@ -54,7 +53,7 @@
     private val connectedDisplayInteractor: ConnectedDisplayInteractor,
     @Application private val scope: CoroutineScope,
     @Background private val bgDispatcher: CoroutineDispatcher,
-    private val configurationController: ConfigurationController,
+    private val bottomSheetFactory: MirroringConfirmationDialogDelegate.Factory,
 ) : CoreStartable {
 
     private var dialog: Dialog? = null
@@ -91,8 +90,8 @@
     private fun showDialog(pendingDisplay: PendingDisplay, concurrentDisplaysInProgess: Boolean) {
         hideDialog()
         dialog =
-            MirroringConfirmationDialog(
-                    context,
+            bottomSheetFactory
+                .createDialog(
                     onStartMirroringClickListener = {
                         scope.launch(bgDispatcher) { pendingDisplay.enable() }
                         hideDialog()
@@ -102,7 +101,6 @@
                         hideDialog()
                     },
                     navbarBottomInsetsProvider = { Utils.getNavbarInsets(context).bottom },
-                    configurationController,
                     showConcurrentDisplayInfo = concurrentDisplaysInProgess
                 )
                 .apply { show() }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
index bf1f074..eef4b97 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -52,7 +52,6 @@
     @Application private val applicationScope: CoroutineScope,
     @Application private val context: Context,
     deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
-    private val sceneContainerFlags: SceneContainerFlags,
     private val sceneInteractor: SceneInteractor,
     private val primaryBouncerInteractor: PrimaryBouncerInteractor,
     alternateBouncerInteractor: AlternateBouncerInteractor,
@@ -75,7 +74,7 @@
         get() = context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
 
     private val isBouncerSceneActive: Flow<Boolean> =
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             sceneInteractor.currentScene.map { it == Scenes.Bouncer }.distinctUntilChanged()
         } else {
             flowOf(false)
@@ -115,7 +114,7 @@
             .distinctUntilChanged()
 
     private fun isBouncerActive(): Boolean {
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             return sceneInteractor.currentScene.value == Scenes.Bouncer
         }
         return primaryBouncerInteractor.isBouncerShowing() &&
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index c476948..7224536 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -44,7 +44,7 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.data.repository.ShadeRepository
 import com.android.systemui.statusbar.CommandQueue
@@ -84,7 +84,6 @@
     private val repository: KeyguardRepository,
     private val commandQueue: CommandQueue,
     powerInteractor: PowerInteractor,
-    sceneContainerFlags: SceneContainerFlags,
     bouncerRepository: KeyguardBouncerRepository,
     configurationInteractor: ConfigurationInteractor,
     shadeRepository: ShadeRepository,
@@ -331,7 +330,7 @@
 
     /** Whether to animate the next doze mode transition. */
     val animateDozingTransitions: Flow<Boolean> by lazy {
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             sceneInteractorProvider
                 .get()
                 .transitioningTo
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 5ee35e4f..cc54920 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -30,6 +30,9 @@
 import android.view.ViewGroup.OnHierarchyChangeListener
 import android.view.ViewPropertyAnimator
 import android.view.WindowInsets
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
@@ -49,6 +52,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.shared.ComposeLockscreen
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
@@ -125,6 +129,21 @@
         disposables +=
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    if (ComposeLockscreen.isEnabled) {
+                        view.setViewTreeOnBackPressedDispatcherOwner(
+                            object : OnBackPressedDispatcherOwner {
+                                override val onBackPressedDispatcher =
+                                    OnBackPressedDispatcher().apply {
+                                        setOnBackInvokedDispatcher(
+                                            view.viewRootImpl.onBackInvokedDispatcher
+                                        )
+                                    }
+
+                                override val lifecycle: Lifecycle =
+                                    [email protected]
+                            }
+                        )
+                    }
                     launch {
                         occludingAppDeviceEntryMessageViewModel.message.collect { biometricMessage
                             ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 49fffdd..45dca99 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -30,7 +30,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.util.kotlin.sample
 import dagger.Lazy
@@ -64,7 +64,6 @@
     transitionInteractor: KeyguardTransitionInteractor,
     val keyguardInteractor: KeyguardInteractor,
     val viewModel: AodToLockscreenTransitionViewModel,
-    private val sceneContainerFlags: SceneContainerFlags,
     private val keyguardViewController: Lazy<KeyguardViewController>,
     private val deviceEntryInteractor: DeviceEntryInteractor,
     private val deviceEntrySourceInteractor: DeviceEntrySourceInteractor,
@@ -242,7 +241,7 @@
         }
 
     suspend fun onLongPress() {
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             deviceEntryInteractor.attemptDeviceEntry()
         } else {
             keyguardViewController.get().showPrimaryBouncer(/* scrim */ true)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/model/MediaSortKeyModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/model/MediaSortKeyModel.kt
new file mode 100644
index 0000000..cfe5cde
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/model/MediaSortKeyModel.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.data.model
+
+import com.android.internal.logging.InstanceId
+import com.android.systemui.media.controls.shared.model.MediaData.Companion.PLAYBACK_LOCAL
+
+data class MediaSortKeyModel(
+    /** Whether the item represents a Smartspace media recommendation that should be prioritized. */
+    val isPrioritizedRec: Boolean = false,
+    val isPlaying: Boolean? = null,
+    val playbackLocation: Int = PLAYBACK_LOCAL,
+    val active: Boolean = true,
+    val isResume: Boolean = false,
+    val lastActive: Long = 0L,
+    val notificationKey: String? = null,
+    val updateTime: Long = 0,
+    val instanceId: InstanceId? = null,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
index 9dc5900..7e57cf4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
@@ -18,10 +18,14 @@
 
 import com.android.internal.logging.InstanceId
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.media.controls.data.model.MediaSortKeyModel
+import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.util.time.SystemClock
+import java.util.TreeMap
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -29,7 +33,7 @@
 
 /** A repository that holds the state of filtered media data on the device. */
 @SysUISingleton
-class MediaFilterRepository @Inject constructor() {
+class MediaFilterRepository @Inject constructor(private val systemClock: SystemClock) {
 
     /** Instance id of media control that recommendations card reactivated. */
     private val _reactivatedId: MutableStateFlow<InstanceId?> = MutableStateFlow(null)
@@ -58,6 +62,26 @@
     val recommendationsLoadingState: StateFlow<SmartspaceMediaLoadingModel> =
         _recommendationsLoadingState.asStateFlow()
 
+    private val comparator =
+        compareByDescending<MediaSortKeyModel> {
+                it.isPlaying == true && it.playbackLocation == MediaData.PLAYBACK_LOCAL
+            }
+            .thenByDescending {
+                it.isPlaying == true && it.playbackLocation == MediaData.PLAYBACK_CAST_LOCAL
+            }
+            .thenByDescending { it.active }
+            .thenByDescending { it.isPrioritizedRec }
+            .thenByDescending { !it.isResume }
+            .thenByDescending { it.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE }
+            .thenByDescending { it.lastActive }
+            .thenByDescending { it.updateTime }
+            .thenByDescending { it.notificationKey }
+
+    private val _sortedMedia: MutableStateFlow<TreeMap<MediaSortKeyModel, MediaCommonModel>> =
+        MutableStateFlow(TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator))
+    val sortedMedia: StateFlow<Map<MediaSortKeyModel, MediaCommonModel>> =
+        _sortedMedia.asStateFlow()
+
     fun addMediaEntry(key: String, data: MediaData) {
         val entries = LinkedHashMap<String, MediaData>(_allUserEntries.value)
         entries[key] = data
@@ -138,9 +162,91 @@
                 } else {
                     emptyList()
                 }
+
+        addMediaLoadingToSortedMap(mediaDataLoadingModel)
     }
 
-    fun setRecommedationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) {
+    fun setRecommendationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) {
         _recommendationsLoadingState.value = smartspaceMediaLoadingModel
+
+        addRecsLoadingToSortedMap(smartspaceMediaLoadingModel)
+    }
+
+    private fun addMediaLoadingToSortedMap(mediaDataLoadingModel: MediaDataLoadingModel) {
+        val instanceId =
+            when (mediaDataLoadingModel) {
+                is MediaDataLoadingModel.Loaded -> mediaDataLoadingModel.instanceId
+                is MediaDataLoadingModel.Removed -> mediaDataLoadingModel.instanceId
+                MediaDataLoadingModel.Unknown -> null
+            }
+        val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)
+        sortedMap.putAll(
+            _sortedMedia.value.filter { (_, commonModel) ->
+                commonModel !is MediaCommonModel.MediaControl ||
+                    commonModel.instanceId != instanceId
+            }
+        )
+
+        _selectedUserEntries.value[instanceId]?.let {
+            val sortKey =
+                MediaSortKeyModel(
+                    isPrioritizedRec = false,
+                    it.isPlaying,
+                    it.playbackLocation,
+                    it.active,
+                    it.resumption,
+                    it.lastActive,
+                    it.notificationKey,
+                    systemClock.currentTimeMillis(),
+                    it.instanceId,
+                )
+
+            if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) {
+                sortedMap[sortKey] = MediaCommonModel.MediaControl(it.instanceId)
+            }
+        }
+
+        _sortedMedia.value = sortedMap
+    }
+
+    private fun addRecsLoadingToSortedMap(
+        smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel
+    ) {
+        val isPrioritized: Boolean
+        val key: String?
+        when (smartspaceMediaLoadingModel) {
+            is SmartspaceMediaLoadingModel.Loaded -> {
+                isPrioritized = smartspaceMediaLoadingModel.isPrioritized
+                key = smartspaceMediaLoadingModel.key
+            }
+            is SmartspaceMediaLoadingModel.Removed -> {
+                isPrioritized = false
+                key = smartspaceMediaLoadingModel.key
+            }
+            SmartspaceMediaLoadingModel.Unknown -> {
+                isPrioritized = false
+                key = null
+            }
+        }
+        val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)
+        sortedMap.putAll(
+            _sortedMedia.value.filter { (_, commonModel) ->
+                commonModel !is MediaCommonModel.MediaRecommendations || commonModel.key != key
+            }
+        )
+
+        key?.let {
+            val sortKey =
+                MediaSortKeyModel(
+                    isPrioritizedRec = isPrioritized,
+                    isPlaying = false,
+                    active = _smartspaceMediaData.value.isActive,
+                )
+            if (smartspaceMediaLoadingModel is SmartspaceMediaLoadingModel.Loaded) {
+                sortedMap[sortKey] = MediaCommonModel.MediaRecommendations(key)
+            }
+        }
+
+        _sortedMedia.value = sortedMap
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
index a30e582..e8d3274 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
@@ -186,7 +186,7 @@
             smartspaceMediaData.packageName,
             smartspaceMediaData.instanceId
         )
-        mediaFilterRepository.setRecommedationsLoadingState(
+        mediaFilterRepository.setRecommendationsLoadingState(
             SmartspaceMediaLoadingModel.Loaded(key, shouldPrioritizeMutable)
         )
     }
@@ -224,7 +224,7 @@
                 )
             )
         }
-        mediaFilterRepository.setRecommedationsLoadingState(
+        mediaFilterRepository.setRecommendationsLoadingState(
             SmartspaceMediaLoadingModel.Removed(key, immediately)
         )
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index cdcf363..c3ba913 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.media.controls.domain.pipeline.MediaSessionBasedFilter
 import com.android.systemui.media.controls.domain.pipeline.MediaTimeoutListener
 import com.android.systemui.media.controls.domain.resume.MediaResumeListener
+import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
 import com.android.systemui.media.controls.util.MediaFlags
@@ -46,6 +47,7 @@
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.stateIn
 
@@ -120,6 +122,10 @@
     val recommendationsLoadingState: Flow<SmartspaceMediaLoadingModel> =
         mediaFilterRepository.recommendationsLoadingState
 
+    /** The most recent sorted set for user media instances */
+    val sortedMedia: Flow<List<MediaCommonModel>> =
+        mediaFilterRepository.sortedMedia.map { it.values.toList() }
+
     override fun start() {
         if (!mediaFlags.isMediaControlsRefactorEnabled()) {
             return
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt
new file mode 100644
index 0000000..83e2765
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.shared.model
+
+import com.android.internal.logging.InstanceId
+
+/** Models any type of media. */
+sealed class MediaCommonModel {
+    data class MediaControl(val instanceId: InstanceId) : MediaCommonModel()
+
+    data class MediaRecommendations(val key: String) : MediaCommonModel()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index 1a56a9b..bd3893b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -738,8 +738,11 @@
                                     mPackageName, mMediaViewHolder.getSeamlessButton());
                         } else {
                             mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
-                            mMediaOutputDialogManager.createAndShow(mPackageName, true,
-                                    mMediaViewHolder.getSeamlessButton());
+                            // TODO: b/321969740 - Populate the userHandle parameter. The user
+                            // handle is necessary to disambiguate the same package running on
+                            // different users.
+                            mMediaOutputDialogManager.createAndShow(
+                                    mPackageName, true, mMediaViewHolder.getSeamlessButton(), null);
                         }
                     } else {
                         mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
@@ -767,8 +770,11 @@
                                 Log.w(TAG, "Device pending intent is not an activity.");
                             }
                         } else {
-                            mMediaOutputDialogManager.createAndShow(mPackageName, true,
-                                    mMediaViewHolder.getSeamlessButton());
+                            // TODO: b/321969740 - Populate the userHandle parameter. The user
+                            // handle is necessary to disambiguate the same package running on
+                            // different users.
+                            mMediaOutputDialogManager.createAndShow(
+                                    mPackageName, true, mMediaViewHolder.getSeamlessButton(), null);
                         }
                     }
                 });
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/LocalMediaManagerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/LocalMediaManagerFactory.kt
index 452cb7e..ff8e903b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/LocalMediaManagerFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/LocalMediaManagerFactory.kt
@@ -31,8 +31,9 @@
 ) {
     /** Creates a [LocalMediaManager] for the given package. */
     fun create(packageName: String?): LocalMediaManager {
-        return InfoMediaManager.createInstance(context, packageName, localBluetoothManager).run {
-            LocalMediaManager(context, localBluetoothManager, this, packageName)
-        }
+        // TODO: b/321969740 - Populate the userHandle parameter in InfoMediaManager. The user
+        // handle is necessary to disambiguate the same package running on different users.
+        return InfoMediaManager.createInstance(context, packageName, null, localBluetoothManager)
+            .run { LocalMediaManager(context, localBluetoothManager, this, packageName) }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index d4bd6da..4e77d13 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -21,16 +21,11 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import javax.inject.Inject
 
 @SysUISingleton
-class MediaFlags
-@Inject
-constructor(
-    private val featureFlags: FeatureFlagsClassic,
-    private val sceneContainerFlags: SceneContainerFlags
-) {
+class MediaFlags @Inject constructor(private val featureFlags: FeatureFlagsClassic) {
     /**
      * Check whether media control actions should be based on PlaybackState instead of notification
      */
@@ -57,7 +52,7 @@
 
     /** Check whether to use scene framework */
     fun isSceneContainerEnabled() =
-        sceneContainerFlags.isEnabled() && MediaInSceneContainerFlag.isEnabled
+        SceneContainerFlag.isEnabled && MediaInSceneContainerFlag.isEnabled
 
     /** Check whether to use media refactor code */
     fun isMediaControlsRefactorEnabled() = MediaControlsRefactorFlag.isEnabled
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogManager.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogManager.kt
index 54d175c..06267e2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogManager.kt
@@ -38,7 +38,9 @@
         // Dismiss the previous dialog, if any.
         mediaOutputBroadcastDialog?.dismiss()
 
-        val controller = mediaOutputControllerFactory.create(packageName)
+        // TODO: b/321969740 - Populate the userHandle parameter. The user handle is necessary to
+        //  disambiguate the same package running on different users.
+        val controller = mediaOutputControllerFactory.create(packageName, /* userHandle= */ null)
         val dialog =
             MediaOutputBroadcastDialog(context, aboveStatusBar, broadcastSender, controller)
         mediaOutputBroadcastDialog = dialog
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 4db89d1..d6ca320 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -124,6 +124,7 @@
     private static final String ALLOWLIST_REASON = "mediaoutput:remote_transfer";
 
     private final String mPackageName;
+    private final UserHandle mUserHandle;
     private final Context mContext;
     private final MediaSessionManager mMediaSessionManager;
     private final LocalBluetoothManager mLocalBluetoothManager;
@@ -177,6 +178,7 @@
     public MediaOutputController(
             Context context,
             @Assisted String packageName,
+            @Assisted @Nullable UserHandle userHandle,
             MediaSessionManager mediaSessionManager,
             @Nullable LocalBluetoothManager lbm,
             ActivityStarter starter,
@@ -190,6 +192,7 @@
             UserTracker userTracker) {
         mContext = context;
         mPackageName = packageName;
+        mUserHandle = userHandle;
         mMediaSessionManager = mediaSessionManager;
         mLocalBluetoothManager = lbm;
         mActivityStarter = starter;
@@ -199,7 +202,8 @@
         mKeyGuardManager = keyGuardManager;
         mFeatureFlags = featureFlags;
         mUserTracker = userTracker;
-        InfoMediaManager imm = InfoMediaManager.createInstance(mContext, packageName, lbm);
+        InfoMediaManager imm =
+                InfoMediaManager.createInstance(mContext, packageName, userHandle, lbm);
         mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
         mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
         mDialogTransitionAnimator = dialogTransitionAnimator;
@@ -231,7 +235,7 @@
     @AssistedFactory
     public interface Factory {
         /** Construct a MediaOutputController */
-        MediaOutputController create(String packageName);
+        MediaOutputController create(String packageName, UserHandle userHandle);
     }
 
     protected void start(@NonNull Callback cb) {
@@ -946,11 +950,22 @@
     }
 
     void launchMediaOutputBroadcastDialog(View mediaOutputDialog, BroadcastSender broadcastSender) {
-        MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
-                mMediaSessionManager, mLocalBluetoothManager, mActivityStarter,
-                mNotifCollection, mDialogTransitionAnimator, mNearbyMediaDevicesManager,
-                mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags,
-                mUserTracker);
+        MediaOutputController controller =
+                new MediaOutputController(
+                        mContext,
+                        mPackageName,
+                        mUserHandle,
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mActivityStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyGuardManager,
+                        mFeatureFlags,
+                        mUserTracker);
         MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true,
                 broadcastSender, controller);
         dialog.show();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
index e7816a4..04d1492 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.dialog
 
 import android.content.Context
+import android.os.UserHandle
 import android.view.View
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
@@ -41,7 +42,15 @@
     }
 
     /** Creates a [MediaOutputDialog] for the given package. */
-    open fun createAndShow(packageName: String, aboveStatusBar: Boolean, view: View? = null) {
+    // TODO: b/321969740 - Make the userHandle non-optional, and place the parameter next to the
+    // package name. The user handle is necessary to disambiguate the same package running on
+    // different users.
+    open fun createAndShow(
+        packageName: String,
+        aboveStatusBar: Boolean,
+        view: View? = null,
+        userHandle: UserHandle? = null
+    ) {
         createAndShowWithController(
             packageName,
             aboveStatusBar,
@@ -55,20 +64,26 @@
                         )
                     )
                 },
+            userHandle = userHandle,
         )
     }
 
     /** Creates a [MediaOutputDialog] for the given package. */
+    // TODO: b/321969740 - Make the userHandle non-optional, and place the parameter next to the
+    // package name. The user handle is necessary to disambiguate the same package running on
+    // different users.
     open fun createAndShowWithController(
         packageName: String,
         aboveStatusBar: Boolean,
         controller: DialogTransitionAnimator.Controller?,
+        userHandle: UserHandle? = null,
     ) {
         createAndShow(
             packageName,
             aboveStatusBar,
             dialogTransitionAnimatorController = controller,
-            includePlaybackAndAppMetadata = true
+            includePlaybackAndAppMetadata = true,
+            userHandle = userHandle,
         )
     }
 
@@ -79,20 +94,25 @@
             packageName = null,
             aboveStatusBar = false,
             dialogTransitionAnimatorController = null,
-            includePlaybackAndAppMetadata = false
+            includePlaybackAndAppMetadata = false,
+            userHandle = null,
         )
     }
 
+    // TODO: b/321969740 - Make the userHandle non-optional, and place the parameter next to the
+    // package name. The user handle is necessary to disambiguate the same package running on
+    // different users.
     private fun createAndShow(
         packageName: String?,
         aboveStatusBar: Boolean,
         dialogTransitionAnimatorController: DialogTransitionAnimator.Controller?,
-        includePlaybackAndAppMetadata: Boolean = true
+        includePlaybackAndAppMetadata: Boolean = true,
+        userHandle: UserHandle? = null,
     ) {
         // Dismiss the previous dialog, if any.
         mediaOutputDialog?.dismiss()
 
-        val controller = mediaOutputControllerFactory.create(packageName)
+        val controller = mediaOutputControllerFactory.create(packageName, userHandle)
 
         val mediaOutputDialog =
             MediaOutputDialog(
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
index da85234..9cc2888 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
@@ -55,8 +55,8 @@
     @MainThread
     public void showMediaOutputSwitcher(String packageName, UserHandle userHandle) {
         if (!TextUtils.isEmpty(packageName)) {
-            // TODO: b/279555229 - Pass the userHandle into the output dialog manager.
-            mMediaOutputDialogManager.createAndShow(packageName, false, null);
+            mMediaOutputDialogManager.createAndShow(
+                    packageName, /* aboveStatusBar= */ false, /* view= */ null, userHandle);
         } else {
             Log.e(TAG, "Unable to launch media output dialog. Package name is empty.");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RemoteRecentSplitTaskTransitionRunner.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RemoteRecentSplitTaskTransitionRunner.kt
index 9514c4a..b7942f7 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RemoteRecentSplitTaskTransitionRunner.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RemoteRecentSplitTaskTransitionRunner.kt
@@ -27,8 +27,8 @@
 import android.util.Log
 import android.view.SurfaceControl
 import android.view.animation.DecelerateInterpolator
-import android.window.IRemoteTransition
 import android.window.IRemoteTransitionFinishedCallback
+import android.window.RemoteTransitionStub
 import android.window.TransitionInfo
 import android.window.WindowContainerToken
 import com.android.app.viewcapture.ViewCapture
@@ -41,7 +41,7 @@
     private val viewPosition: IntArray,
     private val screenBounds: Rect,
     private val handleResult: () -> Unit,
-) : IRemoteTransition.Stub() {
+) : RemoteTransitionStub() {
     override fun startAnimation(
         transition: IBinder?,
         info: TransitionInfo?,
@@ -114,14 +114,6 @@
         }
     }
 
-    override fun mergeAnimation(
-        transition: IBinder?,
-        info: TransitionInfo?,
-        t: SurfaceControl.Transaction?,
-        mergeTarget: IBinder?,
-        finishedCallback: IRemoteTransitionFinishedCallback?
-    ) {}
-
     @Throws(RemoteException::class)
     override fun onTransitionConsumed(transition: IBinder, aborted: Boolean) {
         Log.w(TAG, "unexpected consumption of app selector transition: aborted=$aborted")
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 63989ef..a6b6d61 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -35,6 +35,7 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.inputmethodservice.InputMethodService;
 import android.net.Uri;
@@ -74,6 +75,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import dagger.Lazy;
@@ -101,7 +103,7 @@
         AccessibilityButtonModeObserver.ModeChangedListener,
         AccessibilityButtonTargetsObserver.TargetsChangedListener,
         OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
-        Dumpable, CommandQueue.Callbacks {
+        Dumpable, CommandQueue.Callbacks, ConfigurationController.ConfigurationListener {
     private static final String TAG = NavBarHelper.class.getSimpleName();
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -189,6 +191,7 @@
             UserTracker userTracker,
             DisplayTracker displayTracker,
             NotificationShadeWindowController notificationShadeWindowController,
+            ConfigurationController configurationController,
             DumpManager dumpManager,
             CommandQueue commandQueue,
             @Main Executor mainExecutor) {
@@ -215,6 +218,7 @@
 
         mNavBarMode = navigationModeController.addListener(this);
         mCommandQueue.addCallback(this);
+        configurationController.addCallback(this);
         overviewProxyService.addCallback(this);
         dumpManager.registerDumpable(this);
     }
@@ -359,6 +363,11 @@
         updateA11yState();
     }
 
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        mEdgeBackGestureHandler.onConfigurationChanged(newConfig);
+    }
+
     /**
      * Updates the current accessibility button state. The accessibility button state is only
      * used for {@link Secure#ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR} and
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index ade56c4..b609864 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -902,11 +902,6 @@
             refreshLayout(ld);
         }
         repositionNavigationBar(rotation);
-        // NOTE(b/260220098): In some cases, the recreated nav bar will already have the right
-        // configuration, which means that NavBarView will not receive a configuration change to
-        // propagate to EdgeBackGestureHandler (which is injected into this and NBV). As such, we
-        // should also force-update the gesture handler to ensure it updates to the right bounds
-        mEdgeBackGestureHandler.onConfigurationChanged(newConfig);
         if (canShowSecondaryHandle()) {
             if (rotation != mCurrentRotation) {
                 mCurrentRotation = rotation;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index 9f7d1b3..12f27038 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -162,14 +162,11 @@
         mIsLargeScreen = isLargeScreen(mContext);
         boolean willApplyConfig = mConfigChanges.applyNewConfig(mContext.getResources());
         boolean largeScreenChanged = mIsLargeScreen != isOldConfigLargeScreen;
-        // TODO(b/243765256): Disable this logging once b/243765256 is fixed.
+        // TODO(b/332635834): Disable this logging once b/332635834 is fixed.
         Log.i(DEBUG_MISSING_GESTURE_TAG, "NavbarController: newConfig=" + newConfig
                 + " mTaskbarDelegate initialized=" + mTaskbarDelegate.isInitialized()
                 + " willApplyConfigToNavbars=" + willApplyConfig
                 + " navBarCount=" + mNavigationBars.size());
-        if (mTaskbarDelegate.isInitialized()) {
-            mTaskbarDelegate.onConfigurationChanged(newConfig);
-        }
         // If we folded/unfolded while in 3 button, show navbar in folded state, hide in unfolded
         if (largeScreenChanged && updateNavbarForTaskbar()) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 1927f49..3c69ed9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -1031,7 +1031,6 @@
         updateIcons(mTmpLastConfiguration);
         updateRecentsIcon();
         updateCurrentRotation();
-        mEdgeBackGestureHandler.onConfigurationChanged(mConfiguration);
         if (uiCarModeChanged || mTmpLastConfiguration.densityDpi != mConfiguration.densityDpi
                 || mTmpLastConfiguration.getLayoutDirection() != mConfiguration.getLayoutDirection()) {
             // If car mode or density changes, we need to reset the icons.
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 5dd1bd8..f67973b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -39,7 +39,6 @@
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
@@ -72,7 +71,6 @@
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -250,8 +248,6 @@
             mLightBarController.setNavigationBar(mLightBarTransitionsController);
             mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener);
             mEdgeBackGestureHandler.setBackAnimation(mBackAnimation);
-            mEdgeBackGestureHandler.onConfigurationChanged(
-                    mContext.getResources().getConfiguration());
             mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
             mInitialized = true;
         } finally {
@@ -495,10 +491,6 @@
         return mBehavior != BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
     }
 
-    public void onConfigurationChanged(Configuration configuration) {
-        mEdgeBackGestureHandler.onConfigurationChanged(configuration);
-    }
-
     @Override
     public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
         mOverviewProxyService.onNavigationBarLumaSamplingEnabled(displayId, enable);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 9d0ea5e..db4a7fa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -1187,7 +1187,7 @@
             updateDisabledForQuickstep(newConfig);
         }
 
-        // TODO(b/243765256): Disable this logging once b/243765256 is fixed.
+        // TODO(b/332635834): Disable this logging once b/332635834 is fixed.
         Log.i(DEBUG_MISSING_GESTURE_TAG, "Config changed: newConfig=" + newConfig
                 + " lastReportedConfig=" + mLastReportedConfig);
         mLastReportedConfig.updateFrom(newConfig);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index ffbc560..7ccdf0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -24,7 +24,7 @@
 
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.ViewController;
 
@@ -66,15 +66,14 @@
             QSPanelController qsPanelController,
             QuickStatusBarHeaderController quickStatusBarHeaderController,
             ConfigurationController configurationController,
-            FalsingManager falsingManager,
-            SceneContainerFlags sceneContainerFlags) {
+            FalsingManager falsingManager) {
         super(view);
         mQsPanelController = qsPanelController;
         mQuickStatusBarHeaderController = quickStatusBarHeaderController;
         mConfigurationController = configurationController;
         mFalsingManager = falsingManager;
         mQSPanelContainer = mView.getQSPanelContainer();
-        mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+        mSceneContainerEnabled = SceneContainerFlag.isEnabled();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index a0607e9..1f4838e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -60,7 +60,7 @@
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.settings.brightness.MirrorController;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.CommandQueue;
@@ -174,8 +174,6 @@
     @Nullable
     private View mFooterActionsView;
 
-    private final SceneContainerFlags mSceneContainerFlags;
-
     @Inject
     public QSImpl(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
             SysuiStatusBarStateController statusBarStateController, CommandQueue commandQueue,
@@ -188,8 +186,7 @@
             FooterActionsViewModel.Factory footerActionsViewModelFactory,
             FooterActionsViewBinder footerActionsViewBinder,
             LargeScreenShadeInterpolator largeScreenShadeInterpolator,
-            FeatureFlags featureFlags,
-            SceneContainerFlags sceneContainerFlags) {
+            FeatureFlags featureFlags) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mQsMediaHost = qsMediaHost;
         mQqsMediaHost = qqsMediaHost;
@@ -205,8 +202,7 @@
         mFooterActionsViewModelFactory = footerActionsViewModelFactory;
         mFooterActionsViewBinder = footerActionsViewBinder;
         mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
-        mSceneContainerFlags = sceneContainerFlags;
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             mStatusBarState = StatusBarState.SHADE;
         }
     }
@@ -224,7 +220,7 @@
         mQSPanelController.init();
         mQuickQSPanelController.init();
 
-        if (!mSceneContainerFlags.isEnabled()) {
+        if (!SceneContainerFlag.isEnabled()) {
             mQSFooterActionsViewModel = mFooterActionsViewModelFactory
                     .create(mListeningAndVisibilityLifecycleOwner);
             bindFooterActionsView(mRootView);
@@ -249,7 +245,7 @@
                         mScrollListener.onQsPanelScrollChanged(scrollY);
                     }
                 });
-        mQSPanelScrollView.setScrollingEnabled(!mSceneContainerFlags.isEnabled());
+        mQSPanelScrollView.setScrollingEnabled(!SceneContainerFlag.isEnabled());
         mHeader = mRootView.findViewById(R.id.header);
         mFooter = qsComponent.getQSFooter();
 
@@ -509,7 +505,7 @@
 
     @VisibleForTesting
     boolean isKeyguardState() {
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             return false;
         } else {
             // We want the freshest state here since otherwise we'll have some weirdness if earlier
@@ -573,7 +569,7 @@
     }
 
     private void setKeyguardShowing(boolean keyguardShowing) {
-        if (!mSceneContainerFlags.isEnabled()) {
+        if (!SceneContainerFlag.isEnabled()) {
             if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
             mLastQSExpansion = -1;
 
@@ -651,7 +647,7 @@
 
     @Override
     public int getHeightDiff() {
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             return mQSPanelController.getViewBottom() - mHeader.getBottom()
                     + mHeader.getPaddingBottom();
         } else {
@@ -720,7 +716,7 @@
         mQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
         mQuickQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
 
-        if (!mSceneContainerFlags.isEnabled()) {
+        if (!SceneContainerFlag.isEnabled()) {
             float qsScrollViewTranslation =
                     onKeyguard && !mShowCollapsedOnKeyguard ? panelTranslationY : 0;
             mQSPanelScrollView.setTranslationY(qsScrollViewTranslation);
@@ -824,7 +820,7 @@
             mQsBounds.set(-sideMargin, 0, mQSPanelScrollView.getWidth() + sideMargin,
                     mQSPanelScrollView.getHeight());
         }
-        if (!mSceneContainerFlags.isEnabled()) {
+        if (!SceneContainerFlag.isEnabled()) {
             mQSPanelScrollView.setClipBounds(mQsBounds);
 
             mQSPanelScrollView.getLocationOnScreen(mLocationTemp);
@@ -907,7 +903,7 @@
         // The customize state changed, so our height changed.
         mContainer.updateExpansion();
         boolean customizing = isCustomizing();
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             mQSPanelController.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
         } else {
             mQSPanelScrollView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
@@ -984,7 +980,7 @@
 
     @Override
     public void onStateChanged(int newState) {
-        if (mSceneContainerFlags.isEnabled() || newState == mStatusBarState) {
+        if (SceneContainerFlag.isEnabled() || newState == mStatusBarState) {
             return;
         }
         mStatusBarState = newState;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index b8c3c1a..e24caf1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -37,7 +37,7 @@
 import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.settings.brightness.BrightnessController;
 import com.android.systemui.settings.brightness.BrightnessMirrorHandler;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
@@ -94,7 +94,6 @@
             FalsingManager falsingManager,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             SplitShadeStateController splitShadeStateController,
-            SceneContainerFlags sceneContainerFlags,
             Provider<QSLongPressEffect> longPRessEffectProvider) {
         super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
                 metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
@@ -113,7 +112,7 @@
         mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mLastDensity = view.getResources().getConfiguration().densityDpi;
-        mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+        mSceneContainerEnabled = SceneContainerFlag.isEnabled();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 1d92d78..bb40d3e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -17,7 +17,7 @@
 package com.android.systemui.qs;
 
 import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
@@ -34,12 +34,11 @@
 
     @Inject
     QuickStatusBarHeaderController(QuickStatusBarHeader view,
-            QuickQSPanelController quickQSPanelController,
-            SceneContainerFlags sceneContainerFlags
+            QuickQSPanelController quickQSPanelController
     ) {
         super(view);
         mQuickQSPanelController = quickQSPanelController;
-        mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+        mSceneContainerEnabled = SceneContainerFlag.isEnabled();
     }
     @Override
     protected void onViewAttached() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
index 34b1b2d..a222b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
@@ -42,7 +42,7 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -107,8 +107,7 @@
     protected QSCustomizerController(QSCustomizer view, TileQueryHelper tileQueryHelper,
             QSHost qsHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle,
             KeyguardStateController keyguardStateController, LightBarController lightBarController,
-            ConfigurationController configurationController, UiEventLogger uiEventLogger,
-            SceneContainerFlags sceneContainerFlags) {
+            ConfigurationController configurationController, UiEventLogger uiEventLogger) {
         super(view);
         mTileQueryHelper = tileQueryHelper;
         mQsHost = qsHost;
@@ -118,7 +117,7 @@
         mLightBarController = lightBarController;
         mConfigurationController = configurationController;
         mUiEventLogger = uiEventLogger;
-        view.setSceneContainerEnabled(sceneContainerFlags.isEnabled());
+        view.setSceneContainerEnabled(SceneContainerFlag.isEnabled());
 
         mToolbar = mView.findViewById(com.android.internal.R.id.action_bar);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 4ece7b6..1ddc094 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -98,7 +98,7 @@
 import com.android.systemui.navigationbar.buttons.KeyButtonView;
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
@@ -146,7 +146,6 @@
     private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
 
     private final Context mContext;
-    private final SceneContainerFlags mSceneContainerFlags;
     private final Executor mMainExecutor;
     private final ShellInterface mShellInterface;
     private final Lazy<ShadeViewController> mShadeViewControllerLazy;
@@ -208,7 +207,7 @@
         @Override
         public void onStatusBarTouchEvent(MotionEvent event) {
             verifyCallerAndClearCallingIdentity("onStatusBarTouchEvent", () -> {
-                if (mSceneContainerFlags.isEnabled()) {
+                if (SceneContainerFlag.isEnabled()) {
                     //TODO(b/329863123) implement latency tracking for shade scene
                     Log.i(TAG_OPS, "Scene container enabled. Latency tracking not started.");
                 } else if (event.getActionMasked() == ACTION_DOWN) {
@@ -223,7 +222,7 @@
 
                         // If scene framework is enabled, set the scene container window to
                         // visible and let the touch "slip" into that window.
-                        if (mSceneContainerFlags.isEnabled()) {
+                        if (SceneContainerFlag.isEnabled()) {
                             mSceneInteractor.get().onRemoteUserInteractionStarted("launcher swipe");
                         } else {
                             mShadeViewControllerLazy.get().startInputFocusTransfer();
@@ -232,7 +231,7 @@
                     if (action == ACTION_UP || action == ACTION_CANCEL) {
                         mInputFocusTransferStarted = false;
 
-                        if (!mSceneContainerFlags.isEnabled()) {
+                        if (!SceneContainerFlag.isEnabled()) {
                             float velocity = (event.getY() - mInputFocusTransferStartY)
                                     / (event.getEventTime() - mInputFocusTransferStartMillis);
                             if (action == ACTION_CANCEL) {
@@ -612,7 +611,6 @@
             KeyguardUnlockAnimationController sysuiUnlockAnimationController,
             InWindowLauncherUnlockAnimationManager inWindowLauncherUnlockAnimationManager,
             AssistUtils assistUtils,
-            SceneContainerFlags sceneContainerFlags,
             DumpManager dumpManager,
             Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
             BroadcastDispatcher broadcastDispatcher
@@ -624,7 +622,6 @@
         }
 
         mContext = context;
-        mSceneContainerFlags = sceneContainerFlags;
         mMainExecutor = mainExecutor;
         mShellInterface = shellInterface;
         mShadeViewControllerLazy = shadeViewControllerLazy;
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index afd0746..8277c73 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.scene
 
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import dagger.Module
@@ -29,7 +28,6 @@
             EmptySceneModule::class,
             GoneSceneModule::class,
             QuickSettingsSceneModule::class,
-            SceneContainerFlagsModule::class,
             ShadeSceneModule::class,
         ],
 )
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 62b0914..69f9443 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -20,7 +20,6 @@
 import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlagsModule
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.startable.SceneContainerStartable
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import dagger.Binds
@@ -40,7 +39,6 @@
             GoneSceneModule::class,
             LockscreenSceneModule::class,
             QuickSettingsSceneModule::class,
-            SceneContainerFlagsModule::class,
             ShadeSceneModule::class,
         ],
 )
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index 0665c9e..d202c24 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.scene
 
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import dagger.Module
@@ -30,7 +29,6 @@
             EmptySceneModule::class,
             GoneSceneModule::class,
             LockscreenSceneModule::class,
-            SceneContainerFlagsModule::class,
         ],
 )
 object ShadelessSceneContainerFrameworkModule {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
index c736707..1cf1c18 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.NotificationPresenter
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -53,7 +53,6 @@
     private val headsUpManager: HeadsUpManager,
     private val powerInteractor: PowerInteractor,
     private val activeNotificationsInteractor: ActiveNotificationsInteractor,
-    sceneContainerFlags: SceneContainerFlags,
     sceneInteractorProvider: Provider<SceneInteractor>,
 ) : CoreStartable {
 
@@ -68,7 +67,7 @@
      * false if the bouncer is visible.
      */
     val isLockscreenOrShadeVisible: StateFlow<Boolean> =
-        if (!sceneContainerFlags.isEnabled()) {
+        if (!SceneContainerFlag.isEnabled) {
             windowRootViewVisibilityRepository.isLockscreenOrShadeVisible
         } else {
             sceneInteractorProvider
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 0e66c28..4774eb3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -44,7 +44,7 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.logger.SceneLogger
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -92,7 +92,6 @@
     private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val bouncerInteractor: BouncerInteractor,
     private val keyguardInteractor: KeyguardInteractor,
-    private val flags: SceneContainerFlags,
     private val sysUiState: SysUiState,
     @DisplayId private val displayId: Int,
     private val sceneLogger: SceneLogger,
@@ -111,7 +110,7 @@
 ) : CoreStartable {
 
     override fun start() {
-        if (flags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             sceneLogger.logFrameworkEnabled(isEnabled = true)
             hydrateVisibility()
             automaticallySwitchScenes()
@@ -124,16 +123,18 @@
         } else {
             sceneLogger.logFrameworkEnabled(
                 isEnabled = false,
-                reason = flags.requirementDescription(),
+                reason = SceneContainerFlag.requirementDescription(),
             )
         }
     }
 
     override fun dump(pw: PrintWriter, args: Array<out String>) =
         pw.asIndenting().run {
-            printSection("SceneContainerFlags") {
-                println("isEnabled", flags.isEnabled())
-                printSection("requirementDescription") { println(flags.requirementDescription()) }
+            printSection("SceneContainerFlag") {
+                println("isEnabled", SceneContainerFlag.isEnabled)
+                printSection("requirementDescription") {
+                    println(SceneContainerFlag.requirementDescription())
+                }
             }
         }
 
@@ -288,7 +289,8 @@
                                 Scenes.Gone to "device was unlocked in Bouncer scene"
                             } else {
                                 val prevScene = previousScene.value
-                                (prevScene ?: Scenes.Gone) to
+                                (prevScene
+                                    ?: Scenes.Gone) to
                                     "device was unlocked in Bouncer scene, from sceneKey=$prevScene"
                             }
                         isOnLockscreen ->
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
rename to packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
index cff11a7..234eda8 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
@@ -20,7 +20,6 @@
 
 import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
 import com.android.systemui.Flags.sceneContainer
-import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.flags.FlagToken
 import com.android.systemui.flags.RefactorFlagUtils
@@ -32,8 +31,6 @@
 import com.android.systemui.media.controls.util.MediaInSceneContainerFlag
 import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
 import com.android.systemui.statusbar.phone.PredictiveBackSysUiFlag
-import dagger.Module
-import dagger.Provides
 
 /** Helper for reading or using the scene container flag state. */
 object SceneContainerFlag {
@@ -99,30 +96,12 @@
      */
     @JvmStatic
     inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, DESCRIPTION)
-}
-
-/**
- * Defines interface for classes that can check whether the scene container framework feature is
- * enabled.
- */
-interface SceneContainerFlags {
-
-    /** Returns `true` if the Scene Container Framework is enabled; `false` otherwise. */
-    fun isEnabled(): Boolean
 
     /** Returns a developer-readable string that describes the current requirement list. */
-    fun requirementDescription(): String
-}
-
-class SceneContainerFlagsImpl : SceneContainerFlags {
-
-    override fun isEnabled(): Boolean {
-        return SceneContainerFlag.isEnabled
-    }
-
-    override fun requirementDescription(): String {
+    @JvmStatic
+    fun requirementDescription(): String {
         return buildString {
-            SceneContainerFlag.getAllRequirements().forEach { requirement ->
+            getAllRequirements().forEach { requirement ->
                 append('\n')
                 append(if (requirement.isEnabled) "    [MET]" else "[NOT MET]")
                 append(" ${requirement.name}")
@@ -130,9 +109,3 @@
         }
     }
 }
-
-@Module
-object SceneContainerFlagsModule {
-
-    @Provides @SysUISingleton fun impl(): SceneContainerFlags = SceneContainerFlagsImpl()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
index 67dc0cc..259a8bf 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -4,7 +4,6 @@
 import android.util.AttributeSet
 import android.view.View
 import android.view.WindowInsets
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.scene.shared.model.Scene
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -31,7 +30,6 @@
         viewModel: SceneContainerViewModel,
         containerConfig: SceneContainerConfig,
         sharedNotificationContainer: SharedNotificationContainer,
-        flags: SceneContainerFlags,
         scenes: Set<Scene>,
         layoutInsetController: LayoutInsetsController,
         sceneDataSourceDelegator: SceneDataSourceDelegator,
@@ -44,7 +42,6 @@
             windowInsets = windowInsets,
             containerConfig = containerConfig,
             sharedNotificationContainer = sharedNotificationContainer,
-            flags = flags,
             scenes = scenes,
             onVisibilityChangedInternal = { isVisible ->
                 super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 809ac2e..2ef9b73 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -39,7 +39,7 @@
 import com.android.systemui.common.ui.compose.windowinsets.ScreenDecorProvider
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scene
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -63,7 +63,6 @@
         windowInsets: StateFlow<WindowInsets?>,
         containerConfig: SceneContainerConfig,
         sharedNotificationContainer: SharedNotificationContainer,
-        flags: SceneContainerFlags,
         scenes: Set<Scene>,
         onVisibilityChangedInternal: (isVisible: Boolean) -> Unit,
         dataSourceDelegator: SceneDataSourceDelegator,
@@ -115,7 +114,7 @@
                     //  the SceneContainerView. This SharedNotificationContainer should contain NSSL
                     //  due to the NotificationStackScrollLayoutSection (legacy) or
                     //  NotificationSection (scene container) moving it there.
-                    if (flags.isEnabled()) {
+                    if (SceneContainerFlag.isEnabled) {
                         (sharedNotificationContainer.parent as? ViewGroup)?.removeView(
                             sharedNotificationContainer
                         )
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index fb32b9f..adcb14a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -59,7 +59,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scene.ui.view.WindowRootViewComponent;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
@@ -117,7 +117,6 @@
     private final AuthController mAuthController;
     private final Lazy<SelectedUserInteractor> mUserInteractor;
     private final Lazy<ShadeInteractor> mShadeInteractorLazy;
-    private final SceneContainerFlags mSceneContainerFlags;
     private final Lazy<CommunalInteractor> mCommunalInteractor;
     private ViewGroup mWindowRootView;
     private LayoutParams mLp;
@@ -166,7 +165,6 @@
             ShadeWindowLogger logger,
             Lazy<SelectedUserInteractor> userInteractor,
             UserTracker userTracker,
-            SceneContainerFlags sceneContainerFlags,
             Lazy<CommunalInteractor> communalInteractor) {
         mContext = context;
         mWindowRootViewComponentFactory = windowRootViewComponentFactory;
@@ -186,7 +184,6 @@
         dumpManager.registerCriticalDumpable("{slow}NotificationShadeWindowControllerImpl", this);
         mAuthController = authController;
         mUserInteractor = userInteractor;
-        mSceneContainerFlags = sceneContainerFlags;
         mCommunalInteractor = communalInteractor;
         mLastKeyguardRotationAllowed = mKeyguardStateController.isKeyguardScreenRotationAllowed();
         mLockScreenDisplayTimeout = context.getResources()
@@ -289,7 +286,7 @@
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         mLp.privateFlags |= PRIVATE_FLAG_OPTIMIZE_MEASURE;
 
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             // This prevents the appearance and disappearance of the software keyboard (also known
             // as the "IME") from scrolling/panning the window to make room for the keyboard.
             //
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 648d4b5..a0c9391 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -19,7 +19,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.qs.QSContainerController
 import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.data.repository.PrivacyChipRepository
 import com.android.systemui.shade.data.repository.PrivacyChipRepositoryImpl
 import com.android.systemui.shade.data.repository.ShadeRepository
@@ -50,11 +50,10 @@
         @Provides
         @SysUISingleton
         fun provideBaseShadeInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeInteractorSceneContainerImpl>,
             sceneContainerOff: Provider<ShadeInteractorLegacyImpl>
         ): BaseShadeInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -64,11 +63,10 @@
         @Provides
         @SysUISingleton
         fun provideShadeController(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeControllerSceneImpl>,
             sceneContainerOff: Provider<ShadeControllerImpl>
         ): ShadeController {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -78,11 +76,10 @@
         @Provides
         @SysUISingleton
         fun provideShadeAnimationInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeAnimationInteractorSceneContainerImpl>,
             sceneContainerOff: Provider<ShadeAnimationInteractorLegacyImpl>
         ): ShadeAnimationInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -92,11 +89,10 @@
         @Provides
         @SysUISingleton
         fun provideShadeBackActionInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeBackActionInteractorImpl>,
             sceneContainerOff: Provider<NotificationPanelViewController>
         ): ShadeBackActionInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -106,11 +102,10 @@
         @Provides
         @SysUISingleton
         fun provideShadeLockscreenInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeLockscreenInteractorImpl>,
             sceneContainerOff: Provider<NotificationPanelViewController>
         ): ShadeLockscreenInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -120,11 +115,10 @@
         @Provides
         @SysUISingleton
         fun providePanelExpansionInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<PanelExpansionInteractorImpl>,
             sceneContainerOff: Provider<NotificationPanelViewController>
         ): PanelExpansionInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
@@ -134,11 +128,10 @@
         @Provides
         @SysUISingleton
         fun provideQuickSettingsController(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<QuickSettingsControllerSceneImpl>,
             sceneContainerOff: Provider<QuickSettingsControllerImpl>,
         ): QuickSettingsController {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index f5dd5e4..bc23778 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -33,7 +33,7 @@
 import com.android.systemui.keyguard.ui.view.KeyguardRootView
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scene
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -78,15 +78,13 @@
         @SysUISingleton
         fun providesWindowRootView(
             layoutInflater: LayoutInflater,
-            sceneContainerFlags: SceneContainerFlags,
             viewModelProvider: Provider<SceneContainerViewModel>,
             containerConfigProvider: Provider<SceneContainerConfig>,
-            flagsProvider: Provider<SceneContainerFlags>,
             scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
             layoutInsetController: NotificationInsetsController,
             sceneDataSourceDelegator: Provider<SceneDataSourceDelegator>,
         ): WindowRootView {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 checkNoSceneDuplicates(scenesProvider.get())
                 val sceneWindowRootView =
                     layoutInflater.inflate(R.layout.scene_window_root, null) as SceneWindowRootView
@@ -95,7 +93,6 @@
                     containerConfig = containerConfigProvider.get(),
                     sharedNotificationContainer =
                         sceneWindowRootView.requireViewById(R.id.shared_notification_container),
-                    flags = flagsProvider.get(),
                     scenes = scenesProvider.get(),
                     layoutInsetController = layoutInsetController,
                     sceneDataSourceDelegator = sceneDataSourceDelegator.get(),
@@ -115,9 +112,8 @@
         @SysUISingleton
         fun providesNotificationShadeWindowView(
             root: WindowRootView,
-            sceneContainerFlags: SceneContainerFlags,
         ): NotificationShadeWindowView {
-            if (sceneContainerFlags.isEnabled()) {
+            if (SceneContainerFlag.isEnabled) {
                 return root.requireViewById(R.id.legacy_window_root)
             }
             return root as NotificationShadeWindowView?
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index e5b6497..594c191 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -35,7 +35,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeSurface;
@@ -61,8 +61,6 @@
 import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
-import javax.inject.Provider;
-
 import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
@@ -70,6 +68,8 @@
 import dagger.multibindings.ClassKey;
 import dagger.multibindings.IntoMap;
 
+import javax.inject.Provider;
+
 /**
  * This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
  * this separate from {@link CentralSurfacesModule} module so that components that wish to build
@@ -185,10 +185,9 @@
     @Provides
     @SysUISingleton
     static ShadeSurface provideShadeSurface(
-            SceneContainerFlags sceneContainerFlags,
             Provider<ShadeSurfaceImpl> sceneContainerOn,
             Provider<NotificationPanelViewController> sceneContainerOff) {
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             return sceneContainerOn.get();
         } else {
             return sceneContainerOff.get();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 741102b..cf5366b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
@@ -49,7 +48,6 @@
 class SharedNotificationContainerBinder
 @Inject
 constructor(
-    private val sceneContainerFlags: SceneContainerFlags,
     private val controller: NotificationStackScrollLayoutController,
     private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
     private val notificationScrollViewBinder: NotificationScrollViewBinder,
@@ -130,7 +128,7 @@
                             .collect { controller.setMaxDisplayedNotifications(it) }
                     }
 
-                    if (!sceneContainerFlags.isEnabled()) {
+                    if (!SceneContainerFlag.isEnabled) {
                         launch {
                             viewModel.bounds.collect {
                                 val animate =
@@ -166,7 +164,7 @@
                 }
             }
 
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled) {
             disposables += notificationScrollViewBinder.bindWhileAttached()
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index b284179..ca19da5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
@@ -43,7 +43,6 @@
     dumpManager: DumpManager,
     private val interactor: NotificationStackAppearanceInteractor,
     shadeInteractor: ShadeInteractor,
-    flags: SceneContainerFlags,
     featureFlags: FeatureFlagsClassic,
     private val keyguardInteractor: KeyguardInteractor,
 ) : FlowDumperImpl(dumpManager) {
@@ -51,7 +50,7 @@
     val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
 
     /** DEBUG: whether the debug logging should be output. */
-    val isDebugLoggingEnabled: Boolean = flags.isEnabled()
+    val isDebugLoggingEnabled: Boolean = SceneContainerFlag.isEnabled
 
     /** Notifies that the bounds of the notification scrim have changed. */
     fun onScrimBoundsChanged(bounds: ShadeScrimBounds?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 08b65e3..cb3c03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -164,7 +164,6 @@
 import com.android.systemui.res.R;
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
@@ -592,9 +591,6 @@
 
     private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
             (extractor, which) -> updateTheme();
-
-    private final SceneContainerFlags mSceneContainerFlags;
-
     private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor;
 
     /**
@@ -708,7 +704,6 @@
             UserTracker userTracker,
             Provider<FingerprintManager> fingerprintManager,
             ActivityStarter activityStarter,
-            SceneContainerFlags sceneContainerFlags,
             BrightnessMirrorShowingInteractor brightnessMirrorShowingInteractor
     ) {
         mContext = context;
@@ -804,7 +799,6 @@
         mUserTracker = userTracker;
         mFingerprintManager = fingerprintManager;
         mActivityStarter = activityStarter;
-        mSceneContainerFlags = sceneContainerFlags;
         mBrightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor;
 
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -1088,7 +1082,7 @@
         mJavaAdapter.alwaysCollectFlow(
                 mCommunalInteractor.isIdleOnCommunal(),
                 mIdleOnCommunalConsumer);
-        if (mSceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             mJavaAdapter.alwaysCollectFlow(
                     mBrightnessMirrorShowingInteractor.isShowing(),
                     this::setBrightnessMirrorShowing
@@ -1277,7 +1271,7 @@
 
         // Set up the quick settings tile panel
         final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame);
-        if (container != null && !mSceneContainerFlags.isEnabled()) {
+        if (container != null && !SceneContainerFlag.isEnabled()) {
             FragmentHostManager fragmentHostManager =
                     mFragmentService.getFragmentHostManager(container);
             ExtensionFragmentListener.attachExtensonToFragment(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 92fd90a..5206e46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -24,10 +24,10 @@
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeController
 import com.android.systemui.shade.ShadeLogger
@@ -65,7 +65,6 @@
     private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
     private val userChipViewModel: StatusBarUserChipViewModel,
     private val viewUtil: ViewUtil,
-    private val sceneContainerFlags: SceneContainerFlags,
     private val configurationController: ConfigurationController,
     private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
 ) : ViewController<PhoneStatusBarView>(view) {
@@ -205,7 +204,7 @@
 
             // If scene framework is enabled, route the touch to it and
             // ignore the rest of the gesture.
-            if (sceneContainerFlags.isEnabled()) {
+            if (SceneContainerFlag.isEnabled) {
                 windowRootView.get().dispatchTouchEvent(event)
                 return true
             }
@@ -267,7 +266,6 @@
         @Named(UNFOLD_STATUS_BAR)
         private val progressProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
         private val featureFlags: FeatureFlags,
-        private val sceneContainerFlags: SceneContainerFlags,
         private val userChipViewModel: StatusBarUserChipViewModel,
         private val centralSurfaces: CentralSurfaces,
         private val statusBarWindowStateController: StatusBarWindowStateController,
@@ -301,7 +299,6 @@
                 statusBarMoveFromCenterAnimationController,
                 userChipViewModel,
                 viewUtil,
-                sceneContainerFlags,
                 configurationController,
                 statusOverlayHoverListenerFactory,
             )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 8e8de46..d1189e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -37,7 +37,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -91,7 +91,6 @@
             ShadeInteractor shadeInteractor,
             Provider<SceneInteractor> sceneInteractor,
             JavaAdapter javaAdapter,
-            SceneContainerFlags sceneContainerFlags,
             UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
             PrimaryBouncerInteractor primaryBouncerInteractor,
             AlternateBouncerInteractor alternateBouncerInteractor
@@ -130,7 +129,7 @@
 
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
 
-        if (sceneContainerFlags.isEnabled()) {
+        if (SceneContainerFlag.isEnabled()) {
             javaAdapter.alwaysCollectFlow(
                     sceneInteractor.get().isVisible(),
                     this::onSceneContainerVisibilityChanged);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt
index 541ac48..31c2134 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt
@@ -15,36 +15,55 @@
  */
 package com.android.systemui.statusbar.phone
 
+import android.annotation.StyleRes
 import android.app.Dialog
 import android.content.Context
-import android.content.res.Configuration
 import android.graphics.Color
 import android.graphics.drawable.ColorDrawable
 import android.os.Bundle
 import android.view.Gravity
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.view.WindowInsets
-import android.view.WindowInsets.Type.InsetsType
-import android.view.WindowInsetsAnimation
 import android.view.WindowManager.LayoutParams.MATCH_PARENT
 import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
 import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
 import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL
+import androidx.activity.ComponentDialog
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
+import com.android.systemui.statusbar.policy.onConfigChanged
+import dagger.Lazy
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.launch
 
 /** A dialog shown as a bottom sheet. */
-open class SystemUIBottomSheetDialog(
+class SystemUIBottomSheetDialog
+@VisibleForTesting
+constructor(
     context: Context,
-    private val configurationController: ConfigurationController? = null,
-    theme: Int = R.style.Theme_SystemUI_Dialog
-) : Dialog(context, theme) {
+    private val coroutineScope: CoroutineScope,
+    private val configurationController: ConfigurationController,
+    private val delegate: DialogDelegate<in Dialog>,
+    private val windowLayout: WindowLayout,
+    theme: Int,
+) : ComponentDialog(context, theme) {
+
+    private var job: Job? = null
+
     override fun onCreate(savedInstanceState: Bundle?) {
+        delegate.beforeCreate(this, savedInstanceState)
         super.onCreate(savedInstanceState)
         setupWindow()
-        setupEdgeToEdge()
         setCanceledOnTouchOutside(true)
+        delegate.onCreate(this, savedInstanceState)
     }
 
     private fun setupWindow() {
@@ -62,60 +81,84 @@
         }
     }
 
-    private fun setupEdgeToEdge() {
-        val edgeToEdgeHorizontally =
-            context.resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog)
-        val width = if (edgeToEdgeHorizontally) MATCH_PARENT else WRAP_CONTENT
-        val height = WRAP_CONTENT
-        window?.setLayout(width, height)
-    }
-
     override fun onStart() {
         super.onStart()
-        configurationController?.addCallback(onConfigChanged)
-        window?.decorView?.setWindowInsetsAnimationCallback(insetsAnimationCallback)
+        job?.cancel()
+        job =
+            coroutineScope.launch {
+                windowLayout
+                    .calculate()
+                    .onEach { window?.apply { setLayout(it.width, it.height) } }
+                    .launchIn(this)
+                configurationController.onConfigChanged
+                    .onEach { delegate.onConfigurationChanged(this@SystemUIBottomSheetDialog, it) }
+                    .launchIn(this)
+            }
+        delegate.onStart(this)
     }
 
     override fun onStop() {
+        job?.cancel()
+        delegate.onStop(this)
         super.onStop()
-        configurationController?.removeCallback(onConfigChanged)
-        window?.decorView?.setWindowInsetsAnimationCallback(null)
     }
 
-    /** Called after any insets change. */
-    open fun onInsetsChanged(@InsetsType changedTypes: Int, insets: WindowInsets) {}
+    override fun onWindowFocusChanged(hasFocus: Boolean) {
+        super.onWindowFocusChanged(hasFocus)
+        delegate.onWindowFocusChanged(this, hasFocus)
+    }
 
-    /** Can be overridden by subclasses to receive config changed events. */
-    open fun onConfigurationChanged() {}
+    class Factory
+    @Inject
+    constructor(
+        @Application private val context: Context,
+        @Application private val coroutineScope: CoroutineScope,
+        private val defaultWindowLayout: Lazy<WindowLayout.LimitedEdgeToEdge>,
+        private val configurationController: ConfigurationController,
+    ) {
 
-    private val insetsAnimationCallback =
-        object : WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+        fun create(
+            delegate: DialogDelegate<in Dialog>,
+            windowLayout: WindowLayout = defaultWindowLayout.get(),
+            @StyleRes theme: Int = R.style.Theme_SystemUI_Dialog,
+        ): SystemUIBottomSheetDialog =
+            SystemUIBottomSheetDialog(
+                context = context,
+                configurationController = configurationController,
+                coroutineScope = coroutineScope,
+                delegate = delegate,
+                windowLayout = windowLayout,
+                theme = theme,
+            )
+    }
 
-            private var lastInsets: WindowInsets? = null
+    /** [SystemUIBottomSheetDialog] uses this to determine the [android.view.Window] layout. */
+    interface WindowLayout {
 
-            override fun onEnd(animation: WindowInsetsAnimation) {
-                lastInsets?.let { onInsetsChanged(animation.typeMask, it) }
-            }
+        /** Returns a [Layout] to apply to [android.view.Window.setLayout]. */
+        fun calculate(): Flow<Layout>
 
-            override fun onProgress(
-                insets: WindowInsets,
-                animations: MutableList<WindowInsetsAnimation>,
-            ): WindowInsets {
-                lastInsets = insets
-                onInsetsChanged(changedTypes = allAnimationMasks(animations), insets)
-                return insets
-            }
+        /** Edge to edge with which doesn't fill the whole space on the large screen. */
+        class LimitedEdgeToEdge
+        @Inject
+        constructor(
+            @Application private val context: Context,
+            private val configurationController: ConfigurationController,
+        ) : WindowLayout {
 
-            private fun allAnimationMasks(animations: List<WindowInsetsAnimation>): Int =
-                animations.fold(0) { acc: Int, it -> acc or it.typeMask }
-        }
+            override fun calculate(): Flow<Layout> {
+                return configurationController.onConfigChanged
+                    .onStart { emit(context.resources.configuration) }
+                    .map {
+                        val edgeToEdgeHorizontally =
+                            context.resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog)
+                        val width = if (edgeToEdgeHorizontally) MATCH_PARENT else WRAP_CONTENT
 
-    private val onConfigChanged =
-        object : ConfigurationListener {
-            override fun onConfigChanged(newConfig: Configuration?) {
-                super.onConfigChanged(newConfig)
-                setupEdgeToEdge()
-                onConfigurationChanged()
+                        Layout(width, WRAP_CONTENT)
+                    }
             }
         }
+
+        data class Layout(val width: Int, val height: Int)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
index f924ab4..bcea411 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
@@ -36,6 +36,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
 
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
@@ -78,6 +79,7 @@
     protected final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
     protected @Mock DeviceEntryInteractor mDeviceEntryInteractor;
     protected @Mock LockIconView mLockIconView;
+    protected @Mock ImageView mLockIcon;
     protected @Mock AnimatedStateListDrawable mIconDrawable;
     protected @Mock Context mContext;
     protected @Mock Resources mResources;
@@ -146,8 +148,10 @@
         when(mStatusBarStateController.isDozing()).thenReturn(false);
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
 
-        mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR);
-        mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT);
+        if (!Flags.sceneContainer()) {
+            mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR);
+            mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT);
+        }
 
         mFeatureFlags = new FakeFeatureFlags();
         mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
@@ -172,8 +176,7 @@
                 mFeatureFlags,
                 mPrimaryBouncerInteractor,
                 mContext,
-                () -> mDeviceEntryInteractor,
-                mKosmos.getFakeSceneContainerFlags()
+                () -> mDeviceEntryInteractor
         );
     }
 
@@ -225,6 +228,7 @@
     protected void setupLockIconViewMocks() {
         when(mLockIconView.getResources()).thenReturn(mResources);
         when(mLockIconView.getContext()).thenReturn(mContext);
+        when(mLockIconView.getLockIcon()).thenReturn(mLockIcon);
     }
 
     protected void resetLockIconView() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
index 8689842..255c7d9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
@@ -43,6 +43,7 @@
 import com.android.systemui.biometrics.UdfpsController;
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
 import com.android.systemui.doze.util.BurnInHelperKt;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.statusbar.StatusBarState;
 
 import org.junit.Test;
@@ -373,7 +374,6 @@
     @Test
     public void longPress_showBouncer_sceneContainerNotEnabled() {
         init(/* useMigrationFlag= */ false);
-        mKosmos.getFakeSceneContainerFlags().setEnabled(false);
         when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
 
         // WHEN longPress
@@ -385,9 +385,9 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void longPress_showBouncer() {
         init(/* useMigrationFlag= */ false);
-        mKosmos.getFakeSceneContainerFlags().setEnabled(true);
         when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
 
         // WHEN longPress
@@ -399,9 +399,9 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void longPress_falsingTriggered_doesNotShowBouncer() {
         init(/* useMigrationFlag= */ false);
-        mKosmos.getFakeSceneContainerFlags().setEnabled(true);
         when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true);
 
         // WHEN longPress
diff --git a/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
index f490f3c..cbad133 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.QuickSettingsController
 import com.android.systemui.shade.ShadeController
@@ -109,7 +108,6 @@
             headsUpManager,
             powerInteractor,
             activeNotificationsInteractor,
-            kosmos.sceneContainerFlags,
             kosmos::sceneInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index 30c5e6e..d3cc232 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -78,7 +78,6 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.phone.dozeServiceHost
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -239,7 +238,6 @@
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
-                kosmos.fakeSceneContainerFlags,
                 kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 238a76e..415da02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -77,7 +77,6 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.phone.dozeServiceHost
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -236,7 +235,6 @@
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
-                kosmos.fakeSceneContainerFlags,
                 kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt
new file mode 100644
index 0000000..d118cc7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.ui.view
+
+import android.app.Dialog
+import android.graphics.Insets
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.Window
+import android.view.WindowInsets
+import android.view.WindowInsetsAnimation
+import androidx.test.filters.SmallTest
+import com.android.app.animation.Interpolators
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
[email protected](setAsMainLooper = true)
+class MirroringConfirmationDialogDelegateTest : SysuiTestCase() {
+
+    private lateinit var underTest: MirroringConfirmationDialogDelegate
+
+    private val onStartMirroringCallback = mock<View.OnClickListener>()
+    private val onCancelCallback = mock<View.OnClickListener>()
+    private val windowDecorView: View = mock {}
+    private val windowInsetsAnimationCallbackCaptor =
+        ArgumentCaptor.forClass(WindowInsetsAnimation.Callback::class.java)
+    private val dialog: Dialog =
+        mock<Dialog> {
+            var view: View? = null
+            whenever(setContentView(any<Int>())).then {
+                view =
+                    LayoutInflater.from([email protected])
+                        .inflate(it.arguments[0] as Int, null, false)
+                Unit
+            }
+            whenever(requireViewById<View>(any<Int>())).then {
+                view?.requireViewById(it.arguments[0] as Int)
+            }
+            val window: Window = mock { whenever(decorView).thenReturn(windowDecorView) }
+            whenever(this.window).thenReturn(window)
+        }
+
+    @Before
+    fun setUp() {
+        underTest =
+            MirroringConfirmationDialogDelegate(
+                context = context,
+                showConcurrentDisplayInfo = false,
+                onStartMirroringClickListener = onStartMirroringCallback,
+                onCancelMirroring = onCancelCallback,
+                navbarBottomInsetsProvider = { 0 },
+            )
+    }
+
+    @Test
+    fun startMirroringButton_clicked_callsCorrectCallback() {
+        underTest.onCreate(dialog, null)
+
+        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
+
+        verify(onStartMirroringCallback).onClick(any())
+        verify(onCancelCallback, never()).onClick(any())
+    }
+
+    @Test
+    fun cancelButton_clicked_callsCorrectCallback() {
+        underTest.onCreate(dialog, null)
+
+        dialog.requireViewById<View>(R.id.cancel).callOnClick()
+
+        verify(onCancelCallback).onClick(any())
+        verify(onStartMirroringCallback, never()).onClick(any())
+    }
+
+    @Test
+    fun onCancel_afterEnablingMirroring_cancelCallbackNotCalled() {
+        underTest.onCreate(dialog, null)
+        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
+
+        underTest.onStop(dialog)
+
+        verify(onCancelCallback, never()).onClick(any())
+        verify(onStartMirroringCallback).onClick(any())
+    }
+
+    @Test
+    fun onDismiss_afterEnablingMirroring_cancelCallbackNotCalled() {
+        underTest.onCreate(dialog, null)
+        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
+
+        underTest.onStop(dialog)
+
+        verify(onCancelCallback, never()).onClick(any())
+        verify(onStartMirroringCallback).onClick(any())
+    }
+
+    @Test
+    fun onInsetsChanged_navBarInsets_updatesBottomPadding() {
+        underTest.onCreate(dialog, null)
+        underTest.onStart(dialog)
+
+        val insets = buildInsets(WindowInsets.Type.navigationBars(), TEST_BOTTOM_INSETS)
+
+        triggerInsetsChanged(WindowInsets.Type.navigationBars(), insets)
+
+        assertThat(dialog.requireViewById<View>(R.id.cd_bottom_sheet).paddingBottom)
+            .isEqualTo(TEST_BOTTOM_INSETS)
+    }
+
+    @Test
+    fun onInsetsChanged_otherType_doesNotUpdateBottomPadding() {
+        underTest.onCreate(dialog, null)
+        underTest.onStart(dialog)
+
+        val insets = buildInsets(WindowInsets.Type.ime(), TEST_BOTTOM_INSETS)
+        triggerInsetsChanged(WindowInsets.Type.ime(), insets)
+
+        assertThat(dialog.requireViewById<View>(R.id.cd_bottom_sheet).paddingBottom)
+            .isNotEqualTo(TEST_BOTTOM_INSETS)
+    }
+
+    private fun buildInsets(@WindowInsets.Type.InsetsType type: Int, bottom: Int): WindowInsets {
+        return WindowInsets.Builder().setInsets(type, Insets.of(0, 0, 0, bottom)).build()
+    }
+
+    private fun triggerInsetsChanged(type: Int, insets: WindowInsets) {
+        verify(windowDecorView)
+            .setWindowInsetsAnimationCallback(capture(windowInsetsAnimationCallbackCaptor))
+        windowInsetsAnimationCallbackCaptor.value.onProgress(
+            insets,
+            listOf(WindowInsetsAnimation(type, Interpolators.INSTANT, 0))
+        )
+    }
+
+    private companion object {
+        const val TEST_BOTTOM_INSETS = 1000 // arbitrarily high number
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt
deleted file mode 100644
index 30519b0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.display.ui.view
-
-import android.graphics.Insets
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import android.view.View
-import android.view.WindowInsets
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.res.R
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
[email protected](setAsMainLooper = true)
-class MirroringConfirmationDialogTest : SysuiTestCase() {
-
-    private lateinit var dialog: MirroringConfirmationDialog
-
-    private val onStartMirroringCallback = mock<View.OnClickListener>()
-    private val onCancelCallback = mock<View.OnClickListener>()
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        dialog =
-            MirroringConfirmationDialog(
-                context,
-                onStartMirroringCallback,
-                onCancelCallback,
-                navbarBottomInsetsProvider = { 0 },
-            )
-    }
-
-    @Test
-    fun startMirroringButton_clicked_callsCorrectCallback() {
-        dialog.show()
-
-        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
-
-        verify(onStartMirroringCallback).onClick(any())
-        verify(onCancelCallback, never()).onClick(any())
-    }
-
-    @Test
-    fun cancelButton_clicked_callsCorrectCallback() {
-        dialog.show()
-
-        dialog.requireViewById<View>(R.id.cancel).callOnClick()
-
-        verify(onCancelCallback).onClick(any())
-        verify(onStartMirroringCallback, never()).onClick(any())
-    }
-
-    @Test
-    fun onCancel_afterEnablingMirroring_cancelCallbackNotCalled() {
-        dialog.show()
-        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
-
-        dialog.cancel()
-
-        verify(onCancelCallback, never()).onClick(any())
-        verify(onStartMirroringCallback).onClick(any())
-    }
-
-    @Test
-    fun onDismiss_afterEnablingMirroring_cancelCallbackNotCalled() {
-        dialog.show()
-        dialog.requireViewById<View>(R.id.enable_display).callOnClick()
-
-        dialog.dismiss()
-
-        verify(onCancelCallback, never()).onClick(any())
-        verify(onStartMirroringCallback).onClick(any())
-    }
-
-    @Test
-    fun onInsetsChanged_navBarInsets_updatesBottomPadding() {
-        dialog.show()
-
-        val insets = buildInsets(WindowInsets.Type.navigationBars(), TEST_BOTTOM_INSETS)
-        dialog.onInsetsChanged(WindowInsets.Type.navigationBars(), insets)
-
-        assertThat(dialog.requireViewById<View>(R.id.cd_bottom_sheet).paddingBottom)
-            .isEqualTo(TEST_BOTTOM_INSETS)
-    }
-
-    @Test
-    fun onInsetsChanged_otherType_doesNotUpdateBottomPadding() {
-        dialog.show()
-
-        val insets = buildInsets(WindowInsets.Type.ime(), TEST_BOTTOM_INSETS)
-        dialog.onInsetsChanged(WindowInsets.Type.ime(), insets)
-
-        assertThat(dialog.requireViewById<View>(R.id.cd_bottom_sheet).paddingBottom)
-            .isNotEqualTo(TEST_BOTTOM_INSETS)
-    }
-
-    private fun buildInsets(@WindowInsets.Type.InsetsType type: Int, bottom: Int): WindowInsets {
-        return WindowInsets.Builder().setInsets(type, Insets.of(0, 0, 0, bottom)).build()
-    }
-
-    @After
-    fun teardown() {
-        if (::dialog.isInitialized) {
-            dialog.dismiss()
-        }
-    }
-
-    private companion object {
-        const val TEST_BOTTOM_INSETS = 1000 // arbitrarily high number
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index a46f755..709f779 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -25,8 +25,8 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
-import static com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER;
 import static com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR;
+import static com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER;
 import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
 import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT;
 import static com.android.systemui.keyguard.KeyguardViewMediator.REBOOT_MAINLINE_UPDATE;
@@ -102,7 +102,6 @@
 import com.android.systemui.log.SessionTracker;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.scene.FakeWindowRootViewComponent;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
@@ -222,7 +221,6 @@
     private @Mock DreamViewModel mDreamViewModel;
     private @Mock CommunalTransitionViewModel mCommunalTransitionViewModel;
     private @Mock SystemPropertiesHelper mSystemPropertiesHelper;
-    private @Mock SceneContainerFlags mSceneContainerFlags;
 
     private FakeFeatureFlags mFeatureFlags;
     private final int mDefaultUserId = 100;
@@ -270,7 +268,6 @@
                 mShadeWindowLogger,
                 () -> mSelectedUserInteractor,
                 mUserTracker,
-                mSceneContainerFlags,
                 mKosmos::getCommunalInteractor);
         mFeatureFlags = new FakeFeatureFlags();
         mSetFlagsRule.enableFlags(FLAG_REFACTOR_GET_CURRENT_USER);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index b0aace6..b50d248 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.utils.GlobalWindowManager
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -63,8 +62,8 @@
 
         val withDeps =
             KeyguardInteractorFactory.create(
-                repository = keyguardRepository,
                 featureFlags = featureFlags,
+                repository = keyguardRepository,
             )
         val keyguardInteractor = withDeps.keyguardInteractor
         resourceTrimmer =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
index 9266af4..dc7f372 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFingerprintAuthInteractor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
@@ -40,7 +41,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -87,7 +87,6 @@
     @Before
     fun setup() {
         mSetFlagsRule.enableFlags(FLAG_SIDEFPS_CONTROLLER_REFACTOR)
-        kosmos.fakeSceneContainerFlags.enabled = false
 
         primaryBouncerInteractor =
             PrimaryBouncerInteractor(
@@ -127,7 +126,6 @@
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
-                kosmos.fakeSceneContainerFlags,
                 kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
@@ -168,15 +166,14 @@
         }
 
     @Test
+    @EnableSceneContainer
     fun updatesShowIndicatorForDeviceEntry_onBouncerSceneActive() =
         testScope.runTest {
-            kosmos.fakeSceneContainerFlags.enabled = true
             underTest =
                 DeviceEntrySideFpsOverlayInteractor(
                     testScope.backgroundScope,
                     mContext,
                     deviceEntryFingerprintAuthRepository,
-                    kosmos.fakeSceneContainerFlags,
                     kosmos.sceneInteractor,
                     primaryBouncerInteractor,
                     alternateBouncerInteractor,
@@ -196,15 +193,14 @@
         }
 
     @Test
+    @EnableSceneContainer
     fun updatesShowIndicatorForDeviceEntry_onBouncerSceneInactive() =
         testScope.runTest {
-            kosmos.fakeSceneContainerFlags.enabled = true
             underTest =
                 DeviceEntrySideFpsOverlayInteractor(
                     testScope.backgroundScope,
                     mContext,
                     deviceEntryFingerprintAuthRepository,
-                    kosmos.fakeSceneContainerFlags,
                     kosmos.sceneInteractor,
                     primaryBouncerInteractor,
                     alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index fe8fdc0..4d20f55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -101,7 +101,7 @@
         MediaPlayerData.clear()
         whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
         testScope = TestScope()
-        repository = MediaFilterRepository()
+        repository = MediaFilterRepository(FakeSystemClock())
         mediaDataFilter =
             MediaDataFilterImpl(
                 context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
index 5c275b4..ffb50c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
@@ -210,7 +210,7 @@
         )
         testDispatcher = UnconfinedTestDispatcher()
         testScope = TestScope(testDispatcher)
-        mediaFilterRepository = MediaFilterRepository()
+        mediaFilterRepository = MediaFilterRepository(clock)
         mediaDataRepository = MediaDataRepository(mediaFlags, dumpManager)
         mediaDataProcessor =
             MediaDataProcessor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index ca403e0..9bb21f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -123,11 +123,22 @@
         mMediaControllers.add(mMediaController);
         when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
 
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mContext,
+                        TEST_PACKAGE,
+                        mContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         // Using a fake package will cause routing operations to fail, so we intercept
         // scanning-related operations.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
index c9eb67e..2e6388a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
@@ -124,11 +124,22 @@
         when(mLocalBluetoothLeBroadcast.getBroadcastCode()).thenReturn(
                 BROADCAST_CODE_TEST.getBytes(StandardCharsets.UTF_8));
 
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mContext,
+                        TEST_PACKAGE,
+                        mContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputBroadcastDialog = new MediaOutputBroadcastDialog(mContext, false,
                 mBroadcastSender, mMediaOutputController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 980eb59..4eb0038 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -194,11 +194,22 @@
         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
                 mCachedBluetoothDeviceManager);
 
-        mMediaOutputController = new MediaOutputController(mSpyContext, mPackageName,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        mPackageName,
+                        mContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
         mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
         when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
@@ -276,11 +287,22 @@
 
     @Test
     public void start_withoutPackageName_verifyMediaControllerInit() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         mMediaOutputController.start(mCb);
 
@@ -306,11 +328,22 @@
 
     @Test
     public void stop_withoutPackageName_verifyMediaControllerDeinit() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         mMediaOutputController.start(mCb);
 
@@ -550,12 +583,22 @@
 
     @Test
     public void getAppSourceName_packageNameIsNull_returnsNull() {
-        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
-                "",
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        MediaOutputController testMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        "",
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
         testMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -573,12 +616,22 @@
 
     @Test
     public void getNotificationSmallIcon_packageNameIsNull_returnsNull() {
-        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
-                "",
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        MediaOutputController testMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        "",
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
         testMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -609,12 +662,22 @@
 
     @Test
     public void addDeviceToPlayMedia_callsLocalMediaManager() {
-        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
-                null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        MediaOutputController testMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         LocalMediaManager mockLocalMediaManager = mock(LocalMediaManager.class);
         testMediaOutputController.mLocalMediaManager = mockLocalMediaManager;
@@ -625,12 +688,22 @@
 
     @Test
     public void removeDeviceFromPlayMedia_callsLocalMediaManager() {
-        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
-                null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        MediaOutputController testMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         LocalMediaManager mockLocalMediaManager = mock(LocalMediaManager.class);
         testMediaOutputController.mLocalMediaManager = mockLocalMediaManager;
@@ -894,11 +967,22 @@
 
     @Test
     public void getNotificationLargeIcon_withoutPackageName_returnsNull() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         assertThat(mMediaOutputController.getNotificationIcon()).isNull();
     }
@@ -1085,12 +1169,22 @@
 
     @Test
     public void setTemporaryAllowListExceptionIfNeeded_packageNameIsNull_NoAction() {
-        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
-                null,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        MediaOutputController testMediaOutputController =
+                new MediaOutputController(
+                        mSpyContext,
+                        null,
+                        mSpyContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
 
         testMediaOutputController.setTemporaryAllowListExceptionIfNeeded(mMediaDevice2);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
index 83def8e4..3b6a88a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 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.times;
@@ -61,7 +62,7 @@
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
         verify(mMockMediaOutputDialogManager, times(1))
-                .createAndShow(getContext().getPackageName(), false, null);
+                .createAndShow(eq(getContext().getPackageName()), eq(false), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -72,7 +73,8 @@
         intent.putExtra("Wrong Package Name Key", getContext().getPackageName());
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -82,7 +84,8 @@
         Intent intent = new Intent(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -95,7 +98,8 @@
         intent.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, getContext().getPackageName());
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -108,9 +112,10 @@
         intent.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, getContext().getPackageName());
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, times(1))
-                .createAndShow(getContext().getPackageName(), true, null);
+                .createAndShow(eq(getContext().getPackageName()), eq(true), any());
     }
 
     @Test
@@ -121,7 +126,8 @@
         intent.putExtra("Wrong Package Name Key", getContext().getPackageName());
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -133,7 +139,8 @@
                 MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG);
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -145,7 +152,8 @@
         intent.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, getContext().getPackageName());
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
@@ -155,7 +163,8 @@
         Intent intent = new Intent("UnKnown Action");
         mMediaOutputDialogReceiver.onReceive(getContext(), intent);
 
-        verify(mMockMediaOutputDialogManager, never()).createAndShow(any(), anyBoolean(), any());
+        verify(mMockMediaOutputDialogManager, never())
+                .createAndShow(any(), anyBoolean(), any(), any());
         verify(mMockMediaOutputBroadcastDialogManager, never())
                 .createAndShow(any(), anyBoolean(), any());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index 84300da..cdef964 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -137,11 +137,22 @@
                 Mockito.eq(userHandle))).thenReturn(
                 mMediaControllers);
 
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotifCollection, mDialogTransitionAnimator,
-                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags, mUserTracker);
+        mMediaOutputController =
+                new MediaOutputController(
+                        mContext,
+                        TEST_PACKAGE,
+                        mContext.getUser(),
+                        mMediaSessionManager,
+                        mLocalBluetoothManager,
+                        mStarter,
+                        mNotifCollection,
+                        mDialogTransitionAnimator,
+                        mNearbyMediaDevicesManager,
+                        mAudioManager,
+                        mPowerExemptionManager,
+                        mKeyguardManager,
+                        mFlags,
+                        mUserTracker);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputDialog = makeTestDialog(mMediaOutputController);
         mMediaOutputDialog.show();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index a702dda..224e755 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
+import android.content.res.Configuration;
 import android.view.IWindowManager;
 import android.view.accessibility.AccessibilityManager;
 
@@ -55,6 +56,8 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.FakeConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import dagger.Lazy;
@@ -117,6 +120,7 @@
     EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
     @Mock
     NotificationShadeWindowController mNotificationShadeWindowController;
+    ConfigurationController mConfigurationController = new FakeConfigurationController();
 
     private AccessibilityManager.AccessibilityServicesStateChangeListener
             mAccessibilityServicesStateChangeListener;
@@ -144,9 +148,8 @@
                 mSystemActions, mOverviewProxyService, mAssistManagerLazy,
                 () -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class),
                 mNavigationModeController, mEdgeBackGestureHandlerFactory, mWm, mUserTracker,
-                mDisplayTracker, mNotificationShadeWindowController, mDumpManager, mCommandQueue,
-                mSynchronousExecutor);
-
+                mDisplayTracker, mNotificationShadeWindowController, mConfigurationController,
+                mDumpManager, mCommandQueue, mSynchronousExecutor);
     }
 
     @Test
@@ -335,6 +338,12 @@
         assertThat(state2.mWindowState).isNotEqualTo(newState);
     }
 
+    @Test
+    public void configUpdatePropagatesToEdgeBackGestureHandler() {
+        mConfigurationController.onConfigurationChanged(Configuration.EMPTY);
+        verify(mEdgeBackGestureHandler, times(1)).onConfigurationChanged(any());
+    }
+
     private List<String> createFakeShortcutTargets() {
         return new ArrayList<>(List.of("a", "b", "c", "d"));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index d405df7..354a87a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -37,11 +37,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
-import android.content.res.Configuration;
 import android.testing.AndroidTestingRunner;
 import android.util.SparseArray;
 
@@ -293,23 +290,6 @@
     }
 
     @Test
-    public void testConfigurationChange_taskbarNotInitialized() {
-        Configuration configuration = mContext.getResources().getConfiguration();
-        mNavigationBarController.mIsLargeScreen = true;
-        mNavigationBarController.onConfigChanged(configuration);
-        verify(mTaskbarDelegate, never()).onConfigurationChanged(configuration);
-    }
-
-    @Test
-    public void testConfigurationChange_taskbarInitialized() {
-        Configuration configuration = mContext.getResources().getConfiguration();
-        mNavigationBarController.mIsLargeScreen = true;
-        when(mTaskbarDelegate.isInitialized()).thenReturn(true);
-        mNavigationBarController.onConfigChanged(configuration);
-        verify(mTaskbarDelegate, times(1)).onConfigurationChanged(configuration);
-    }
-
-    @Test
     public void testShouldRenderTaskbar_taskbarNotRenderedOnPhone() {
         mNavigationBarController.mIsLargeScreen = false;
         mNavigationBarController.mIsPhone = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index b38d5e3..0e7a215 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -111,6 +111,7 @@
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.DeviceConfigProxyFake;
@@ -275,8 +276,8 @@
                     mKeyguardStateController, mock(NavigationModeController.class),
                     mEdgeBackGestureHandlerFactory, mock(IWindowManager.class),
                     mock(UserTracker.class), mock(DisplayTracker.class),
-                    mNotificationShadeWindowController, mock(DumpManager.class),
-                    mock(CommandQueue.class), mSynchronousExecutor));
+                    mNotificationShadeWindowController, mock(ConfigurationController.class),
+                    mock(DumpManager.class), mock(CommandQueue.class), mSynchronousExecutor));
             mNavigationBar = createNavBar(mContext);
             mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
         });
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
index e4a4836..6956bea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
@@ -57,6 +57,7 @@
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.flags.FeatureFlagsClassic;
 import com.android.systemui.media.controls.ui.view.MediaHost;
 import com.android.systemui.qs.customize.QSCustomizerController;
@@ -66,7 +67,6 @@
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.CommandQueue;
@@ -115,7 +115,6 @@
     @Mock private FooterActionsViewBinder mFooterActionsViewBinder;
     @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
     @Mock private FeatureFlagsClassic mFeatureFlags;
-    @Mock private SceneContainerFlags mSceneContainerFlags;
     private ViewGroup mQsView;
 
     private final CommandQueue mCommandQueue =
@@ -127,7 +126,6 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        when(mSceneContainerFlags.isEnabled()).thenReturn(false);
 
         mUnderTest = instantiate();
 
@@ -496,8 +494,8 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void testSceneContainerFlagsEnabled_FooterActionsRemoved_controllerNotStarted() {
-        when(mSceneContainerFlags.isEnabled()).thenReturn(true);
         clearInvocations(
                 mFooterActionsViewBinder, mFooterActionsViewModel, mFooterActionsViewModelFactory);
         QSImpl other = instantiate();
@@ -513,9 +511,8 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void testSceneContainerFlagsEnabled_statusBarStateIsShade() {
-        when(mSceneContainerFlags.isEnabled()).thenReturn(true);
-
         mUnderTest.onStateChanged(KEYGUARD);
         assertThat(mUnderTest.getStatusBarState()).isEqualTo(SHADE);
 
@@ -524,9 +521,8 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void testSceneContainerFlagsEnabled_isKeyguardState_alwaysFalse() {
-        when(mSceneContainerFlags.isEnabled()).thenReturn(true);
-
         mUnderTest.onStateChanged(KEYGUARD);
         assertThat(mUnderTest.isKeyguardState()).isFalse();
 
@@ -559,8 +555,8 @@
                 mFooterActionsViewModelFactory,
                 mFooterActionsViewBinder,
                 mLargeScreenShadeInterpolator,
-                mFeatureFlags,
-                mSceneContainerFlags);
+                mFeatureFlags
+        );
     }
 
     private void setUpOther() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index a60494f..0275643 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -17,13 +17,13 @@
 import com.android.systemui.qs.customize.QSCustomizerController
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
 import com.android.systemui.settings.brightness.BrightnessController
 import com.android.systemui.settings.brightness.BrightnessSliderController
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
 import com.android.systemui.tuner.TunerService
 import com.google.common.truth.Truth.assertThat
+import javax.inject.Provider
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -36,7 +36,6 @@
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
-import javax.inject.Provider
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
@@ -65,8 +64,6 @@
     @Mock private lateinit var pagedTileLayout: PagedTileLayout
     @Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
 
-    private val sceneContainerFlags = FakeSceneContainerFlags()
-
     private lateinit var controller: QSPanelController
     private val testableResources: TestableResources = mContext.orCreateTestableResources
 
@@ -103,7 +100,6 @@
             falsingManager,
             statusBarKeyguardViewManager,
             ResourcesSplitShadeStateController(),
-            sceneContainerFlags,
             longPressEffectProvider,
         )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 8acde36..4915e55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -20,15 +20,14 @@
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Answers
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -43,8 +42,6 @@
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private lateinit var context: Context
 
-    private val sceneContainerFlags = FakeSceneContainerFlags()
-
     private lateinit var controller: QuickStatusBarHeaderController
 
     @Before
@@ -55,9 +52,8 @@
         `when`(view.context).thenReturn(context)
 
         controller = QuickStatusBarHeaderController(
-                view,
-                quickQSPanelController,
-                sceneContainerFlags,
+            view,
+            quickQSPanelController,
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index 1313227..387f27d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -42,7 +42,6 @@
 import com.android.systemui.navigationbar.NavigationBarController
 import com.android.systemui.navigationbar.NavigationModeController
 import com.android.systemui.recents.OverviewProxyService.ACTION_QUICKSTEP
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
 import com.android.systemui.settings.FakeDisplayTracker
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shade.ShadeViewController
@@ -249,7 +248,6 @@
             sysuiUnlockAnimationController,
             inWindowLauncherUnlockAnimationManager,
             assistUtils,
-            FakeSceneContainerFlags(),
             dumpManager,
             unfoldTransitionProgressForwarder,
             broadcastDispatcher
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index cf7c6f4..b89ccef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -75,8 +75,6 @@
 import com.android.systemui.scene.FakeWindowRootViewComponent;
 import com.android.systemui.scene.data.repository.SceneContainerRepository;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.scene.shared.logger.SceneLogger;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.data.repository.FakeShadeRepository;
@@ -136,7 +134,6 @@
     @Mock private ShadeWindowLogger mShadeWindowLogger;
     @Mock private SelectedUserInteractor mSelectedUserInteractor;
     @Mock private UserTracker mUserTracker;
-    @Mock private SceneContainerFlags mSceneContainerFlags;
     @Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
     @Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
     @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListener;
@@ -185,14 +182,12 @@
                 mKosmos.getDeviceUnlockedInteractor());
 
         FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository();
-        FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
         KeyguardTransitionInteractor keyguardTransitionInteractor =
                 mKosmos.getKeyguardTransitionInteractor();
         KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
                 keyguardRepository,
                 new FakeCommandQueue(),
                 powerInteractor,
-                sceneContainerFlags,
                 new FakeKeyguardBouncerRepository(),
                 new ConfigurationInteractor(configurationRepository),
                 shadeRepository,
@@ -256,7 +251,6 @@
                 mShadeWindowLogger,
                 () -> mSelectedUserInteractor,
                 mUserTracker,
-                mSceneContainerFlags,
                 () -> communalInteractor) {
                     @Override
                     protected boolean isDebuggable() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index 20d877e..77ad17a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -62,7 +62,6 @@
 import com.android.systemui.res.R;
 import com.android.systemui.scene.data.repository.SceneContainerRepository;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
 import com.android.systemui.scene.shared.logger.SceneLogger;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.shade.data.repository.FakeShadeRepository;
@@ -208,14 +207,12 @@
                 mock(SceneLogger.class),
                 mKosmos.getDeviceUnlockedInteractor());
 
-        FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
         KeyguardTransitionInteractor keyguardTransitionInteractor =
                 mKosmos.getKeyguardTransitionInteractor();
         KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
                 mKeyguardRepository,
                 new FakeCommandQueue(),
                 powerInteractor,
-                sceneContainerFlags,
                 new FakeKeyguardBouncerRepository(),
                 new ConfigurationInteractor(configurationRepository),
                 mShadeRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index 433c95a..6bdd3ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
@@ -95,7 +94,6 @@
             headsUpManager,
             PowerInteractorFactory.create().powerInteractor,
             ActiveNotificationsInteractor(activeNotificationsRepository, testDispatcher),
-            kosmos.sceneContainerFlags,
             kosmos::sceneInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index d2fc087..be5af88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -55,7 +55,6 @@
 import com.android.systemui.power.data.repository.FakePowerRepository
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.LargeScreenHeaderHelper
 import com.android.systemui.shade.data.repository.FakeShadeRepository
@@ -87,8 +86,8 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -135,7 +134,6 @@
         val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
         val featureFlags = FakeFeatureFlagsClassic()
         val shadeRepository = FakeShadeRepository()
-        val sceneContainerFlags = FakeSceneContainerFlags()
         val configurationRepository = FakeConfigurationRepository()
         val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
         fromLockscreenTransitionInteractor = kosmos.fromLockscreenTransitionInteractor
@@ -146,7 +144,6 @@
                 keyguardRepository,
                 FakeCommandQueue(),
                 powerInteractor,
-                sceneContainerFlags,
                 FakeKeyguardBouncerRepository(),
                 ConfigurationInteractor(configurationRepository),
                 shadeRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index 54a6523..bb68ec5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -138,7 +138,6 @@
                 mHeadsUpManager,
                 mPowerInteractor,
                 mActiveNotificationsInteractor,
-                mKosmos.getSceneContainerFlags(),
                 () -> mKosmos.getSceneInteractor());
         mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index db053d8..9e2856d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -180,7 +180,6 @@
                 mHeadsUpManager,
                 PowerInteractorFactory.create().getPowerInteractor(),
                 mActiveNotificationsInteractor,
-                mKosmos.getSceneContainerFlags(),
                 () -> mKosmos.getSceneInteractor()
         );
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 65a960b..1b85dfa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -45,6 +45,7 @@
 import com.android.internal.statusbar.statusBarService
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager
@@ -55,7 +56,6 @@
 import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.UserContextProvider
 import com.android.systemui.shade.shadeControllerSceneImpl
@@ -93,6 +93,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper
+@EnableSceneContainer
 class NotificationGutsManagerWithScenesTest : SysuiTestCase() {
     private val testNotificationChannel =
         NotificationChannel(
@@ -143,8 +144,6 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        val sceneContainerFlags = kosmos.fakeSceneContainerFlags
-        sceneContainerFlags.enabled = true
         allowTestableLooperAsMainThread()
         helper = NotificationTestHelper(mContext, mDependency)
         Mockito.`when`(accessibilityManager.isTouchExplorationEnabled).thenReturn(false)
@@ -156,9 +155,9 @@
                 headsUpManager,
                 create().powerInteractor,
                 activeNotificationsInteractor,
-                sceneContainerFlags,
-                { sceneInteractor },
-            )
+            ) {
+                sceneInteractor
+            }
         gutsManager =
             NotificationGutsManager(
                 mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 783bf80..5c65103 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -101,6 +102,7 @@
 import com.android.systemui.communal.shared.model.CommunalScenes;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.fragments.FragmentService;
@@ -120,7 +122,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
 import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
@@ -336,8 +337,6 @@
     private final DumpManager mDumpManager = new DumpManager();
     private final ScreenLifecycle mScreenLifecycle = new ScreenLifecycle(mDumpManager);
 
-    private final FakeSceneContainerFlags mSceneContainerFlags = new FakeSceneContainerFlags();
-
     private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor =
             mKosmos.getBrightnessMirrorShowingInteractor();
 
@@ -351,7 +350,9 @@
         // Turn AOD on and toggle feature flag for jank fixes
         mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true);
         when(mDozeParameters.getAlwaysOn()).thenReturn(true);
-        mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
+        if (!com.android.systemui.Flags.sceneContainer()) {
+            mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
+        }
 
         IThermalService thermalService = mock(IThermalService.class);
         mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
@@ -426,22 +427,25 @@
             ((Runnable) invocation.getArgument(0)).run();
             return null;
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
-
-        mShadeController = spy(new ShadeControllerImpl(
-                mCommandQueue,
-                mMainExecutor,
-                mock(WindowRootViewVisibilityInteractor.class),
-                mKeyguardStateController,
-                mStatusBarStateController,
-                mStatusBarKeyguardViewManager,
-                mStatusBarWindowController,
-                mDeviceProvisionedController,
-                mNotificationShadeWindowController,
-                0,
-                () -> mNotificationPanelViewController,
-                () -> mAssistManager,
-                () -> mNotificationGutsManager
-        ));
+        if (com.android.systemui.Flags.sceneContainer()) {
+            mShadeController = spy(mKosmos.getShadeController());
+        } else {
+            mShadeController = spy(new ShadeControllerImpl(
+                    mCommandQueue,
+                    mMainExecutor,
+                    mock(WindowRootViewVisibilityInteractor.class),
+                    mKeyguardStateController,
+                    mStatusBarStateController,
+                    mStatusBarKeyguardViewManager,
+                    mStatusBarWindowController,
+                    mDeviceProvisionedController,
+                    mNotificationShadeWindowController,
+                    0,
+                    () -> mNotificationPanelViewController,
+                    () -> mAssistManager,
+                    () -> mNotificationGutsManager
+            ));
+        }
         mShadeController.setNotificationShadeWindowViewController(
                 mNotificationShadeWindowViewController);
         mShadeController.setNotificationPresenter(mNotificationPresenter);
@@ -562,7 +566,6 @@
                 mUserTracker,
                 () -> mFingerprintManager,
                 mActivityStarter,
-                mSceneContainerFlags,
                 mBrightnessMirrorShowingInteractor
         );
         mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver);
@@ -1094,25 +1097,24 @@
     }
 
     @Test
+    @EnableSceneContainer
     public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
-        mSceneContainerFlags.setEnabled(true);
         mCentralSurfaces.registerCallbacks();
 
         mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
         mTestScope.getTestScheduler().runCurrent();
-        verify(mScrimController).transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+        verify(mScrimController, atLeastOnce()).transitionTo(ScrimState.BRIGHTNESS_MIRROR);
 
         mBrightnessMirrorShowingInteractor.setMirrorShowing(false);
         mTestScope.getTestScheduler().runCurrent();
         ArgumentCaptor<ScrimState> captor = ArgumentCaptor.forClass(ScrimState.class);
         // The default is to call the one with the callback argument
-        verify(mScrimController).transitionTo(captor.capture(), any());
+        verify(mScrimController, atLeastOnce()).transitionTo(captor.capture(), any());
         assertThat(captor.getValue()).isNotEqualTo(ScrimState.BRIGHTNESS_MIRROR);
     }
 
     @Test
     public void brightnesShowingChanged_flagDisabled_ScrimControllerNotified() {
-        mSceneContainerFlags.setEnabled(false);
         mCentralSurfaces.registerCallbacks();
 
         mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index dc3db4c..a6a4f24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -20,9 +20,9 @@
 import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS;
 import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
 
+import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
-import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -172,7 +172,6 @@
                 mKeyguardRepository,
                 mCommandQueue,
                 PowerInteractorFactory.create().getPowerInteractor(),
-                mKosmos.getSceneContainerFlags(),
                 new FakeKeyguardBouncerRepository(),
                 new ConfigurationInteractor(new FakeConfigurationRepository()),
                 new FakeShadeRepository(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 1463680..d365663 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeControllerImpl
 import com.android.systemui.shade.ShadeLogger
@@ -51,6 +50,8 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.view.ViewUtil
 import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import javax.inject.Provider
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentCaptor
@@ -61,8 +62,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.Optional
-import javax.inject.Provider
 
 @SmallTest
 class PhoneStatusBarViewControllerTest : SysuiTestCase() {
@@ -296,7 +295,6 @@
             Optional.of(sysuiUnfoldComponent),
             Optional.of(progressProvider),
             featureFlags,
-            FakeSceneContainerFlags(),
             userChipViewModel,
             centralSurfacesImpl,
             statusBarWindowStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
index 1e628bd..dedd0af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
@@ -13,68 +13,103 @@
  */
 package com.android.systemui.statusbar.phone
 
+import android.app.Dialog
 import android.content.res.Configuration
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import android.view.WindowManager
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.testKosmos
 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.mock
-import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper(setAsMainLooper = true)
 class SystemUIBottomSheetDialogTest : SysuiTestCase() {
 
+    private val kosmos = testKosmos()
     private val configurationController = mock<ConfigurationController>()
     private val config = mock<Configuration>()
+    private val delegate = mock<DialogDelegate<Dialog>>()
 
     private lateinit var dialog: SystemUIBottomSheetDialog
 
     @Before
     fun setup() {
-        dialog = SystemUIBottomSheetDialog(mContext, configurationController)
+        dialog =
+            with(kosmos) {
+                SystemUIBottomSheetDialog(
+                    context,
+                    testScope.backgroundScope,
+                    configurationController,
+                    delegate,
+                    TestLayout(),
+                    0,
+                )
+            }
     }
 
     @Test
     fun onStart_registersConfigCallback() {
-        dialog.show()
+        kosmos.testScope.runTest {
+            dialog.show()
+            runCurrent()
 
-        verify(configurationController).addCallback(any())
+            verify(configurationController).addCallback(any())
+        }
     }
 
     @Test
     fun onStop_unregisterConfigCallback() {
-        dialog.show()
-        dialog.dismiss()
+        kosmos.testScope.runTest {
+            dialog.show()
+            runCurrent()
+            dialog.dismiss()
+            runCurrent()
 
-        verify(configurationController).removeCallback(any())
+            verify(configurationController).removeCallback(any())
+        }
     }
 
     @Test
-    fun onConfigurationChanged_calledInSubclass() {
-        var onConfigChangedCalled = false
-        val subclass =
-            object : SystemUIBottomSheetDialog(mContext, configurationController) {
-                override fun onConfigurationChanged() {
-                    onConfigChangedCalled = true
-                }
-            }
+    fun onConfigurationChanged_calledInDelegate() {
+        kosmos.testScope.runTest {
+            dialog.show()
+            runCurrent()
+            val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
+            verify(configurationController).addCallback(capture(captor))
 
-        subclass.show()
+            captor.value.onConfigChanged(config)
+            runCurrent()
 
-        val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
-        verify(configurationController).addCallback(capture(captor))
-        captor.value.onConfigChanged(config)
+            verify(delegate).onConfigurationChanged(any(), any())
+        }
+    }
 
-        assertThat(onConfigChangedCalled).isTrue()
+    private class TestLayout : SystemUIBottomSheetDialog.WindowLayout {
+        override fun calculate(): Flow<SystemUIBottomSheetDialog.WindowLayout.Layout> {
+            return flowOf(
+                SystemUIBottomSheetDialog.WindowLayout.Layout(
+                    WindowManager.LayoutParams.MATCH_PARENT,
+                    WindowManager.LayoutParams.MATCH_PARENT,
+                )
+            )
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index 69536c5..bdd3d18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.data.repository.FakeShadeRepository
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository
@@ -60,7 +59,6 @@
             keyguardRepository,
             mock<CommandQueue>(),
             PowerInteractorFactory.create().powerInteractor,
-            kosmos.sceneContainerFlags,
             FakeKeyguardBouncerRepository(),
             ConfigurationInteractor(FakeConfigurationRepository()),
             FakeShadeRepository(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index c24c86c..d9a0c4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -121,8 +121,6 @@
 import com.android.systemui.scene.FakeWindowRootViewComponent;
 import com.android.systemui.scene.data.repository.SceneContainerRepository;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.scene.shared.logger.SceneLogger;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.settings.UserTracker;
@@ -360,8 +358,6 @@
     @Mock
     private Display mDefaultDisplay;
     @Mock
-    private SceneContainerFlags mSceneContainerFlags;
-    @Mock
     private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
 
     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
@@ -430,14 +426,12 @@
                 mock(SceneLogger.class),
                 mKosmos.getDeviceUnlockedInteractor());
 
-        FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
         KeyguardTransitionInteractor keyguardTransitionInteractor =
                 mKosmos.getKeyguardTransitionInteractor();
         KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
                 keyguardRepository,
                 new FakeCommandQueue(),
                 powerInteractor,
-                sceneContainerFlags,
                 new FakeKeyguardBouncerRepository(),
                 new ConfigurationInteractor(configurationRepository),
                 shadeRepository,
@@ -503,7 +497,6 @@
                 mShadeWindowLogger,
                 () -> mSelectedUserInteractor,
                 mUserTracker,
-                mSceneContainerFlags,
                 mKosmos::getCommunalInteractor
         );
         mNotificationShadeWindowController.fetchWindowRootView();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
index de7b14d..0682361 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
@@ -31,7 +31,7 @@
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.SystemUIDeviceEntryFaceAuthInteractor
 import com.android.systemui.scene.SceneContainerFrameworkModule
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneDataSource
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -104,11 +104,10 @@
 
         @Provides
         fun provideBaseShadeInteractor(
-            sceneContainerFlags: SceneContainerFlags,
             sceneContainerOn: Provider<ShadeInteractorSceneContainerImpl>,
             sceneContainerOff: Provider<ShadeInteractorLegacyImpl>
         ): BaseShadeInteractor {
-            return if (sceneContainerFlags.isEnabled()) {
+            return if (SceneContainerFlag.isEnabled) {
                 sceneContainerOn.get()
             } else {
                 sceneContainerOff.get()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
index 5c3e1f4..60d97d1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
@@ -17,8 +17,6 @@
 package com.android.systemui.bouncer.shared.flag
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 
-var Kosmos.fakeComposeBouncerFlags by
-    Kosmos.Fixture { FakeComposeBouncerFlags(fakeSceneContainerFlags) }
+var Kosmos.fakeComposeBouncerFlags by Kosmos.Fixture { FakeComposeBouncerFlags() }
 val Kosmos.composeBouncerFlags by Kosmos.Fixture<ComposeBouncerFlags> { fakeComposeBouncerFlags }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
index c116bbd..7482c0f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
@@ -16,14 +16,11 @@
 
 package com.android.systemui.bouncer.shared.flag
 
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 
-class FakeComposeBouncerFlags(
-    private val sceneContainerFlags: SceneContainerFlags,
-    var composeBouncerEnabled: Boolean = false
-) : ComposeBouncerFlags {
+class FakeComposeBouncerFlags(var composeBouncerEnabled: Boolean = false) : ComposeBouncerFlags {
     override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
-        return sceneContainerFlags.isEnabled() || composeBouncerEnabled
+        return SceneContainerFlag.isEnabled || composeBouncerEnabled
     }
 
     @Deprecated(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 4b6ef37..3dd382f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.settings.userTracker
 import com.android.systemui.smartspace.data.repository.smartspaceRepository
 import com.android.systemui.user.data.repository.fakeUserRepository
@@ -46,21 +45,20 @@
         broadcastDispatcher = broadcastDispatcher,
         communalRepository = communalRepository,
         widgetRepository = communalWidgetRepository,
-        mediaRepository = communalMediaRepository,
         communalPrefsRepository = communalPrefsRepository,
+        mediaRepository = communalMediaRepository,
         smartspaceRepository = smartspaceRepository,
-        appWidgetHost = mock(),
         keyguardInteractor = keyguardInteractor,
+        communalSettingsInteractor = communalSettingsInteractor,
+        appWidgetHost = mock(),
         editWidgetsActivityStarter = editWidgetsActivityStarter,
         userTracker = userTracker,
         activityStarter = activityStarter,
         userManager = userManager,
         dockManager = fakeDockManager,
+        sceneInteractor = sceneInteractor,
         logBuffer = logcatLogBuffer("CommunalInteractor"),
         tableLogBuffer = mock(),
-        communalSettingsInteractor = communalSettingsInteractor,
-        sceneInteractor = sceneInteractor,
-        sceneContainerFlags = sceneContainerFlags,
     )
 }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
index e21c766..2e751cc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -24,12 +24,9 @@
 import com.android.systemui.keyguard.data.repository.FakeCommandQueue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.shade.data.repository.FakeShadeRepository
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor.ConfigurationBasedDimensions
@@ -49,7 +46,6 @@
     @JvmStatic
     fun create(
         featureFlags: FakeFeatureFlags = FakeFeatureFlags(),
-        sceneContainerFlags: SceneContainerFlags = FakeSceneContainerFlags(),
         repository: FakeKeyguardRepository = FakeKeyguardRepository(),
         commandQueue: FakeCommandQueue = FakeCommandQueue(),
         bouncerRepository: FakeKeyguardBouncerRepository = FakeKeyguardBouncerRepository(),
@@ -88,7 +84,6 @@
             repository = repository,
             commandQueue = commandQueue,
             featureFlags = featureFlags,
-            sceneContainerFlags = sceneContainerFlags,
             bouncerRepository = bouncerRepository,
             configurationRepository = configurationRepository,
             shadeRepository = shadeRepository,
@@ -96,13 +91,12 @@
             KeyguardInteractor(
                 repository = repository,
                 commandQueue = commandQueue,
-                sceneContainerFlags = sceneContainerFlags,
+                powerInteractor = powerInteractor,
                 bouncerRepository = bouncerRepository,
                 configurationInteractor = ConfigurationInteractor(configurationRepository),
                 shadeRepository = shadeRepository,
-                sceneInteractorProvider = { sceneInteractor },
                 keyguardTransitionInteractor = keyguardTransitionInteractor,
-                powerInteractor = powerInteractor,
+                sceneInteractorProvider = { sceneInteractor },
                 fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
                 sharedNotificationContainerInteractor = { sncInteractor },
                 applicationScope = testScope,
@@ -114,7 +108,6 @@
         val repository: FakeKeyguardRepository,
         val commandQueue: FakeCommandQueue,
         val featureFlags: FakeFeatureFlags,
-        val sceneContainerFlags: SceneContainerFlags,
         val bouncerRepository: FakeKeyguardBouncerRepository,
         val configurationRepository: FakeConfigurationRepository,
         val shadeRepository: FakeShadeRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index 2a0c01c..9426718 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.statusbar.commandQueue
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -34,7 +33,6 @@
             repository = keyguardRepository,
             commandQueue = commandQueue,
             powerInteractor = powerInteractor,
-            sceneContainerFlags = sceneContainerFlags,
             bouncerRepository = keyguardBouncerRepository,
             configurationInteractor = configurationInteractor,
             shadeRepository = shadeRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
index 709f864..58b0ff8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,7 +46,6 @@
         transitionInteractor = keyguardTransitionInteractor,
         keyguardInteractor = keyguardInteractor,
         viewModel = aodToLockscreenTransitionViewModel,
-        sceneContainerFlags = sceneContainerFlags,
         keyguardViewController = { statusBarKeyguardViewManager },
         deviceEntryInteractor = deviceEntryInteractor,
         deviceEntrySourceInteractor = deviceEntrySourceInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index fdc3e0a..162f278 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -48,10 +48,9 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.sceneContainerConfig
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.scene.shared.model.sceneDataSource
 import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
+import com.android.systemui.shade.shadeController
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 import com.android.systemui.statusbar.phone.screenOffAnimationController
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
@@ -71,8 +70,6 @@
     val testDispatcher by lazy { kosmos.testDispatcher }
     val testScope by lazy { kosmos.testScope }
     val fakeFeatureFlags by lazy { kosmos.fakeFeatureFlagsClassic }
-    val fakeSceneContainerFlags by lazy { kosmos.fakeSceneContainerFlags }
-    val sceneContainerFlags by lazy { kosmos.sceneContainerFlags }
     val fakeExecutor by lazy { kosmos.fakeExecutor }
     val fakeExecutorHandler by lazy { kosmos.fakeExecutorHandler }
     val configurationRepository by lazy { kosmos.fakeConfigurationRepository }
@@ -112,6 +109,7 @@
     }
     val brightnessMirrorShowingInteractor by lazy { kosmos.brightnessMirrorShowingInteractor }
     val qsLongPressEffect by lazy { kosmos.qsLongPressEffect }
+    val shadeController by lazy { kosmos.shadeController }
 
     init {
         kosmos.applicationContext = testCase.context
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
index 7ce810e..7dab5c2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
@@ -17,5 +17,6 @@
 package com.android.systemui.media.controls.data.repository
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.time.systemClock
 
-val Kosmos.mediaFilterRepository by Kosmos.Fixture { MediaFilterRepository() }
+val Kosmos.mediaFilterRepository by Kosmos.Fixture { MediaFilterRepository(systemClock) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
index 6f652f2..e88d22a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
@@ -18,9 +18,5 @@
 
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 
-val Kosmos.mediaFlags by
-    Kosmos.Fixture {
-        MediaFlags(featureFlags = featureFlagsClassic, sceneContainerFlags = sceneContainerFlags)
-    }
+val Kosmos.mediaFlags by Kosmos.Fixture { MediaFlags(featureFlags = featureFlagsClassic) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt
deleted file mode 100644
index ded7256..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.scene.shared.flag
-
-import dagger.Binds
-import dagger.Module
-import dagger.Provides
-
-class FakeSceneContainerFlags(
-    var enabled: Boolean = SceneContainerFlag.isEnabled,
-) : SceneContainerFlags {
-
-    override fun isEnabled(): Boolean {
-        return enabled
-    }
-
-    override fun requirementDescription(): String {
-        return ""
-    }
-}
-
-@Module(includes = [FakeSceneContainerFlagsModule.Bindings::class])
-class FakeSceneContainerFlagsModule(
-    @get:Provides val sceneContainerFlags: FakeSceneContainerFlags = FakeSceneContainerFlags(),
-) {
-    @Module
-    interface Bindings {
-        @Binds fun bindFake(fake: FakeSceneContainerFlags): SceneContainerFlags
-    }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt
deleted file mode 100644
index 979d8e7..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.scene.shared.flag
-
-import com.android.systemui.kosmos.Kosmos
-
-var Kosmos.fakeSceneContainerFlags by Kosmos.Fixture { FakeSceneContainerFlags() }
-val Kosmos.sceneContainerFlags by Kosmos.Fixture<SceneContainerFlags> { fakeSceneContainerFlags }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
index 07e2d6b..543d5b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.ShadeModule
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.statusbar.disableflags.data.repository.disableFlagsRepository
@@ -36,7 +35,6 @@
 var Kosmos.baseShadeInteractor: BaseShadeInteractor by
     Kosmos.Fixture {
         ShadeModule.provideBaseShadeInteractor(
-            sceneContainerFlags = sceneContainerFlags,
             sceneContainerOn = { shadeInteractorSceneContainerImpl },
             sceneContainerOff = { shadeInteractorLegacyImpl },
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index b249211..f0eea38 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 
@@ -30,7 +29,6 @@
         dumpManager = dumpManager,
         interactor = notificationStackAppearanceInteractor,
         shadeInteractor = shadeInteractor,
-        flags = sceneContainerFlags,
         featureFlags = featureFlagsClassic,
         keyguardInteractor = keyguardInteractor,
     )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
index cf800d0..9c3f510 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.scene.data.repository.windowRootViewVisibilityRepository
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 import com.android.systemui.statusbar.policy.headsUpManager
 
@@ -36,7 +35,7 @@
         headsUpManager = headsUpManager,
         powerInteractor = powerInteractor,
         activeNotificationsInteractor = activeNotificationsInteractor,
-        sceneInteractorProvider = { sceneInteractor },
-        sceneContainerFlags = sceneContainerFlags,
-    )
+    ) {
+        sceneInteractor
+    }
 }
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 23e269a..cbbce1a 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -19,6 +19,7 @@
 import static android.app.WallpaperManager.FLAG_LOCK;
 import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE;
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA;
@@ -39,6 +40,7 @@
 import android.content.SharedPreferences;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
+import android.graphics.BitmapFactory;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
@@ -109,22 +111,16 @@
     static final String LOCK_WALLPAPER_STAGE = "wallpaper-lock-stage";
     @VisibleForTesting
     static final String WALLPAPER_INFO_STAGE = "wallpaper-info-stage";
-
     @VisibleForTesting
     static final String WALLPAPER_BACKUP_DEVICE_INFO_STAGE = "wallpaper-backup-device-info-stage";
-
     static final String EMPTY_SENTINEL = "empty";
     static final String QUOTA_SENTINEL = "quota";
-
     // Shared preferences constants.
     static final String PREFS_NAME = "wbprefs.xml";
     static final String SYSTEM_GENERATION = "system_gen";
     static final String LOCK_GENERATION = "lock_gen";
 
-    /**
-     * An approximate area threshold to compare device dimension similarity
-     */
-    static final int AREA_THRESHOLD = 50; // TODO (b/327637867): determine appropriate threshold
+    static final float DEFAULT_ACCEPTABLE_PARALLAX = 0.2f;
 
     // If this file exists, it means we exceeded our quota last time
     private File mQuotaFile;
@@ -336,7 +332,6 @@
         mEventLogger.onSystemImageWallpaperBackupFailed(error);
     }
 
-
     private void backupLockWallpaperFileIfItExists(SharedPreferences sharedPrefs,
             boolean lockChanged, int lockGeneration, FullBackupDataOutput data) throws IOException {
         final File lockImageStage = new File(getFilesDir(), LOCK_WALLPAPER_STAGE);
@@ -409,6 +404,16 @@
         }
     }
 
+    private static String readText(TypedXmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        String result = "";
+        if (parser.next() == XmlPullParser.TEXT) {
+            result = parser.getText();
+            parser.nextTag();
+        }
+        return result;
+    }
+
     @VisibleForTesting
     // fullBackupFile is final, so we intercept backups here in tests.
     protected void backupFile(File file, FullBackupDataOutput data) {
@@ -438,18 +443,10 @@
         boolean lockImageStageExists = lockImageStage.exists();
 
         try {
-            // Parse the device dimensions of the source device and compare with target to
-            // to identify whether we need to skip the remainder of the restore process
+            // Parse the device dimensions of the source device
             Pair<Point, Point> sourceDeviceDimensions = parseDeviceDimensions(
                     deviceDimensionsStage);
 
-            Point targetDeviceDimensions = getScreenDimensions();
-            if (sourceDeviceDimensions != null && targetDeviceDimensions != null
-                    && isSourceDeviceSignificantlySmallerThanTarget(sourceDeviceDimensions.first,
-                    targetDeviceDimensions)) {
-                Slog.d(TAG, "The source device is significantly smaller than target");
-            }
-
             // First parse the live component name so that we know for logging if we care about
             // logging errors with the image restore.
             ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
@@ -466,9 +463,10 @@
             // to back up the original image on the source device, or there was no user-supplied
             // wallpaper image present.
             if (lockImageStageExists) {
-                restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK);
+                restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK,
+                        sourceDeviceDimensions);
             }
-            restoreFromStage(imageStage, infoStage, "wp", sysWhich);
+            restoreFromStage(imageStage, infoStage, "wp", sysWhich, sourceDeviceDimensions);
 
             // And reset to the wallpaper service we should be using
             if (mLockHasLiveComponent) {
@@ -543,16 +541,6 @@
         }
     }
 
-    private static String readText(TypedXmlPullParser parser)
-            throws IOException, XmlPullParserException {
-        String result = "";
-        if (parser.next() == XmlPullParser.TEXT) {
-            result = parser.getText();
-            parser.nextTag();
-        }
-        return result;
-    }
-
     @VisibleForTesting
     void updateWallpaperComponent(ComponentName wpService, int which)
             throws IOException {
@@ -578,10 +566,13 @@
         }
     }
 
-    private void restoreFromStage(File stage, File info, String hintTag, int which)
+    private void restoreFromStage(File stage, File info, String hintTag, int which,
+            Pair<Point, Point> sourceDeviceDimensions)
             throws IOException {
         if (stage.exists()) {
             if (multiCrop()) {
+                // TODO(b/332937943): implement offset adjustment by manually adjusting crop to
+                //  adhere to device aspect ratio
                 SparseArray<Rect> cropHints = parseCropHints(info, hintTag);
                 if (cropHints != null) {
                     Slog.i(TAG, "Got restored wallpaper; applying which=" + which
@@ -601,7 +592,6 @@
                 }
                 return;
             }
-
             // Parse the restored info file to find the crop hint.  Note that this currently
             // relies on a priori knowledge of the wallpaper info file schema.
             Rect cropHint = parseCropHint(info, hintTag);
@@ -609,8 +599,33 @@
                 Slog.i(TAG, "Got restored wallpaper; applying which=" + which
                         + "; cropHint = " + cropHint);
                 try (FileInputStream in = new FileInputStream(stage)) {
-                    mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true,
-                            which);
+
+                    if (sourceDeviceDimensions != null && sourceDeviceDimensions.first != null) {
+                        BitmapFactory.Options options = new BitmapFactory.Options();
+                        options.inJustDecodeBounds = true;
+                        ParcelFileDescriptor pdf = ParcelFileDescriptor.open(stage, MODE_READ_ONLY);
+                        BitmapFactory.decodeFileDescriptor(pdf.getFileDescriptor(),
+                                null, options);
+                        Point bitmapSize = new Point(options.outWidth, options.outHeight);
+                        Point sourceDeviceSize = new Point(sourceDeviceDimensions.first.x,
+                                sourceDeviceDimensions.first.y);
+                        Point targetDeviceDimensions = getScreenDimensions();
+
+                        // TODO: for now we handle only the case where the target device has smaller
+                        // aspect ratio than the source device i.e. the target device is more narrow
+                        // than the source device
+                        if (isTargetMoreNarrowThanSource(targetDeviceDimensions,
+                                sourceDeviceSize)) {
+                            Rect adjustedCrop = findNewCropfromOldCrop(cropHint,
+                                    sourceDeviceDimensions.first, true, targetDeviceDimensions,
+                                    bitmapSize, true);
+
+                            cropHint.set(adjustedCrop);
+                        }
+                    }
+
+                    mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint,
+                            true, which);
 
                     // And log the success
                     if ((which & FLAG_SYSTEM) > 0) {
@@ -629,6 +644,209 @@
         }
     }
 
+    /**
+     * This method computes the crop of the stored wallpaper to preserve its center point as the
+     * user had set it in the previous device.
+     *
+     * The algorithm involves first computing the original crop of the user (without parallax). Then
+     * manually adjusting the user's original crop to respect the current device's aspect ratio
+     * (thereby preserving the center point). Then finally, adding any leftover image real-estate
+     * (i.e. space left over on the horizontal axis) to add parallax effect. Parallax is only added
+     * if was present in the old device's settings.
+     *
+     */
+    private Rect findNewCropfromOldCrop(Rect oldCrop, Point oldDisplaySize, boolean oldRtl,
+            Point newDisplaySize, Point bitmapSize, boolean newRtl) {
+        Rect cropWithoutParallax = withoutParallax(oldCrop, oldDisplaySize, oldRtl, bitmapSize);
+        oldCrop = oldCrop.isEmpty() ? new Rect(0, 0, bitmapSize.x, bitmapSize.y) : oldCrop;
+        float oldParallaxAmount = ((float) oldCrop.width() / cropWithoutParallax.width()) - 1;
+
+        Rect newCropWithSameCenterWithoutParallax = sameCenter(newDisplaySize, bitmapSize,
+                cropWithoutParallax);
+
+        Rect newCrop = newCropWithSameCenterWithoutParallax;
+
+        // calculate the amount of left-over space there is in the image after adjusting the crop
+        // from the above operation i.e. in a rtl configuration, this is the remaining space in the
+        // image after subtracting the new crop's right edge coordinate from the image itself, and
+        // for ltr, its just the new crop's left edge coordinate (as it's the distance from the
+        // beginning of the image)
+        int widthAvailableForParallaxOnTheNewDevice =
+                (newRtl) ? newCrop.left : bitmapSize.x - newCrop.right;
+
+        // calculate relatively how much this available space is as a fraction of the total cropped
+        // image
+        float availableParallaxAmount =
+                (float) widthAvailableForParallaxOnTheNewDevice / newCrop.width();
+
+        float minAcceptableParallax = Math.min(DEFAULT_ACCEPTABLE_PARALLAX, oldParallaxAmount);
+
+        if (DEBUG) {
+            Slog.d(TAG, "- cropWithoutParallax: " + cropWithoutParallax);
+            Slog.d(TAG, "- oldParallaxAmount: " + oldParallaxAmount);
+            Slog.d(TAG, "- newCropWithSameCenterWithoutParallax: "
+                    + newCropWithSameCenterWithoutParallax);
+            Slog.d(TAG, "- widthAvailableForParallaxOnTheNewDevice: "
+                    + widthAvailableForParallaxOnTheNewDevice);
+            Slog.d(TAG, "- availableParallaxAmount: " + availableParallaxAmount);
+            Slog.d(TAG, "- minAcceptableParallax: " + minAcceptableParallax);
+            Slog.d(TAG, "- oldCrop: " + oldCrop);
+            Slog.d(TAG, "- oldDisplaySize: " + oldDisplaySize);
+            Slog.d(TAG, "- oldRtl: " + oldRtl);
+            Slog.d(TAG, "- newDisplaySize: " + newDisplaySize);
+            Slog.d(TAG, "- bitmapSize: " + bitmapSize);
+            Slog.d(TAG, "- newRtl: " + newRtl);
+        }
+        if (availableParallaxAmount >= minAcceptableParallax) {
+            // but in any case, don't put more parallax than the amount of the old device
+            float parallaxToAdd = Math.min(availableParallaxAmount, oldParallaxAmount);
+
+            int widthToAddForParallax = (int) (newCrop.width() * parallaxToAdd);
+            if (DEBUG) {
+                Slog.d(TAG, "- parallaxToAdd: " + parallaxToAdd);
+                Slog.d(TAG, "- widthToAddForParallax: " + widthToAddForParallax);
+            }
+            if (newRtl) {
+                newCrop.left -= widthToAddForParallax;
+            } else {
+                newCrop.right += widthToAddForParallax;
+            }
+        }
+        return newCrop;
+    }
+
+    /**
+     * This method computes the original crop of the user without parallax.
+     *
+     * NOTE: When the user sets the wallpaper with a specific crop, there may additional image added
+     * to the crop to support parallax. In order to determine the user's actual crop the parallax
+     * must be removed if it exists.
+     */
+    Rect withoutParallax(Rect crop, Point displaySize, boolean rtl, Point bitmapSize) {
+        // in the case an image's crop is not set, we assume the image itself is cropped
+        if (crop.isEmpty()) {
+            crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+        }
+
+        if (DEBUG) {
+            Slog.w(TAG, "- crop: " + crop);
+        }
+
+        Rect adjustedCrop = new Rect(crop);
+        float suggestedDisplayRatio = (float) displaySize.x / displaySize.y;
+
+        // here we calculate the width of the wallpaper image such that it has the same aspect ratio
+        // as the given display i.e. the width of the image on a single page of the device without
+        // parallax (i.e. displaySize will correspond to the display the crop was originally set on)
+        int wallpaperWidthWithoutParallax = (int) (0.5f + (float) displaySize.x * crop.height()
+                / displaySize.y);
+        // subtracting wallpaperWidthWithoutParallax from the wallpaper crop gives the amount of
+        // parallax added
+        int widthToRemove = Math.max(0, crop.width() - wallpaperWidthWithoutParallax);
+
+        if (DEBUG) {
+            Slog.d(TAG, "- adjustedCrop: " + adjustedCrop);
+            Slog.d(TAG, "- suggestedDisplayRatio: " + suggestedDisplayRatio);
+            Slog.d(TAG, "- wallpaperWidthWithoutParallax: " + wallpaperWidthWithoutParallax);
+            Slog.d(TAG, "- widthToRemove: " + widthToRemove);
+        }
+        if (rtl) {
+            adjustedCrop.left += widthToRemove;
+        } else {
+            adjustedCrop.right -= widthToRemove;
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG, "- adjustedCrop: " + crop);
+        }
+        return adjustedCrop;
+    }
+
+    /**
+     * This method computes a new crop based on the given crop in order to preserve the center point
+     * of the given crop on the provided displaySize. This is only for the case where the device
+     * displaySize has a smaller aspect ratio than the cropped image.
+     *
+     * NOTE: If the width to height ratio is less in the device display than cropped image
+     * this means the aspect ratios are off and there will be distortions in the image
+     * if the image is applied to the current display (i.e. the image will be skewed ->
+     * pixels in the image will not align correctly with the same pixels in the image that are
+     * above them)
+     */
+    Rect sameCenter(Point displaySize, Point bitmapSize, Rect crop) {
+
+        // in the case an image's crop is not set, we assume the image itself is cropped
+        if (crop.isEmpty()) {
+            crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+        }
+
+        float screenRatio = (float) displaySize.x / displaySize.y;
+        float cropRatio = (float) crop.width() / crop.height();
+
+        Rect adjustedCrop = new Rect(crop);
+
+        if (screenRatio < cropRatio) {
+            // the screen is more narrow than the image, and as such, the image will need to be
+            // zoomed in till it fits in the vertical axis. Due to this, we need to manually adjust
+            // the image's crop in order for it to fit into the screen without having the framework
+            // do it (since the framework left aligns the image after zooming)
+
+            // Calculate the height of the adjusted wallpaper crop so it respects the aspect ratio
+            // of the device. To calculate the height, we will use the width of the current crop.
+            // This is so we find the largest height possible which also respects the device aspect
+            // ratio.
+            int heightToAdd = (int) (0.5f + crop.width() / screenRatio - crop.height());
+
+            // Calculate how much extra image space available that can be used to adjust
+            // the crop. If this amount is less than heightToAdd, from above, then that means we
+            // can't use heightToAdd. Instead we will need to use the maximum possible height, which
+            // is the height of the original bitmap. NOTE: the bitmap height may be different than
+            // the crop.
+            // since there is no guarantee to have height available on both sides
+            // (e.g. the available height might be fully at the bottom), grab the minimum
+            int availableHeight = 2 * Math.min(crop.top, bitmapSize.y - crop.bottom);
+            int actualHeightToAdd = Math.min(heightToAdd, availableHeight);
+
+            // half of the additional height is added to the top and bottom of the crop
+            adjustedCrop.top -= actualHeightToAdd / 2 + actualHeightToAdd % 2;
+            adjustedCrop.bottom += actualHeightToAdd / 2;
+
+            // Calculate the width of the adjusted crop. Initially we used the fixed width of the
+            // crop to calculate the heightToAdd, but since this height may be invalid (based on
+            // the calculation above) we calculate the width again instead of using the fixed width,
+            // using the adjustedCrop's updated height.
+            int widthToRemove = (int) (0.5f + crop.width() - adjustedCrop.height() * screenRatio);
+
+            // half of the additional width is subtracted from the left and right side of the crop
+            int widthToRemoveLeft = widthToRemove / 2;
+            int widthToRemoveRight = widthToRemove / 2 + widthToRemove % 2;
+
+            adjustedCrop.left += widthToRemoveLeft;
+            adjustedCrop.right -= widthToRemoveRight;
+
+            if (DEBUG) {
+                Slog.d(TAG, "cropRatio: " + cropRatio);
+                Slog.d(TAG, "screenRatio: " + screenRatio);
+                Slog.d(TAG, "heightToAdd: " + heightToAdd);
+                Slog.d(TAG, "actualHeightToAdd: " + actualHeightToAdd);
+                Slog.d(TAG, "availableHeight: " + availableHeight);
+                Slog.d(TAG, "widthToRemove: " + widthToRemove);
+                Slog.d(TAG, "adjustedCrop: " + adjustedCrop);
+            }
+
+            return adjustedCrop;
+        }
+
+        return adjustedCrop;
+    }
+
+    private boolean isTargetMoreNarrowThanSource(Point targetDisplaySize, Point srcDisplaySize) {
+        float targetScreenRatio = (float) targetDisplaySize.x / targetDisplaySize.y;
+        float srcScreenRatio = (float) srcDisplaySize.x / srcDisplaySize.y;
+
+        return (targetScreenRatio < srcScreenRatio);
+    }
+
     private void logRestoreErrorIfNoLiveComponent(int which, String error) {
         if (mSystemHasLiveComponent) {
             return;
@@ -644,6 +862,7 @@
             mEventLogger.onLockImageWallpaperRestoreFailed(error);
         }
     }
+
     private Rect parseCropHint(File wallpaperInfo, String sectionTag) {
         Rect cropHint = new Rect();
         try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
@@ -681,7 +900,7 @@
                 if (type != XmlPullParser.START_TAG) continue;
                 String tag = parser.getName();
                 if (!sectionTag.equals(tag)) continue;
-                for (Pair<Integer, String> pair: List.of(
+                for (Pair<Integer, String> pair : List.of(
                         new Pair<>(WallpaperManager.PORTRAIT, "Portrait"),
                         new Pair<>(WallpaperManager.LANDSCAPE, "Landscape"),
                         new Pair<>(WallpaperManager.SQUARE_PORTRAIT, "SquarePortrait"),
@@ -907,22 +1126,6 @@
         return internalDisplays;
     }
 
-    /**
-     * This method compares the source and target dimensions, and returns true if there is a
-     * significant difference in area between them and the source dimensions are smaller than the
-     * target dimensions.
-     *
-     * @param sourceDimensions is the dimensions of the source device
-     * @param targetDimensions is the dimensions of the target device
-     */
-    @VisibleForTesting
-    boolean isSourceDeviceSignificantlySmallerThanTarget(Point sourceDimensions,
-            Point targetDimensions) {
-        int rawAreaDelta = (targetDimensions.x * targetDimensions.y)
-                - (sourceDimensions.x * sourceDimensions.y);
-        return rawAreaDelta > AREA_THRESHOLD;
-    }
-
     @VisibleForTesting
     boolean isDeviceInRestore() {
         try {
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index ec9223c..3ecdf3f 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -59,7 +59,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
@@ -841,26 +840,6 @@
         testParseCropHints(testMap);
     }
 
-    @Test
-    public void test_sourceDimensionsAreLargerThanTarget() {
-        // source device is larger than target, expecting to get false
-        Point sourceDimensions = new Point(2208, 1840);
-        Point targetDimensions = new Point(1080, 2092);
-        boolean isSourceSmaller = mWallpaperBackupAgent
-                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
-        assertThat(isSourceSmaller).isEqualTo(false);
-    }
-
-    @Test
-    public void test_sourceDimensionsMuchSmallerThanTarget() {
-        // source device is smaller than target, expecting to get true
-        Point sourceDimensions = new Point(1080, 2092);
-        Point targetDimensions = new Point(2208, 1840);
-        boolean isSourceSmaller = mWallpaperBackupAgent
-                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
-        assertThat(isSourceSmaller).isEqualTo(true);
-    }
-
     private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception {
         assumeTrue(multiCrop());
         mockRestoredStaticWallpaperFile(testMap);
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 7df63b1..11cca66 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -25,15 +25,12 @@
 import static android.Manifest.permission.USE_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.Manifest.permission.USE_FINGERPRINT;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -778,13 +775,7 @@
             hidlConfigs = null;
         }
 
-        if (com.android.server.biometrics.Flags.deHidl()) {
-            registerAuthenticators();
-        } else {
-            // Registers HIDL and AIDL authenticators, but only HIDL configs need to be provided.
-            registerAuthenticators(hidlConfigs);
-        }
-
+        registerAuthenticators();
         mInjector.publishBinderService(this, mImpl);
     }
 
@@ -874,7 +865,7 @@
 
             if (faceService != null) {
                 try {
-                    faceService.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+                    faceService.registerAuthenticators(mFaceSensorConfigurations);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "RemoteException when registering face authenticators", e);
                 }
@@ -912,8 +903,7 @@
 
             if (fingerprintService != null) {
                 try {
-                    fingerprintService.registerAuthenticatorsLegacy(
-                            mFingerprintSensorConfigurations);
+                    fingerprintService.registerAuthenticators(mFingerprintSensorConfigurations);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "RemoteException when registering fingerprint authenticators", e);
                 }
@@ -948,78 +938,6 @@
         return configStrings;
     }
 
-    /**
-     * Registers HIDL and AIDL authenticators for all of the available modalities.
-     *
-     * @param hidlSensors Array of {@link SensorConfig} configuration for all of the HIDL sensors
-     *                    available on the device. This array may contain configuration for
-     *                    different modalities and different sensors of the same modality in
-     *                    arbitrary order. Can be null if no HIDL sensors exist on the device.
-     */
-    private void registerAuthenticators(@Nullable SensorConfig[] hidlSensors) {
-        List<FingerprintSensorPropertiesInternal> hidlFingerprintSensors = new ArrayList<>();
-        List<FaceSensorPropertiesInternal> hidlFaceSensors = new ArrayList<>();
-        // Iris doesn't have IrisSensorPropertiesInternal, using SensorPropertiesInternal instead.
-        List<SensorPropertiesInternal> hidlIrisSensors = new ArrayList<>();
-
-        if (hidlSensors != null) {
-            for (SensorConfig sensor : hidlSensors) {
-                Slog.d(TAG, "Registering HIDL ID: " + sensor.id + " Modality: " + sensor.modality
-                        + " Strength: " + sensor.strength);
-                switch (sensor.modality) {
-                    case TYPE_FINGERPRINT:
-                        hidlFingerprintSensors.add(
-                                getHidlFingerprintSensorProps(sensor.id, sensor.strength));
-                        break;
-
-                    case TYPE_FACE:
-                        hidlFaceSensors.add(getHidlFaceSensorProps(sensor.id, sensor.strength));
-                        break;
-
-                    case TYPE_IRIS:
-                        hidlIrisSensors.add(getHidlIrisSensorProps(sensor.id, sensor.strength));
-                        break;
-
-                    default:
-                        Slog.e(TAG, "Unknown modality: " + sensor.modality);
-                }
-            }
-        }
-
-        final IFingerprintService fingerprintService = mInjector.getFingerprintService();
-        if (fingerprintService != null) {
-            try {
-                fingerprintService.registerAuthenticators(hidlFingerprintSensors);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "RemoteException when registering fingerprint authenticators", e);
-            }
-        } else if (hidlFingerprintSensors.size() > 0) {
-            Slog.e(TAG, "HIDL fingerprint configuration exists, but FingerprintService is null.");
-        }
-
-        final IFaceService faceService = mInjector.getFaceService();
-        if (faceService != null) {
-            try {
-                faceService.registerAuthenticators(hidlFaceSensors);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "RemoteException when registering face authenticators", e);
-            }
-        } else if (hidlFaceSensors.size() > 0) {
-            Slog.e(TAG, "HIDL face configuration exists, but FaceService is null.");
-        }
-
-        final IIrisService irisService = mInjector.getIrisService();
-        if (irisService != null) {
-            try {
-                irisService.registerAuthenticators(hidlIrisSensors);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "RemoteException when registering iris authenticators", e);
-            }
-        } else if (hidlIrisSensors.size() > 0) {
-            Slog.e(TAG, "HIDL iris configuration exists, but IrisService is null.");
-        }
-    }
-
     private void checkInternalPermission() {
         getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
                 "Must have USE_BIOMETRIC_INTERNAL permission");
diff --git a/services/core/java/com/android/server/biometrics/BiometricHandlerProvider.java b/services/core/java/com/android/server/biometrics/BiometricHandlerProvider.java
index e578861..91cabb5 100644
--- a/services/core/java/com/android/server/biometrics/BiometricHandlerProvider.java
+++ b/services/core/java/com/android/server/biometrics/BiometricHandlerProvider.java
@@ -21,7 +21,6 @@
 
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
 
 /**
  * This class provides the handler to process biometric operations.
@@ -76,11 +75,8 @@
     }
 
     private Handler getNewHandler(String tag, int priority) {
-        if (Flags.deHidl()) {
-            HandlerThread handlerThread = new HandlerThread(tag, priority);
-            handlerThread.start();
-            return new Handler(handlerThread.getLooper());
-        }
-        return new Handler(Looper.getMainLooper());
+        HandlerThread handlerThread = new HandlerThread(tag, priority);
+        handlerThread.start();
+        return new Handler(handlerThread.getLooper());
     }
 }
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 7f04628..7a8e25b 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
@@ -81,22 +81,6 @@
     boolean isHardwareIgnoringTouches();
 
     /**
-     * Subscribe to context changes.
-     *
-     * Note that this method only notifies for properties that are visible to the HAL.
-     *
-     * @param context context that will be modified when changed
-     * @param consumer callback when the context is modified
-     *
-     * @deprecated instead use {@link BiometricContext#subscribe(OperationContextExt, Consumer,
-     *                                                           Consumer, AuthenticateOptions)}
-     * TODO (b/294161627): Delete this API once Flags.DE_HIDL is removed.
-     */
-    @Deprecated
-    void subscribe(@NonNull OperationContextExt context,
-            @NonNull Consumer<OperationContext> consumer);
-
-    /**
      * Subscribe to context changes and start the HAL operation.
      *
      * Note that this method only notifies for properties that are visible to the HAL.
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 d8dfa60..a17de3d 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
@@ -229,16 +229,6 @@
 
     @Override
     public void subscribe(@NonNull OperationContextExt context,
-            @NonNull Consumer<OperationContext> consumer) {
-        mSubscribers.put(context, consumer);
-        // TODO(b/294161627) Combine the getContext/subscribe APIs to avoid race
-        if (context.getDisplayState() != getDisplayState()) {
-            consumer.accept(context.update(this, context.isCrypto()).toAidlContext());
-        }
-    }
-
-    @Override
-    public void subscribe(@NonNull OperationContextExt context,
             @NonNull Consumer<OperationContext> startHalConsumer,
             @NonNull Consumer<OperationContext> updateContextConsumer,
             @Nullable AuthenticateOptions options) {
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 4fa8741..1e2451c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -35,7 +35,6 @@
 import android.util.Slog;
 
 import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -117,24 +116,20 @@
 
     @LockoutTracker.LockoutMode
     public int handleFailedAttempt(int userId) {
-        if (Flags.deHidl()) {
-            if (mLockoutTracker != null) {
-                mLockoutTracker.addFailedAttemptForUser(getTargetUserId());
-            }
-            @LockoutTracker.LockoutMode final int lockoutMode =
-                    getLockoutTracker().getLockoutModeForUser(userId);
-            final PerformanceTracker performanceTracker =
-                    PerformanceTracker.getInstanceForSensorId(getSensorId());
-            if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
-                performanceTracker.incrementPermanentLockoutForUser(userId);
-            } else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
-                performanceTracker.incrementTimedLockoutForUser(userId);
-            }
-
-            return lockoutMode;
-        } else {
-            return LockoutTracker.LOCKOUT_NONE;
+        if (mLockoutTracker != null) {
+            mLockoutTracker.addFailedAttemptForUser(getTargetUserId());
         }
+        @LockoutTracker.LockoutMode final int lockoutMode =
+                getLockoutTracker().getLockoutModeForUser(userId);
+        final PerformanceTracker performanceTracker =
+                PerformanceTracker.getInstanceForSensorId(getSensorId());
+        if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
+            performanceTracker.incrementPermanentLockoutForUser(userId);
+        } else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
+            performanceTracker.incrementTimedLockoutForUser(userId);
+        }
+
+        return lockoutMode;
     }
 
     protected long getStartTimeMs() {
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 89e08c1..82d5d4d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -19,9 +19,9 @@
 import static com.android.server.biometrics.sensors.BiometricSchedulerOperation.STATE_STARTED;
 
 import android.annotation.IntDef;
-import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.WorkerThread;
 import android.content.Context;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -38,7 +38,6 @@
 import com.android.modules.expresslog.Counter;
 import com.android.server.biometrics.BiometricSchedulerProto;
 import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
 
 import java.io.PrintWriter;
@@ -65,9 +64,8 @@
  * @param <T> Hal instance for starting the user.
  * @param <U> Session associated with the current user id.
  *
- * TODO: (b/304604965) Update thread annotation when FLAGS_DE_HIDL is removed.
  */
-@MainThread
+@WorkerThread
 public class BiometricScheduler<T, U> {
 
     private static final String TAG = "BiometricScheduler";
@@ -176,7 +174,7 @@
                     Slog.w(TAG, "operation is already null or different (reset?): "
                             + mCurrentOperation);
                 }
-                startNextOperationIfIdle();
+                checkCurrentUserAndStartNextOperation();
             });
         }
     }
@@ -219,7 +217,7 @@
                 mRecentOperations.add(mCurrentOperation.getProtoEnum());
                 mCurrentOperation = null;
                 mTotalOperationsHandled++;
-                startNextOperationIfIdle();
+                checkCurrentUserAndStartNextOperation();
             });
         }
     };
@@ -304,15 +302,7 @@
         return mInternalCallback;
     }
 
-    protected void startNextOperationIfIdle() {
-        if (Flags.deHidl()) {
-            startNextOperation();
-        } else {
-            startNextOperationIfIdleLegacy();
-        }
-    }
-
-    protected void startNextOperation() {
+    protected void checkCurrentUserAndStartNextOperation() {
         if (mCurrentOperation != null) {
             Slog.v(TAG, "Not idle, current operation: " + mCurrentOperation);
             return;
@@ -326,7 +316,7 @@
         final int nextUserId = mPendingOperations.getFirst().getTargetUserId();
 
         if (nextUserId == currentUserId || mPendingOperations.getFirst().isStartUserOperation()) {
-            startNextOperationIfIdleLegacy();
+            startNextOperationIfIdle();
         } else if (currentUserId == UserHandle.USER_NULL && mUserSwitchProvider != null) {
             final BaseClientMonitor startClient =
                     mUserSwitchProvider.getStartUserClient(nextUserId);
@@ -357,7 +347,7 @@
         }
     }
 
-    protected void startNextOperationIfIdleLegacy() {
+    protected void startNextOperationIfIdle() {
         if (mCurrentOperation != null) {
             Slog.v(TAG, "Not idle, current operation: " + mCurrentOperation);
             return;
@@ -422,7 +412,7 @@
                 // run these. A single request from the manager layer to the service layer may
                 // actually be multiple operations (i.e. updateActiveUser + authenticate).
                 mCurrentOperation = null;
-                startNextOperationIfIdle();
+                checkCurrentUserAndStartNextOperation();
             }
         } else {
             try {
@@ -459,7 +449,7 @@
         } else {
             Slog.e(TAG, "[Unable To Start] Prepared client: " + mCurrentOperation);
             mCurrentOperation = null;
-            startNextOperationIfIdle();
+            checkCurrentUserAndStartNextOperation();
         }
     }
 
@@ -504,7 +494,7 @@
             Slog.d(TAG, "[Cancelling Interruptable]: " + mCurrentOperation);
             mCurrentOperation.cancel(mHandler, mInternalCallback);
         } else {
-            startNextOperationIfIdle();
+            checkCurrentUserAndStartNextOperation();
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
deleted file mode 100644
index 7ca10e3..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ /dev/null
@@ -1,183 +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.BiometricSchedulerOperation.STATE_STARTED;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.IBiometricService;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
-
-/**
- * A user-aware scheduler that requests user-switches based on scheduled operation's targetUserId.
- * TODO (b/304604965): Remove class when Flags.FLAG_DE_HIDL is removed.
- *
- * @param <T> Hal instance for starting the user.
- * @param <U> Session associated with the current user id.
- */
-public class UserAwareBiometricScheduler<T, U> extends BiometricScheduler<T, U> {
-
-    private static final String TAG = "UaBiometricScheduler";
-
-    /**
-     * Interface to retrieve the owner's notion of the current userId. Note that even though
-     * the scheduler can determine this based on its history of processed clients, we should still
-     * query the owner since it may be cleared due to things like HAL death, etc.
-     */
-    public interface CurrentUserRetriever {
-        int getCurrentUserId();
-    }
-
-    public interface UserSwitchCallback {
-        @NonNull StopUserClient<?> getStopUserClient(int userId);
-        @NonNull StartUserClient<?, ?> getStartUserClient(int newUserId);
-    }
-
-    @NonNull private final CurrentUserRetriever mCurrentUserRetriever;
-    @NonNull private final UserSwitchCallback mUserSwitchCallback;
-    @Nullable private StopUserClient<?> mStopUserClient;
-
-    private class ClientFinishedCallback implements ClientMonitorCallback {
-        @NonNull private final BaseClientMonitor mOwner;
-
-        ClientFinishedCallback(@NonNull BaseClientMonitor owner) {
-            mOwner = owner;
-        }
-
-        @Override
-        public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
-            mHandler.post(() -> {
-                Slog.d(TAG, "[Client finished] " + clientMonitor + ", success: " + success);
-
-                // Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
-                // for that the queue will wait indefinitely until the field is cleared.
-                if (clientMonitor instanceof StopUserClient<?>) {
-                    if (!success) {
-                        Slog.w(TAG, "StopUserClient failed(), is the HAL stuck? "
-                                + "Clearing mStopUserClient");
-                    }
-                    mStopUserClient = null;
-                }
-                if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
-                    mCurrentOperation = null;
-                } else {
-                    // can happen if the hal dies and is usually okay
-                    // do not unset the current operation that may be newer
-                    Slog.w(TAG, "operation is already null or different (reset?): "
-                            + mCurrentOperation);
-                }
-                startNextOperationIfIdle();
-            });
-        }
-    }
-
-    @VisibleForTesting
-    public UserAwareBiometricScheduler(@NonNull String tag,
-            @NonNull Handler handler,
-            @SensorType int sensorType,
-            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
-            @NonNull IBiometricService biometricService,
-            @NonNull CurrentUserRetriever currentUserRetriever,
-            @NonNull UserSwitchCallback userSwitchCallback) {
-        super(handler, sensorType, gestureAvailabilityDispatcher, biometricService,
-                LOG_NUM_RECENT_OPERATIONS);
-
-        mCurrentUserRetriever = currentUserRetriever;
-        mUserSwitchCallback = userSwitchCallback;
-    }
-
-    public UserAwareBiometricScheduler(@NonNull String tag,
-            @SensorType int sensorType,
-            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
-            @NonNull CurrentUserRetriever currentUserRetriever,
-            @NonNull UserSwitchCallback userSwitchCallback) {
-        this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher,
-                IBiometricService.Stub.asInterface(
-                        ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
-                currentUserRetriever, userSwitchCallback);
-    }
-
-    @Override
-    protected void startNextOperationIfIdle() {
-        if (mCurrentOperation != null) {
-            Slog.v(TAG, "Not idle, current operation: " + mCurrentOperation);
-            return;
-        }
-        if (mPendingOperations.isEmpty()) {
-            Slog.d(TAG, "No operations, returning to idle");
-            return;
-        }
-
-        final int currentUserId = mCurrentUserRetriever.getCurrentUserId();
-        final int nextUserId = mPendingOperations.getFirst().getTargetUserId();
-
-        if (nextUserId == currentUserId || mPendingOperations.getFirst().isStartUserOperation()) {
-            super.startNextOperationIfIdle();
-        } else if (currentUserId == UserHandle.USER_NULL) {
-            final BaseClientMonitor startClient =
-                    mUserSwitchCallback.getStartUserClient(nextUserId);
-            final ClientFinishedCallback finishedCallback =
-                    new ClientFinishedCallback(startClient);
-
-            Slog.d(TAG, "[Starting User] " + startClient);
-            mCurrentOperation = new BiometricSchedulerOperation(
-                    startClient, finishedCallback, STATE_STARTED);
-            startClient.start(finishedCallback);
-        } else {
-            if (mStopUserClient != null) {
-                Slog.d(TAG, "[Waiting for StopUser] " + mStopUserClient);
-            } else {
-                mStopUserClient = mUserSwitchCallback
-                        .getStopUserClient(currentUserId);
-                final ClientFinishedCallback finishedCallback =
-                        new ClientFinishedCallback(mStopUserClient);
-
-                Slog.d(TAG, "[Stopping User] current: " + currentUserId
-                        + ", next: " + nextUserId + ". " + mStopUserClient);
-                mCurrentOperation = new BiometricSchedulerOperation(
-                        mStopUserClient, finishedCallback, STATE_STARTED);
-                mStopUserClient.start(finishedCallback);
-            }
-        }
-    }
-
-    @Override
-    public void onUserStopped() {
-        if (mStopUserClient == null) {
-            Slog.e(TAG, "Unexpected onUserStopped");
-            return;
-        }
-
-        Slog.d(TAG, "[OnUserStopped]: " + mStopUserClient);
-        mStopUserClient.onUserStopped();
-        mStopUserClient = null;
-    }
-
-    @VisibleForTesting
-    @Nullable public StopUserClient<?> getStopUserClient() {
-        return mStopUserClient;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index a946af8..bd6d593 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -72,9 +72,6 @@
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.face.aidl.FaceProvider;
-import com.android.server.biometrics.sensors.face.hidl.Face10;
-
-import com.google.android.collect.Lists;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -664,60 +661,11 @@
             provider.second.scheduleGetFeature(provider.first, token, userId, feature,
                     new ClientMonitorCallbackConverter(receiver), opPackageName);
         }
-        @NonNull
-        private List<ServiceProvider> getHidlProviders(
-                @NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
-            final List<ServiceProvider> providers = new ArrayList<>();
-
-            for (FaceSensorPropertiesInternal hidlSensor : hidlSensors) {
-                providers.add(
-                        Face10.newInstance(getContext(), mBiometricStateCallback,
-                                mAuthenticationStateListeners, hidlSensor,
-                                mLockoutResetDispatcher));
-            }
-
-            return providers;
-        }
-
-        @NonNull
-        private List<ServiceProvider> getAidlProviders(@NonNull List<String> instances) {
-            final List<ServiceProvider> providers = new ArrayList<>();
-
-            for (String instance : instances) {
-                final FaceProvider provider = mFaceProvider.apply(instance);
-                Slog.i(TAG, "Adding AIDL provider: " + instance);
-                providers.add(provider);
-            }
-
-            return providers;
-        }
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         public void registerAuthenticators(
-                @NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
-            super.registerAuthenticators_enforcePermission();
-
-            mRegistry.registerAll(() -> {
-                List<String> aidlSensors = new ArrayList<>();
-                final String[] instances = mAidlInstanceNameSupplier.get();
-                if (instances != null) {
-                    aidlSensors.addAll(Lists.newArrayList(instances));
-                }
-
-                final Pair<List<FaceSensorPropertiesInternal>, List<String>>
-                        filteredInstances = filterAvailableHalInstances(hidlSensors, aidlSensors);
-
-                final List<ServiceProvider> providers = new ArrayList<>();
-                providers.addAll(getHidlProviders(filteredInstances.first));
-                providers.addAll(getAidlProviders(filteredInstances.second));
-                return providers;
-            });
-        }
-
-        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
-        public void registerAuthenticatorsLegacy(
                 FaceSensorConfigurations faceSensorConfigurations) {
-            super.registerAuthenticatorsLegacy_enforcePermission();
+            super.registerAuthenticators_enforcePermission();
 
             if (!faceSensorConfigurations.hasSensorConfigurations()) {
                 Slog.d(TAG, "No face sensors to register.");
@@ -771,40 +719,6 @@
                     .getSensorPropForInstance(finalSensorInstance));
         }
 
-        private Pair<List<FaceSensorPropertiesInternal>, List<String>>
-                filterAvailableHalInstances(
-                @NonNull List<FaceSensorPropertiesInternal> hidlInstances,
-                @NonNull List<String> aidlInstances) {
-            if ((hidlInstances.size() + aidlInstances.size()) <= 1) {
-                return new Pair(hidlInstances, aidlInstances);
-            }
-
-            if (Flags.faceVhalFeature()) {
-                Slog.i(TAG, "Face VHAL feature is on");
-            } else {
-                Slog.i(TAG, "Face VHAL feature is off");
-            }
-
-            final int virtualAt = aidlInstances.indexOf("virtual");
-            if (Flags.faceVhalFeature() && Utils.isFaceVirtualEnabled(getContext())) {
-                if (virtualAt != -1) {
-                    //only virtual instance should be returned
-                    Slog.i(TAG, "virtual hal is used");
-                    return new Pair(new ArrayList<>(), List.of(aidlInstances.get(virtualAt)));
-                } else {
-                    Slog.e(TAG, "Could not find virtual interface while it is enabled");
-                    return new Pair(hidlInstances, aidlInstances);
-                }
-            } else {
-                //remove virtual instance
-                aidlInstances = new ArrayList<>(aidlInstances);
-                if (virtualAt != -1) {
-                    aidlInstances.remove(virtualAt);
-                }
-                return new Pair(hidlInstances, aidlInstances);
-            }
-        }
-
         @Override
         public void addAuthenticatorsRegisteredCallback(
                 IFaceAuthenticatorsRegisteredCallback callback) {
@@ -883,17 +797,13 @@
             return null;
         };
 
-        if (Flags.deHidl()) {
-            mFaceProviderFunction = faceProviderFunction != null ? faceProviderFunction :
-                    ((filteredSensorProps, resetLockoutRequiresChallenge) -> new FaceProvider(
-                            getContext(), mBiometricStateCallback, mAuthenticationStateListeners,
-                            filteredSensorProps.second,
-                            filteredSensorProps.first, mLockoutResetDispatcher,
-                            BiometricContext.getInstance(getContext()),
-                            resetLockoutRequiresChallenge));
-        } else {
-            mFaceProviderFunction = ((filteredSensorProps, resetLockoutRequiresChallenge) -> null);
-        }
+        mFaceProviderFunction = faceProviderFunction != null ? faceProviderFunction :
+                ((filteredSensorProps, resetLockoutRequiresChallenge) -> new FaceProvider(
+                        getContext(), mBiometricStateCallback, mAuthenticationStateListeners,
+                        filteredSensorProps.second,
+                        filteredSensorProps.first, mLockoutResetDispatcher,
+                        BiometricContext.getInstance(getContext()),
+                        resetLockoutRequiresChallenge));
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlResponseHandler.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlResponseHandler.java
index 098be21..cf677d5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlResponseHandler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlResponseHandler.java
@@ -27,7 +27,6 @@
 import android.hardware.keymaster.HardwareAuthToken;
 import android.util.Slog;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.HardwareAuthTokenUtils;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.AcquisitionClient;
@@ -53,16 +52,6 @@
     /**
      * Interface to send results to the AidlResponseHandler's owner.
      */
-    public interface HardwareUnavailableCallback {
-        /**
-         * Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
-         */
-        void onHardwareUnavailable();
-    }
-
-    /**
-     * Interface to send results to the AidlResponseHandler's owner.
-     */
     public interface AidlResponseHandlerCallback {
         /**
          * Invoked when enrollment is successful.
@@ -90,8 +79,6 @@
     @NonNull
     private final AuthSessionCoordinator mAuthSessionCoordinator;
     @NonNull
-    private final HardwareUnavailableCallback mHardwareUnavailableCallback;
-    @NonNull
     private final AidlResponseHandlerCallback mAidlResponseHandlerCallback;
 
     public AidlResponseHandler(@NonNull Context context,
@@ -99,24 +86,6 @@
             @NonNull LockoutTracker lockoutTracker,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             @NonNull AuthSessionCoordinator authSessionCoordinator,
-            @NonNull HardwareUnavailableCallback hardwareUnavailableCallback) {
-        this(context, scheduler, sensorId, userId, lockoutTracker, lockoutResetDispatcher,
-                authSessionCoordinator, hardwareUnavailableCallback,
-                new AidlResponseHandlerCallback() {
-                    @Override
-                    public void onEnrollSuccess() {}
-
-                    @Override
-                    public void onHardwareUnavailable() {}
-                });
-    }
-
-    public AidlResponseHandler(@NonNull Context context,
-            @NonNull BiometricScheduler scheduler, int sensorId, int userId,
-            @NonNull LockoutTracker lockoutTracker,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull AuthSessionCoordinator authSessionCoordinator,
-            @NonNull HardwareUnavailableCallback hardwareUnavailableCallback,
             @NonNull AidlResponseHandlerCallback aidlResponseHandlerCallback) {
         mContext = context;
         mScheduler = scheduler;
@@ -125,7 +94,6 @@
         mLockoutTracker = lockoutTracker;
         mLockoutResetDispatcher = lockoutResetDispatcher;
         mAuthSessionCoordinator = authSessionCoordinator;
-        mHardwareUnavailableCallback = hardwareUnavailableCallback;
         mAidlResponseHandlerCallback = aidlResponseHandlerCallback;
     }
 
@@ -185,11 +153,7 @@
         handleResponse(ErrorConsumer.class, (c) -> {
             c.onError(error, vendorCode);
             if (error == Error.HW_UNAVAILABLE) {
-                if (Flags.deHidl()) {
-                    mAidlResponseHandlerCallback.onHardwareUnavailable();
-                } else {
-                    mHardwareUnavailableCallback.onHardwareUnavailable();
-                }
+                mAidlResponseHandlerCallback.onHardwareUnavailable();
             }
         });
     }
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 415d294..c43c7d9 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
@@ -20,7 +20,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.NotificationManager;
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.SensorPrivacyManager;
@@ -39,7 +38,6 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -70,8 +68,6 @@
     private final UsageStats mUsageStats;
     @NonNull
     private final AuthSessionCoordinator mAuthSessionCoordinator;
-    @Nullable
-    private final NotificationManager mNotificationManager;
     private final int[] mBiometricPromptIgnoreList;
     private final int[] mBiometricPromptIgnoreListVendor;
     private final int[] mKeyguardIgnoreList;
@@ -123,7 +119,6 @@
                 biometricStrength);
         setRequestId(requestId);
         mUsageStats = usageStats;
-        mNotificationManager = context.getSystemService(NotificationManager.class);
         mSensorPrivacyManager = sensorPrivacyManager;
         mAuthSessionCoordinator = biometricContext.getAuthSessionCoordinator();
         mAuthenticationStateListeners = authenticationStateListeners;
@@ -163,11 +158,7 @@
                         0 /* vendorCode */);
                 mCallback.onClientFinished(this, false /* success */);
             } else {
-                if (Flags.deHidl()) {
-                    startAuthenticate();
-                } else {
-                    mCancellationSignal = doAuthenticate();
-                }
+                doAuthenticate();
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting auth", e);
@@ -176,27 +167,7 @@
         }
     }
 
-    private ICancellationSignal doAuthenticate() throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-
-        if (session.hasContextMethods()) {
-            final OperationContextExt opContext = getOperationContext();
-            final ICancellationSignal cancel = session.getSession().authenticateWithContext(
-                    mOperationId, opContext.toAidlContext(getOptions()));
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
-            return cancel;
-        } else {
-            return session.getSession().authenticate(mOperationId);
-        }
-    }
-
-    private void startAuthenticate() throws RemoteException {
+    private void doAuthenticate() throws RemoteException {
         final AidlSession session = getFreshDaemon();
 
         if (session.hasContextMethods()) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index 5ddddda..dcd94896 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -29,7 +29,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -112,38 +111,14 @@
         }
 
         try {
-            if (Flags.deHidl()) {
-                startDetect();
-            } else {
-                mCancellationSignal = doDetectInteraction();
-            }
+            doDetectInteraction();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting face detect", e);
             mCallback.onClientFinished(this, false /* success */);
         }
     }
 
-    private ICancellationSignal doDetectInteraction() throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-
-        if (session.hasContextMethods()) {
-            final OperationContextExt opContext = getOperationContext();
-            final ICancellationSignal cancel = session.getSession().detectInteractionWithContext(
-                    opContext.toAidlContext(mOptions));
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
-            return cancel;
-        } else {
-            return session.getSession().detectInteraction();
-        }
-    }
-
-    private void startDetect() throws RemoteException {
+    private void doDetectInteraction() throws RemoteException {
         final AidlSession session = getFreshDaemon();
 
         if (session.hasContextMethods()) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
index 781e3f4..73e8ece 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
@@ -36,7 +36,6 @@
 import android.view.Surface;
 
 import com.android.internal.R;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.HardwareAuthTokenUtils;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
@@ -193,11 +192,7 @@
                 features[i] = featureList.get(i);
             }
 
-            if (Flags.deHidl()) {
-                startEnroll(features);
-            } else {
-                mCancellationSignal = doEnroll(features);
-            }
+            doEnroll(features);
         } catch (RemoteException | IllegalArgumentException e) {
             Slog.e(TAG, "Exception when requesting enroll", e);
             onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
@@ -205,43 +200,7 @@
         }
     }
 
-    private ICancellationSignal doEnroll(byte[] features) throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-        final HardwareAuthToken hat =
-                HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
-
-        if (session.hasContextMethods()) {
-            final OperationContextExt opContext = getOperationContext();
-            ICancellationSignal cancel;
-            if (session.supportsFaceEnrollOptions()) {
-                FaceEnrollOptions options = new FaceEnrollOptions();
-                options.hardwareAuthToken = hat;
-                options.enrollmentType = EnrollmentType.DEFAULT;
-                options.features = features;
-                options.nativeHandlePreview = null;
-                options.context = opContext.toAidlContext();
-                options.surfacePreview = mPreviewSurface;
-                cancel = session.getSession().enrollWithOptions(options);
-            } else {
-                cancel = session.getSession().enrollWithContext(
-                        hat, EnrollmentType.DEFAULT, features, mHwPreviewHandle,
-                        opContext.toAidlContext());
-            }
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
-            return cancel;
-        } else {
-            return session.getSession().enroll(hat, EnrollmentType.DEFAULT, features,
-                    mHwPreviewHandle);
-        }
-    }
-
-    private void startEnroll(byte[] features) throws RemoteException {
+    private void doEnroll(byte[] features) throws RemoteException {
         final AidlSession session = getFreshDaemon();
         final HardwareAuthToken hat =
                 HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 11db183..75b4fd3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -27,11 +27,9 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.biometrics.common.ComponentInfo;
 import android.hardware.biometrics.face.IFace;
 import android.hardware.biometrics.face.SensorProps;
 import android.hardware.face.Face;
@@ -43,7 +41,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -56,7 +53,6 @@
 import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
 import com.android.server.biometrics.AuthenticationStatsCollector;
 import com.android.server.biometrics.BiometricHandlerProvider;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -193,11 +189,7 @@
         mAuthenticationStateListeners = authenticationStateListeners;
         mHalInstanceName = halInstanceName;
         mFaceSensors = new SensorList<>(ActivityManager.getService());
-        if (Flags.deHidl()) {
-            mHandler = biometricHandlerProvider.getFaceHandler();
-        } else {
-            mHandler = new Handler(Looper.getMainLooper());
-        }
+        mHandler = biometricHandlerProvider.getFaceHandler();
         mUsageStats = new UsageStats(context);
         mLockoutResetDispatcher = lockoutResetDispatcher;
         mActivityTaskManager = ActivityTaskManager.getInstance();
@@ -223,50 +215,15 @@
     }
 
     private void initSensors(boolean resetLockoutRequiresChallenge, SensorProps[] props) {
-        if (Flags.deHidl()) {
-            if (resetLockoutRequiresChallenge) {
-                Slog.d(getTag(), "Adding HIDL configs");
-                for (SensorProps prop : props) {
-                    addHidlSensors(prop, resetLockoutRequiresChallenge);
-                }
-            } else {
-                Slog.d(getTag(), "Adding AIDL configs");
-                for (SensorProps prop : props) {
-                    addAidlSensors(prop, resetLockoutRequiresChallenge);
-                }
+        if (resetLockoutRequiresChallenge) {
+            Slog.d(getTag(), "Adding HIDL configs");
+            for (SensorProps prop : props) {
+                addHidlSensors(prop, resetLockoutRequiresChallenge);
             }
         } else {
+            Slog.d(getTag(), "Adding AIDL configs");
             for (SensorProps prop : props) {
-                final int sensorId = prop.commonProps.sensorId;
-
-                final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-                if (prop.commonProps.componentInfo != null) {
-                    for (ComponentInfo info : prop.commonProps.componentInfo) {
-                        componentInfo.add(new ComponentInfoInternal(info.componentId,
-                                info.hardwareVersion, info.firmwareVersion, info.serialNumber,
-                                info.softwareVersion));
-                    }
-                }
-
-                final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
-                        prop.commonProps.sensorId, prop.commonProps.sensorStrength,
-                        prop.commonProps.maxEnrollmentsPerUser, componentInfo, prop.sensorType,
-                        prop.supportsDetectInteraction, prop.halControlsPreview,
-                        false /* resetLockoutRequiresChallenge */);
-                final Sensor sensor = new Sensor(this,
-                        mContext, mHandler, internalProp,
-                        mBiometricContext);
-                sensor.init(mLockoutResetDispatcher, this);
-                final int userId = sensor.getLazySession().get() == null ? UserHandle.USER_NULL :
-                        sensor.getLazySession().get().getUserId();
-                mFaceSensors.addSensor(sensorId, sensor, userId,
-                        new SynchronousUserSwitchObserver() {
-                            @Override
-                            public void onUserSwitching(int newUserId) {
-                                scheduleInternalCleanup(sensorId, newUserId, null /* callback */);
-                            }
-                        });
-                Slog.d(getTag(), "Added: " + internalProp);
+                addAidlSensors(prop, resetLockoutRequiresChallenge);
             }
         }
     }
@@ -477,12 +434,7 @@
 
     @Override
     public int getLockoutModeForUser(int sensorId, int userId) {
-        if (Flags.deHidl()) {
-            return mFaceSensors.get(sensorId).getLockoutModeForUser(userId);
-        } else {
-            return mBiometricContext.getAuthSessionCoordinator().getLockoutStateFor(userId,
-                    Utils.getCurrentStrength(sensorId));
-        }
+        return mFaceSensors.get(sensorId).getLockoutModeForUser(userId);
     }
 
     @Override
@@ -492,11 +444,7 @@
 
     @Override
     public boolean isHardwareDetected(int sensorId) {
-        if (Flags.deHidl()) {
-            return mFaceSensors.get(sensorId).isHardwareDetected(mHalInstanceName);
-        } else {
-            return hasHalInstance();
-        }
+        return mFaceSensors.get(sensorId).isHardwareDetected(mHalInstanceName);
     }
 
     @Override
@@ -549,23 +497,7 @@
                             BiometricsProtoEnums.CLIENT_UNKNOWN,
                             mAuthenticationStatsCollector),
                     mBiometricContext, maxTemplatesPerUser, debugConsent, options);
-            if (Flags.deHidl()) {
-                scheduleForSensor(sensorId, client, mBiometricStateCallback);
-            } else {
-                scheduleForSensor(sensorId, client, new ClientMonitorCompositeCallback(
-                        mBiometricStateCallback, new ClientMonitorCallback() {
-                            @Override
-                            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                                    boolean success) {
-                                ClientMonitorCallback.super.onClientFinished(clientMonitor,
-                                        success);
-                                if (success) {
-                                    scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
-                                    scheduleInvalidationRequest(sensorId, userId);
-                                }
-                            }
-                        }));
-            }
+            scheduleForSensor(sensorId, client, mBiometricStateCallback);
         });
         return id;
     }
@@ -614,12 +546,8 @@
             final int sensorId = options.getSensorId();
             final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
             mFaceSensors.get(sensorId).scheduleFaceUpdateActiveUserClient(userId);
-            final LockoutTracker lockoutTracker;
-            if (Flags.deHidl()) {
-                lockoutTracker = mFaceSensors.get(sensorId).getLockoutTracker(true /* forAuth */);
-            } else {
-                lockoutTracker = null;
-            }
+            final LockoutTracker lockoutTracker = mFaceSensors.get(sensorId).getLockoutTracker(
+                    true /* forAuth */);
             final FaceAuthenticationClient client = new FaceAuthenticationClient(
                     mContext, mFaceSensors.get(sensorId).getLazySession(), token, requestId,
                     callback, operationId, restricted, options, cookie,
@@ -634,29 +562,18 @@
                 @Override
                 public void onClientStarted(
                          BaseClientMonitor clientMonitor) {
-                    if (Flags.deHidl()) {
-                        mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
-                                mAuthSessionCoordinator.authStartedFor(userId, sensorId,
-                                        requestId));
-                    } else {
-                        mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId);
-                    }
+                    mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
+                            mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId));
                 }
 
                 @Override
                 public void onClientFinished(
                         BaseClientMonitor clientMonitor,
                         boolean success) {
-                    if (Flags.deHidl()) {
-                        mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
-                                mAuthSessionCoordinator.authEndedFor(userId,
-                                        Utils.getCurrentStrength(sensorId), sensorId, requestId,
-                                        client.wasAuthSuccessful()));
-                    } else {
-                        mAuthSessionCoordinator.authEndedFor(userId,
-                                Utils.getCurrentStrength(sensorId),
-                                sensorId, requestId, client.wasAuthSuccessful());
-                    }
+                    mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
+                            mAuthSessionCoordinator.authEndedFor(userId,
+                                    Utils.getCurrentStrength(sensorId), sensorId, requestId,
+                                    client.wasAuthSuccessful()));
                 }
             });
         });
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index 635e79a..6b99493 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -42,7 +42,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.SensorServiceStateProto;
 import com.android.server.biometrics.SensorStateProto;
 import com.android.server.biometrics.UserStateProto;
@@ -57,7 +56,6 @@
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.StartUserClient;
 import com.android.server.biometrics.sensors.StopUserClient;
-import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.UserSwitchProvider;
 import com.android.server.biometrics.sensors.face.FaceUtils;
 
@@ -89,7 +87,6 @@
     @Nullable AidlSession mCurrentSession;
     @NonNull BiometricContext mBiometricContext;
 
-
     Sensor(@NonNull FaceProvider provider, @NonNull Context context,
             @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
             @NonNull BiometricContext biometricContext) {
@@ -116,11 +113,7 @@
      */
     public void init(@NonNull LockoutResetDispatcher lockoutResetDispatcher,
             @NonNull FaceProvider provider) {
-        if (Flags.deHidl()) {
-            setScheduler(getBiometricSchedulerForInit(lockoutResetDispatcher, provider));
-        } else {
-            setScheduler(getUserAwareBiometricSchedulerForInit(lockoutResetDispatcher, provider));
-        }
+        setScheduler(getBiometricSchedulerForInit(lockoutResetDispatcher, provider));
         mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
         mLockoutTracker = new LockoutCache();
     }
@@ -149,8 +142,7 @@
                         final AidlResponseHandler resultController = new AidlResponseHandler(
                                 mContext, mScheduler, sensorId, newUserId,
                                 mLockoutTracker, lockoutResetDispatcher,
-                                mBiometricContext.getAuthSessionCoordinator(), () -> {
-                        },
+                                mBiometricContext.getAuthSessionCoordinator(),
                                 new AidlResponseHandler.AidlResponseHandlerCallback() {
                                     @Override
                                     public void onEnrollSuccess() {
@@ -173,40 +165,6 @@
                 });
     }
 
-    private UserAwareBiometricScheduler<IFace, ISession> getUserAwareBiometricSchedulerForInit(
-            LockoutResetDispatcher lockoutResetDispatcher,
-            FaceProvider provider) {
-        return new UserAwareBiometricScheduler<>(TAG,
-                BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityDispatcher */,
-                () -> mCurrentSession != null ? mCurrentSession.getUserId() : UserHandle.USER_NULL,
-                new UserAwareBiometricScheduler.UserSwitchCallback() {
-                    @NonNull
-                    @Override
-                    public StopUserClient<ISession> getStopUserClient(int userId) {
-                        return new FaceStopUserClient(mContext,
-                                () -> mLazySession.get().getSession(), mToken, userId,
-                                mSensorProperties.sensorId, BiometricLogger.ofUnknown(mContext),
-                                mBiometricContext, () -> mCurrentSession = null);
-                    }
-
-                    @NonNull
-                    @Override
-                    public StartUserClient<IFace, ISession> getStartUserClient(int newUserId) {
-                        final int sensorId = mSensorProperties.sensorId;
-                        final AidlResponseHandler resultController = new AidlResponseHandler(
-                                mContext, mScheduler, sensorId, newUserId,
-                                mLockoutTracker, lockoutResetDispatcher,
-                                mBiometricContext.getAuthSessionCoordinator(), () -> {
-                                    Slog.e(TAG, "Face sensor hardware unavailable.");
-                                    mCurrentSession = null;
-                                });
-
-                        return Sensor.this.getStartUserClient(resultController, sensorId,
-                                newUserId, provider);
-                    }
-                });
-    }
-
     private FaceStartUserClient getStartUserClient(@NonNull AidlResponseHandler resultController,
             int sensorId, int newUserId, @NonNull FaceProvider provider) {
         final StartUserClient.UserStartedCallback<ISession> userStartedCallback =
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
deleted file mode 100644
index 0e2367a..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.ITestSession;
-import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.face.Face;
-import android.hardware.face.FaceAuthenticationFrame;
-import android.hardware.face.FaceEnrollFrame;
-import android.hardware.face.FaceEnrollOptions;
-import android.hardware.face.IFaceServiceReceiver;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.face.FaceUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-
-public class BiometricTestSessionImpl extends ITestSession.Stub {
-    private static final String TAG = "BiometricTestSessionImpl";
-
-    @NonNull private final Context mContext;
-    private final int mSensorId;
-    @NonNull private final ITestSessionCallback mCallback;
-    @NonNull private final Face10 mFace10;
-    @NonNull private final Face10.HalResultController mHalResultController;
-    @NonNull private final Set<Integer> mEnrollmentIds;
-    @NonNull private final Random mRandom;
-
-
-    private final IFaceServiceReceiver mReceiver = new IFaceServiceReceiver.Stub() {
-        @Override
-        public void onEnrollResult(Face face, int remaining) {
-
-        }
-
-        @Override
-        public void onAcquired(int acquiredInfo, int vendorCode) {
-
-        }
-
-        @Override
-        public void onAuthenticationSucceeded(Face face, int userId, boolean isStrongBiometric) {
-
-        }
-
-        @Override
-        public void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric) {
-
-        }
-
-        @Override
-        public void onAuthenticationFailed() {
-
-        }
-
-        @Override
-        public void onError(int error, int vendorCode) {
-
-        }
-
-        @Override
-        public void onRemoved(Face face, int remaining) {
-
-        }
-
-        @Override
-        public void onFeatureSet(boolean success, int feature) {
-
-        }
-
-        @Override
-        public void onFeatureGet(boolean success, int[] features, boolean[] featureState) {
-
-        }
-
-        @Override
-        public void onChallengeGenerated(int sensorId, int userId, long challenge) {
-
-        }
-
-        @Override
-        public void onAuthenticationFrame(FaceAuthenticationFrame frame) {
-
-        }
-
-        @Override
-        public void onEnrollmentFrame(FaceEnrollFrame frame) {
-
-        }
-    };
-
-    BiometricTestSessionImpl(@NonNull Context context, int sensorId,
-            @NonNull ITestSessionCallback callback,
-            @NonNull Face10 face10,
-            @NonNull Face10.HalResultController halResultController) {
-        mContext = context;
-        mSensorId = sensorId;
-        mCallback = callback;
-        mFace10 = face10;
-        mHalResultController = halResultController;
-        mEnrollmentIds = new HashSet<>();
-        mRandom = new Random();
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void setTestHalEnabled(boolean enabled) {
-
-        super.setTestHalEnabled_enforcePermission();
-
-        mFace10.setTestHalEnabled(enabled);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void startEnroll(int userId) {
-
-        super.startEnroll_enforcePermission();
-
-        mFace10.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
-                mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
-                null /* previewSurface */, false /* debugConsent */,
-                (new FaceEnrollOptions.Builder()).build());
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void finishEnroll(int userId) {
-
-        super.finishEnroll_enforcePermission();
-
-        int nextRandomId = mRandom.nextInt();
-        while (mEnrollmentIds.contains(nextRandomId)) {
-            nextRandomId = mRandom.nextInt();
-        }
-
-        mEnrollmentIds.add(nextRandomId);
-        mHalResultController.onEnrollResult(0 /* deviceId */,
-                nextRandomId /* faceId */, userId, 0);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void acceptAuthentication(int userId) {
-
-        // Fake authentication with any of the existing fingers
-        super.acceptAuthentication_enforcePermission();
-
-        List<Face> faces = FaceUtils.getLegacyInstance(mSensorId)
-                .getBiometricsForUser(mContext, userId);
-        if (faces.isEmpty()) {
-            Slog.w(TAG, "No faces, returning");
-            return;
-        }
-        final int fid = faces.get(0).getBiometricId();
-        final ArrayList<Byte> hat = new ArrayList<>(Collections.nCopies(69, (byte) 0));
-        mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void rejectAuthentication(int userId) {
-
-        super.rejectAuthentication_enforcePermission();
-
-        mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* faceId */, userId, null);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void notifyAcquired(int userId, int acquireInfo) {
-
-        super.notifyAcquired_enforcePermission();
-
-        mHalResultController.onAcquired(0 /* deviceId */, userId, acquireInfo, 0 /* vendorCode */);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void notifyError(int userId, int errorCode) {
-
-        super.notifyError_enforcePermission();
-
-        mHalResultController.onError(0 /* deviceId */, userId, errorCode, 0 /* vendorCode */);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void cleanupInternalState(int userId) {
-
-        super.cleanupInternalState_enforcePermission();
-
-        mFace10.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                try {
-                    mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                try {
-                    mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-        });
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
deleted file mode 100644
index 306ddfa..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ /dev/null
@@ -1,1342 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.SynchronousUserSwitchObserver;
-import android.app.UserSwitchObserver;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.ITestSession;
-import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
-import android.hardware.face.Face;
-import android.hardware.face.FaceAuthenticateOptions;
-import android.hardware.face.FaceEnrollOptions;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.face.IFaceServiceReceiver;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IHwBinder;
-import android.os.Looper;
-import android.os.NativeHandle;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-import android.view.Surface;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
-import com.android.server.biometrics.AuthenticationStatsCollector;
-import com.android.server.biometrics.Flags;
-import com.android.server.biometrics.SensorServiceStateProto;
-import com.android.server.biometrics.SensorStateProto;
-import com.android.server.biometrics.UserStateProto;
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.AcquisitionClient;
-import com.android.server.biometrics.sensors.AuthSessionCoordinator;
-import com.android.server.biometrics.sensors.AuthenticationConsumer;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.EnumerateConsumer;
-import com.android.server.biometrics.sensors.ErrorConsumer;
-import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.RemovalConsumer;
-import com.android.server.biometrics.sensors.face.FaceUtils;
-import com.android.server.biometrics.sensors.face.LockoutHalImpl;
-import com.android.server.biometrics.sensors.face.ServiceProvider;
-import com.android.server.biometrics.sensors.face.UsageStats;
-import com.android.server.biometrics.sensors.face.aidl.AidlResponseHandler;
-import com.android.server.biometrics.sensors.face.aidl.AidlSession;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.time.Clock;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Supplier;
-
-/**
- * Supports a single instance of the {@link android.hardware.biometrics.face.V1_0} or its extended
- * minor versions.
- */
-public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
-
-    private static final String TAG = "Face10";
-
-    private static final int ENROLL_TIMEOUT_SEC = 75;
-    private static final int GENERATE_CHALLENGE_REUSE_INTERVAL_MILLIS = 60 * 1000;
-    private static final int GENERATE_CHALLENGE_COUNTER_TTL_MILLIS =
-            FaceGenerateChallengeClient.CHALLENGE_TIMEOUT_SEC * 1000;
-    @VisibleForTesting
-    public static Clock sSystemClock = Clock.systemUTC();
-
-    private boolean mTestHalEnabled;
-
-    @NonNull private final FaceSensorPropertiesInternal mSensorProperties;
-    @NonNull private final BiometricStateCallback mBiometricStateCallback;
-    @NonNull
-    private final AuthenticationStateListeners mAuthenticationStateListeners;
-    @NonNull private final Context mContext;
-    @NonNull private final BiometricScheduler<IBiometricsFace, AidlSession> mScheduler;
-    @NonNull private final Handler mHandler;
-    @NonNull private final Supplier<IBiometricsFace> mLazyDaemon;
-    @NonNull private final LockoutHalImpl mLockoutTracker;
-    @NonNull private final UsageStats mUsageStats;
-    @NonNull private final Map<Integer, Long> mAuthenticatorIds;
-    @Nullable private IBiometricsFace mDaemon;
-    @NonNull private final HalResultController mHalResultController;
-    @NonNull private final BiometricContext mBiometricContext;
-    @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
-    // for requests that do not use biometric prompt
-    @NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
-    private int mCurrentUserId = UserHandle.USER_NULL;
-    private final int mSensorId;
-    private final List<Long> mGeneratedChallengeCount = new ArrayList<>();
-    private final LockoutResetDispatcher mLockoutResetDispatcher;
-    private FaceGenerateChallengeClient mGeneratedChallengeCache = null;
-    private AidlSession mSession;
-
-    private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
-        @Override
-        public void onUserSwitching(int newUserId) {
-            scheduleInternalCleanup(newUserId, null /* callback */);
-            scheduleGetFeature(mSensorId, new Binder(), newUserId,
-                    BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
-                    null, mContext.getOpPackageName());
-        }
-    };
-
-    public static class HalResultController extends IBiometricsFaceClientCallback.Stub {
-        /**
-         * Interface to sends results to the HalResultController's owner.
-         */
-        public interface Callback {
-            /**
-             * Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
-             */
-            void onHardwareUnavailable();
-        }
-
-        private final int mSensorId;
-        @NonNull private final Context mContext;
-        @NonNull private final Handler mHandler;
-        @NonNull private final BiometricScheduler<IBiometricsFace, AidlSession> mScheduler;
-        @Nullable private Callback mCallback;
-        @NonNull private final LockoutHalImpl mLockoutTracker;
-        @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
-
-
-        HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
-                @NonNull BiometricScheduler<IBiometricsFace, AidlSession> scheduler,
-                @NonNull LockoutHalImpl lockoutTracker,
-                @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
-            mSensorId = sensorId;
-            mContext = context;
-            mHandler = handler;
-            mScheduler = scheduler;
-            mLockoutTracker = lockoutTracker;
-            mLockoutResetDispatcher = lockoutResetDispatcher;
-        }
-
-        public void setCallback(@Nullable Callback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
-            mHandler.post(() -> {
-                final CharSequence name = FaceUtils.getLegacyInstance(mSensorId)
-                        .getUniqueName(mContext, userId);
-                final Face face = new Face(name, faceId, deviceId);
-
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof FaceEnrollClient)) {
-                    Slog.e(TAG, "onEnrollResult for non-enroll client: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
-                enrollClient.onEnrollResult(face, remaining);
-            });
-        }
-
-        @Override
-        public void onAuthenticated(long deviceId, int faceId, int userId,
-                ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AuthenticationConsumer)) {
-                    Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final AuthenticationConsumer authenticationConsumer =
-                        (AuthenticationConsumer) client;
-                final boolean authenticated = faceId != 0;
-                final Face face = new Face("", faceId, deviceId);
-                authenticationConsumer.onAuthenticated(face, authenticated, token);
-            });
-        }
-
-        @Override
-        public void onAcquired(long deviceId, int userId, int acquiredInfo,
-                int vendorCode) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AcquisitionClient)) {
-                    Slog.e(TAG, "onAcquired for non-acquire client: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final AcquisitionClient<?> acquisitionClient =
-                        (AcquisitionClient<?>) client;
-                acquisitionClient.onAcquired(acquiredInfo, vendorCode);
-            });
-        }
-
-        @Override
-        public void onError(long deviceId, int userId, int error, int vendorCode) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                Slog.d(TAG, "handleError"
-                        + ", client: " + (client != null ? client.getOwnerString() : null)
-                        + ", error: " + error
-                        + ", vendorCode: " + vendorCode);
-                if (!(client instanceof ErrorConsumer)) {
-                    Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(
-                            client));
-                    return;
-                }
-
-                final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-                errorConsumer.onError(error, vendorCode);
-
-                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
-                    Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
-                    if (mCallback != null) {
-                        mCallback.onHardwareUnavailable();
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof RemovalConsumer)) {
-                    Slog.e(TAG, "onRemoved for non-removal consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final RemovalConsumer removalConsumer = (RemovalConsumer) client;
-
-                if (!removed.isEmpty()) {
-                    // Convert to old fingerprint-like behavior, where remove() receives
-                    // one removal at a time. This way, remove can share some more common code.
-                    for (int i = 0; i < removed.size(); i++) {
-                        final int id = removed.get(i);
-                        final Face face = new Face("", id, deviceId);
-                        final int remaining = removed.size() - i - 1;
-                        Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
-                        removalConsumer.onRemoved(face, remaining);
-                    }
-                } else {
-                    removalConsumer.onRemoved(null, 0 /* remaining */);
-                }
-
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
-            });
-        }
-
-        @Override
-        public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof EnumerateConsumer)) {
-                    Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
-
-                if (!faceIds.isEmpty()) {
-                    // Convert to old fingerprint-like behavior, where enumerate() receives one
-                    // template at a time. This way, enumerate can share some more common code.
-                    for (int i = 0; i < faceIds.size(); i++) {
-                        final Face face = new Face("", faceIds.get(i), deviceId);
-                        enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
-                    }
-                } else {
-                    // For face, the HIDL contract is to receive an empty list when there are no
-                    // templates enrolled. Send a null identifier since we don't consume them
-                    // anywhere, and send remaining == 0 so this code can be shared with [email protected]
-                    enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
-                }
-            });
-        }
-
-        @Override
-        public void onLockoutChanged(long duration) {
-            mHandler.post(() -> {
-                Slog.d(TAG, "onLockoutChanged: " + duration);
-                final @LockoutTracker.LockoutMode int lockoutMode;
-                if (duration == 0) {
-                    lockoutMode = LockoutTracker.LOCKOUT_NONE;
-                } else if (duration == -1 || duration == Long.MAX_VALUE) {
-                    lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
-                } else {
-                    lockoutMode = LockoutTracker.LOCKOUT_TIMED;
-                }
-
-                mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
-
-                if (duration == 0) {
-                    mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
-                }
-            });
-        }
-    }
-
-    @VisibleForTesting
-    Face10(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FaceSensorPropertiesInternal sensorProps,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull Handler handler,
-            @NonNull BiometricScheduler<IBiometricsFace, AidlSession> scheduler,
-            @NonNull BiometricContext biometricContext) {
-        mSensorProperties = sensorProps;
-        mContext = context;
-        mBiometricStateCallback = biometricStateCallback;
-        mAuthenticationStateListeners = authenticationStateListeners;
-        mSensorId = sensorProps.sensorId;
-        mScheduler = scheduler;
-        mHandler = handler;
-        mBiometricContext = biometricContext;
-        mUsageStats = new UsageStats(context);
-        mAuthenticatorIds = new HashMap<>();
-        mLazyDaemon = Face10.this::getDaemon;
-        mLockoutTracker = new LockoutHalImpl();
-        mHalResultController = new HalResultController(sensorProps.sensorId, context, mHandler,
-                mScheduler, mLockoutTracker, lockoutResetDispatcher);
-        mLockoutResetDispatcher = lockoutResetDispatcher;
-        mHalResultController.setCallback(() -> {
-            mDaemon = null;
-            mCurrentUserId = UserHandle.USER_NULL;
-        });
-
-        AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
-                new AuthenticationStatsBroadcastReceiver(
-                        mContext,
-                        BiometricsProtoEnums.MODALITY_FACE,
-                        (AuthenticationStatsCollector collector) -> {
-                            Slog.d(TAG, "Initializing AuthenticationStatsCollector");
-                            mAuthenticationStatsCollector = collector;
-                        });
-
-        try {
-            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to register user switch observer");
-        }
-    }
-
-    public static Face10 newInstance(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FaceSensorPropertiesInternal sensorProps,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
-        final Handler handler = new Handler(Looper.getMainLooper());
-        return new Face10(context, biometricStateCallback, authenticationStateListeners,
-                sensorProps, lockoutResetDispatcher, handler, new BiometricScheduler<>(
-                        BiometricScheduler.SENSOR_TYPE_FACE,
-                        null /* gestureAvailabilityTracker */),
-                BiometricContext.getInstance(context));
-    }
-
-    @Override
-    public void serviceDied(long cookie) {
-        Slog.e(TAG, "HAL died");
-        mHandler.post(() -> {
-            PerformanceTracker.getInstanceForSensorId(mSensorId)
-                    .incrementHALDeathCount();
-            mDaemon = null;
-            mCurrentUserId = UserHandle.USER_NULL;
-
-            final BaseClientMonitor client = mScheduler.getCurrentClient();
-            if (client instanceof ErrorConsumer) {
-                Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
-                final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-                errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                        0 /* vendorCode */);
-
-                FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
-                        BiometricsProtoEnums.MODALITY_FACE,
-                        BiometricsProtoEnums.ISSUE_HAL_DEATH,
-                        -1 /* sensorId */);
-            }
-
-            mScheduler.recordCrashState();
-            mScheduler.reset();
-        });
-    }
-
-    public int getCurrentUserId() {
-        return mCurrentUserId;
-    }
-
-    synchronized AidlSession getSession() {
-        if (mDaemon != null && mSession != null) {
-            return mSession;
-        } else {
-            return mSession = new AidlSession(mContext, this::getDaemon, mCurrentUserId,
-                    new AidlResponseHandler(mContext, mScheduler, mSensorId,
-                            mCurrentUserId, mLockoutTracker, mLockoutResetDispatcher,
-                            new AuthSessionCoordinator(), () -> {
-                        mDaemon = null;
-                        mCurrentUserId = UserHandle.USER_NULL;
-                    }));
-        }
-    }
-
-    private synchronized IBiometricsFace getDaemon() {
-        if (mTestHalEnabled) {
-            final TestHal testHal = new TestHal(mContext, mSensorId);
-            testHal.setCallback(mHalResultController);
-            return testHal;
-        }
-
-        if (mDaemon != null) {
-            return mDaemon;
-        }
-
-        Slog.d(TAG, "Daemon was null, reconnecting, current operation: "
-                + mScheduler.getCurrentClient());
-
-        try {
-            mDaemon = IBiometricsFace.getService();
-        } catch (java.util.NoSuchElementException e) {
-            // Service doesn't exist or cannot be opened.
-            Slog.w(TAG, "NoSuchElementException", e);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to get face HAL", e);
-        }
-
-        if (mDaemon == null) {
-            Slog.w(TAG, "Face HAL not available");
-            return null;
-        }
-
-        mDaemon.asBinder().linkToDeath(this, 0 /* flags */);
-
-        // HAL ID for these HIDL versions are only used to determine if callbacks have been
-        // successfully set.
-        long halId = 0;
-        try {
-            halId = mDaemon.setCallback(mHalResultController).value;
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to set callback for face HAL", e);
-            mDaemon = null;
-        }
-
-        Slog.d(TAG, "Face HAL ready, HAL ID: " + halId);
-        if (halId != 0) {
-            scheduleLoadAuthenticatorIds();
-            scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */);
-            scheduleGetFeature(mSensorId, new Binder(),
-                    ActivityManager.getCurrentUser(),
-                    BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null,
-                    mContext.getOpPackageName());
-        } else {
-            Slog.e(TAG, "Unable to set callback");
-            mDaemon = null;
-        }
-
-        return mDaemon;
-    }
-
-    @Override
-    public boolean containsSensor(int sensorId) {
-        return mSensorId == sensorId;
-    }
-
-    @Override
-    @NonNull
-    public List<FaceSensorPropertiesInternal> getSensorProperties() {
-        final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
-        properties.add(mSensorProperties);
-        return properties;
-    }
-
-    @NonNull
-    @Override
-    public FaceSensorPropertiesInternal getSensorProperties(int sensorId) {
-        return mSensorProperties;
-    }
-
-    @Override
-    @NonNull
-    public List<Face> getEnrolledFaces(int sensorId, int userId) {
-        return FaceUtils.getLegacyInstance(mSensorId).getBiometricsForUser(mContext, userId);
-    }
-
-    @Override
-    public boolean hasEnrollments(int sensorId, int userId) {
-        return !getEnrolledFaces(sensorId, userId).isEmpty();
-    }
-
-    @Override
-    @LockoutTracker.LockoutMode
-    public int getLockoutModeForUser(int sensorId, int userId) {
-        return mLockoutTracker.getLockoutModeForUser(userId);
-    }
-
-    @Override
-    public long getAuthenticatorId(int sensorId, int userId) {
-        return mAuthenticatorIds.getOrDefault(userId, 0L);
-    }
-
-    @Override
-    public boolean isHardwareDetected(int sensorId) {
-        return getDaemon() != null;
-    }
-
-    private boolean isGeneratedChallengeCacheValid() {
-        return mGeneratedChallengeCache != null
-                && sSystemClock.millis() - mGeneratedChallengeCache.getCreatedAt()
-                < GENERATE_CHALLENGE_REUSE_INTERVAL_MILLIS;
-    }
-
-    private void incrementChallengeCount() {
-        mGeneratedChallengeCount.add(0, sSystemClock.millis());
-    }
-
-    private int decrementChallengeCount() {
-        final long now = sSystemClock.millis();
-        // ignore values that are old in case generate/revoke calls are not matched
-        // this doesn't ensure revoke if calls are mismatched but it keeps the list from growing
-        mGeneratedChallengeCount.removeIf(x -> now - x > GENERATE_CHALLENGE_COUNTER_TTL_MILLIS);
-        if (!mGeneratedChallengeCount.isEmpty()) {
-            mGeneratedChallengeCount.remove(0);
-        }
-        return mGeneratedChallengeCount.size();
-    }
-
-    /**
-     * {@link IBiometricsFace} only supports a single in-flight challenge but there are cases where
-     * two callers both need challenges (e.g. resetLockout right before enrollment).
-     */
-    @Override
-    public void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleGenerateChallengeAidl(userId, token, receiver, opPackageName);
-            } else {
-                scheduleGenerateChallengeHidl(userId, token, receiver, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleGenerateChallengeAidl(int userId, @NonNull IBinder token,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceGenerateChallengeClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceGenerateChallengeClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
-                        mSensorId, createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                        mBiometricContext);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                if (client != clientMonitor) {
-                    Slog.e(TAG,
-                            "scheduleGenerateChallenge onClientStarted, mismatched client."
-                                    + " Expecting: " + client + ", received: "
-                                    + clientMonitor);
-                }
-            }
-        });
-    }
-
-    private void scheduleGenerateChallengeHidl(int userId, @NonNull IBinder token,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        incrementChallengeCount();
-        if (isGeneratedChallengeCacheValid()) {
-            Slog.d(TAG, "Current challenge is cached and will be reused");
-            mGeneratedChallengeCache.reuseResult(receiver);
-            return;
-        }
-
-        final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
-                mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
-                opPackageName, mSensorId, createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, sSystemClock.millis());
-        mGeneratedChallengeCache = client;
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                if (client != clientMonitor) {
-                    Slog.e(TAG,
-                            "scheduleGenerateChallenge onClientStarted, mismatched client."
-                                    + " Expecting: " + client + ", received: "
-                                    + clientMonitor);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
-            @NonNull String opPackageName, long challenge) {
-        mHandler.post(() -> {
-            if (Flags.deHidl()) {
-                scheduleRevokeChallengeAidl(userId, token, opPackageName);
-            } else {
-                scheduleRevokeChallengeHidl(userId, token, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleRevokeChallengeAidl(int userId, @NonNull IBinder token,
-            @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceRevokeChallengeClient
-                client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceRevokeChallengeClient(
-                        mContext, this::getSession, token, userId, opPackageName, mSensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector), mBiometricContext, 0L);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                if (client != clientMonitor) {
-                    Slog.e(TAG,
-                            "scheduleRevokeChallenge, mismatched client." + "Expecting: "
-                                    + client + ", received: " + clientMonitor);
-                }
-            }
-        });
-    }
-
-    private void scheduleRevokeChallengeHidl(int userId, @NonNull IBinder token,
-            @NonNull String opPackageName) {
-        final boolean shouldRevoke = decrementChallengeCount() == 0;
-        if (!shouldRevoke) {
-            Slog.w(TAG, "scheduleRevokeChallenge skipped - challenge still in use: "
-                    + mGeneratedChallengeCount);
-            return;
-        }
-
-        Slog.d(TAG, "scheduleRevokeChallenge executing - no active clients");
-        mGeneratedChallengeCache = null;
-        final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
-                mLazyDaemon, token, userId, opPackageName, mSensorId,
-                createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                if (client != clientMonitor) {
-                    Slog.e(TAG,
-                            "scheduleRevokeChallenge, mismatched client." + "Expecting: "
-                                    + client + ", received: " + clientMonitor);
-                }
-            }
-        });
-    }
-
-    @Override
-    public long scheduleEnroll(int sensorId, @NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver,
-            @NonNull String opPackageName, @NonNull int[] disabledFeatures,
-            @Nullable Surface previewSurface, boolean debugConsent,
-            @NonNull FaceEnrollOptions options) {
-        final long id = mRequestCounter.incrementAndGet();
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-            if (Flags.deHidl()) {
-                scheduleEnrollAidl(token, hardwareAuthToken, userId, receiver,
-                        opPackageName, disabledFeatures, previewSurface, id, options);
-            } else {
-                scheduleEnrollHidl(token, hardwareAuthToken, userId, receiver,
-                        opPackageName, disabledFeatures, previewSurface, id, options);
-            }
-        });
-        return id;
-    }
-
-    private void scheduleEnrollAidl(@NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver,
-            @NonNull String opPackageName, @NonNull int[] disabledFeatures,
-            @Nullable Surface previewSurface, long id,
-            @NonNull FaceEnrollOptions options) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceEnrollClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceEnrollClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), userId,
-                        hardwareAuthToken, opPackageName, id,
-                        FaceUtils.getLegacyInstance(mSensorId), disabledFeatures,
-                        ENROLL_TIMEOUT_SEC, previewSurface, mSensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_ENROLL,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector), mBiometricContext,
-                        mContext.getResources().getInteger(
-                                com.android.internal.R.integer.config_faceMaxTemplatesPerUser),
-                        false, options);
-
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                mBiometricStateCallback.onClientStarted(clientMonitor);
-            }
-
-            @Override
-            public void onBiometricAction(int action) {
-                mBiometricStateCallback.onBiometricAction(action);
-            }
-
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                mBiometricStateCallback.onClientFinished(clientMonitor, success);
-                if (success) {
-                    // Update authenticatorIds
-                    scheduleUpdateActiveUserWithoutHandler(client.getTargetUserId());
-                }
-            }
-        });
-    }
-
-    private void scheduleEnrollHidl(@NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver,
-            @NonNull String opPackageName, @NonNull int[] disabledFeatures,
-            @Nullable Surface previewSurface, long id, FaceEnrollOptions options) {
-            final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token,
-                    new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
-                    opPackageName, id, FaceUtils.getLegacyInstance(mSensorId), disabledFeatures,
-                    ENROLL_TIMEOUT_SEC, previewSurface, mSensorId,
-                    createLogger(BiometricsProtoEnums.ACTION_ENROLL,
-                            BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                    mBiometricContext, options);
-            mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-                @Override
-                public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                    mBiometricStateCallback.onClientStarted(clientMonitor);
-                }
-
-                @Override
-                public void onBiometricAction(int action) {
-                    mBiometricStateCallback.onBiometricAction(action);
-                }
-
-                @Override
-                public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                        boolean success) {
-                    mBiometricStateCallback.onClientFinished(clientMonitor, success);
-                    if (success) {
-                        // Update authenticatorIds
-                        scheduleUpdateActiveUserWithoutHandler(client.getTargetUserId());
-                    }
-                }
-            });
-    }
-
-    @Override
-    public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) {
-        mHandler.post(() -> mScheduler.cancelEnrollment(token, requestId));
-    }
-
-    @Override
-    public long scheduleFaceDetect(@NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter callback,
-            @NonNull FaceAuthenticateOptions options, int statsClient) {
-        throw new IllegalStateException("Face detect not supported by [email protected]. Did you"
-                + "forget to check the supportsFaceDetection flag?");
-    }
-
-    @Override
-    public void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId) {
-        throw new IllegalStateException("Face detect not supported by [email protected]. Did you"
-                + "forget to check the supportsFaceDetection flag?");
-    }
-
-    @Override
-    public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter receiver,
-            @NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
-            int statsClient, boolean allowBackgroundAuthentication) {
-        mHandler.post(() -> {
-            final int userId = options.getUserId();
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
-            if (Flags.deHidl()) {
-                scheduleAuthenticateAidl(token, operationId, cookie, receiver, options, requestId,
-                        restricted, statsClient, allowBackgroundAuthentication, isStrongBiometric);
-            } else {
-                scheduleAuthenticateHidl(token, operationId, cookie, receiver, options, requestId,
-                        restricted, statsClient, allowBackgroundAuthentication, isStrongBiometric);
-            }
-        });
-    }
-
-    private void scheduleAuthenticateAidl(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter receiver,
-            @NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
-            int statsClient, boolean allowBackgroundAuthentication, boolean isStrongBiometric) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceAuthenticationClient
-                client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceAuthenticationClient(
-                        mContext, this::getSession, token, requestId, receiver, operationId,
-                        restricted, options, cookie, false /* requireConfirmation */,
-                        createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                                mAuthenticationStatsCollector), mBiometricContext,
-                        isStrongBiometric, mUsageStats, mLockoutTracker,
-                        allowBackgroundAuthentication, Utils.getCurrentStrength(mSensorId),
-                        mAuthenticationStateListeners);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleAuthenticateHidl(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter receiver,
-            @NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
-            int statsClient, boolean allowBackgroundAuthentication, boolean isStrongBiometric) {
-        final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
-                mLazyDaemon, token, requestId, receiver, operationId, restricted, options,
-                cookie, false /* requireConfirmation */,
-                createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                        mAuthenticationStatsCollector), mBiometricContext,
-                isStrongBiometric, mLockoutTracker, mUsageStats,
-                allowBackgroundAuthentication, Utils.getCurrentStrength(mSensorId),
-                mAuthenticationStateListeners);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    @Override
-    public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter receiver,
-            @NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
-            boolean allowBackgroundAuthentication) {
-        final long id = mRequestCounter.incrementAndGet();
-
-        scheduleAuthenticate(token, operationId, cookie, receiver,
-                options, id, restricted, statsClient, allowBackgroundAuthentication);
-
-        return id;
-    }
-
-    @Override
-    public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
-        mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token, requestId));
-    }
-
-    @Override
-    public void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleRemoveAidl(token, userId, receiver, opPackageName, faceId);
-            } else {
-                scheduleRemoveHidl(token, userId, receiver, opPackageName, faceId);
-            }
-        });
-    }
-
-    @Override
-    public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            // For [email protected], remove(0) means remove all enrollments
-            if (Flags.deHidl()) {
-                scheduleRemoveAidl(token, userId, receiver, opPackageName, 0);
-            } else {
-                scheduleRemoveHidl(token, userId, receiver, opPackageName, 0);
-            }
-        });
-    }
-
-    private void scheduleRemoveAidl(@NonNull IBinder token, int userId,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName, int faceId) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceRemovalClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceRemovalClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), new int[]{faceId}, userId,
-                        opPackageName, FaceUtils.getLegacyInstance(mSensorId), mSensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_REMOVE,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector), mBiometricContext,
-                        mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    private void scheduleRemoveHidl(@NonNull IBinder token, int userId,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName, int faceId) {
-        final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token,
-                new ClientMonitorCallbackConverter(receiver), faceId, userId,
-                opPackageName, FaceUtils.getLegacyInstance(mSensorId), mSensorId,
-                createLogger(BiometricsProtoEnums.ACTION_REMOVE,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    @Override
-    public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) {
-        mHandler.post(() -> {
-            if (getEnrolledFaces(sensorId, userId).isEmpty()) {
-                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled for user: " + userId);
-                return;
-            }
-
-            scheduleUpdateActiveUserWithoutHandler(userId);
-            if (Flags.deHidl()) {
-                scheduleResetLockoutAidl(userId, hardwareAuthToken);
-            } else {
-                scheduleResetLockoutHidl(userId, hardwareAuthToken);
-            }
-        });
-    }
-
-    private void scheduleResetLockoutAidl(int userId,
-            @NonNull byte[] hardwareAuthToken) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceResetLockoutClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceResetLockoutClient(
-                        mContext, this::getSession, userId, mContext.getOpPackageName(),
-                        mSensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, hardwareAuthToken, mLockoutTracker,
-                        mLockoutResetDispatcher, mSensorProperties.sensorStrength);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleResetLockoutHidl(int userId,
-            @NonNull byte[] hardwareAuthToken) {
-        final FaceResetLockoutClient client = new FaceResetLockoutClient(mContext,
-                mLazyDaemon,
-                userId, mContext.getOpPackageName(), mSensorId,
-                createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, hardwareAuthToken);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    @Override
-    public void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
-            boolean enabled, @NonNull byte[] hardwareAuthToken,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-            if (Flags.deHidl()) {
-                scheduleSetFeatureAidl(sensorId, token, userId, feature, enabled, hardwareAuthToken,
-                        receiver, opPackageName);
-            } else {
-                scheduleSetFeatureHidl(sensorId, token, userId, feature, enabled, hardwareAuthToken,
-                        receiver, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleSetFeatureHidl(int sensorId, @NonNull IBinder token, int userId,
-            int feature, boolean enabled, @NonNull byte[] hardwareAuthToken,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        final List<Face> faces = getEnrolledFaces(sensorId, userId);
-        if (faces.isEmpty()) {
-            Slog.w(TAG, "Ignoring setFeature, no templates enrolled for user: " + userId);
-            return;
-        }
-        final int faceId = faces.get(0).getBiometricId();
-        final FaceSetFeatureClient client = new FaceSetFeatureClient(mContext, mLazyDaemon,
-                token, new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
-                mSensorId, BiometricLogger.ofUnknown(mContext), mBiometricContext, feature,
-                enabled, hardwareAuthToken, faceId);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleSetFeatureAidl(int sensorId, @NonNull IBinder token, int userId,
-            int feature, boolean enabled, @NonNull byte[] hardwareAuthToken,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceSetFeatureClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceSetFeatureClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
-                        mSensorId, BiometricLogger.ofUnknown(mContext), mBiometricContext,
-                        feature, enabled, hardwareAuthToken);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-
-    @Override
-    public void scheduleGetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
-            @Nullable ClientMonitorCallbackConverter listener, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleGetFeatureAidl(token, userId, feature, listener,
-                        opPackageName);
-            } else {
-                scheduleGetFeatureHidl(sensorId, token, userId, feature, listener,
-                        opPackageName);
-            }
-        });
-    }
-
-    private void scheduleGetFeatureHidl(int sensorId, @NonNull IBinder token, int userId,
-            int feature, @Nullable ClientMonitorCallbackConverter listener,
-            @NonNull String opPackageName) {
-        final List<Face> faces = getEnrolledFaces(sensorId, userId);
-        if (faces.isEmpty()) {
-            Slog.w(TAG, "Ignoring getFeature, no templates enrolled for user: " + userId);
-            return;
-        }
-
-        final int faceId = faces.get(0).getBiometricId();
-        final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext, mLazyDaemon,
-                token, listener, userId, opPackageName, mSensorId,
-                BiometricLogger.ofUnknown(mContext), mBiometricContext, feature, faceId);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                if (success
-                        && feature == BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION) {
-                    final int settingsValue = client.getValue() ? 1 : 0;
-                    Slog.d(TAG,
-                            "Updating attention value for user: " + userId + " to value: "
-                                    + settingsValue);
-                    Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                            Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, settingsValue,
-                            userId);
-                }
-            }
-        });
-    }
-
-    private void scheduleGetFeatureAidl(@NonNull IBinder token, int userId,
-            int feature, @Nullable ClientMonitorCallbackConverter listener,
-            @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceGetFeatureClient client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceGetFeatureClient(
-                        mContext, this::getSession, token, listener, userId, opPackageName,
-                        mSensorId, BiometricLogger.ofUnknown(mContext), mBiometricContext,
-                        feature);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleInternalCleanup(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-            if (Flags.deHidl()) {
-                scheduleInternalCleanupAidl(userId, callback);
-            } else {
-                scheduleInternalCleanupHidl(userId, callback);
-            }
-        });
-    }
-
-    private void scheduleInternalCleanupHidl(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
-                mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
-                createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, FaceUtils.getLegacyInstance(mSensorId),
-                mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client,
-                new ClientMonitorCompositeCallback(callback, mBiometricStateCallback));
-    }
-
-    private void scheduleInternalCleanupAidl(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        final com.android.server.biometrics.sensors.face.aidl.FaceInternalCleanupClient
-                client =
-                new com.android.server.biometrics.sensors.face.aidl.FaceInternalCleanupClient(
-                        mContext, this::getSession, userId, mContext.getOpPackageName(),
-                        mSensorId, createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                        mBiometricContext, FaceUtils.getLegacyInstance(mSensorId),
-                        mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client,
-                new ClientMonitorCompositeCallback(callback, mBiometricStateCallback));
-    }
-
-    @Override
-    public void scheduleInternalCleanup(int sensorId, int userId,
-            @Nullable ClientMonitorCallback callback) {
-        scheduleInternalCleanup(userId, mBiometricStateCallback);
-    }
-
-    @Override
-    public void scheduleInternalCleanup(int sensorId, int userId,
-            @Nullable ClientMonitorCallback callback, boolean favorHalEnrollments) {
-        scheduleInternalCleanup(userId, callback);
-    }
-
-    @Override
-    public void startPreparedClient(int sensorId, int cookie) {
-        mHandler.post(() -> {
-            mScheduler.startPreparedClient(cookie);
-        });
-    }
-
-    @Override
-    public void dumpProtoState(int sensorId, ProtoOutputStream proto,
-            boolean clearSchedulerBuffer) {
-        final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
-
-        proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
-        proto.write(SensorStateProto.MODALITY, SensorStateProto.FACE);
-        proto.write(SensorStateProto.CURRENT_STRENGTH,
-                Utils.getCurrentStrength(mSensorProperties.sensorId));
-        proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
-
-        for (UserInfo user : UserManager.get(mContext).getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-
-            final long userToken = proto.start(SensorStateProto.USER_STATES);
-            proto.write(UserStateProto.USER_ID, userId);
-            proto.write(UserStateProto.NUM_ENROLLED, FaceUtils.getLegacyInstance(mSensorId)
-                    .getBiometricsForUser(mContext, userId).size());
-            proto.end(userToken);
-        }
-
-        proto.write(SensorStateProto.RESET_LOCKOUT_REQUIRES_HARDWARE_AUTH_TOKEN,
-                mSensorProperties.resetLockoutRequiresHardwareAuthToken);
-        proto.write(SensorStateProto.RESET_LOCKOUT_REQUIRES_CHALLENGE,
-                mSensorProperties.resetLockoutRequiresChallenge);
-
-        proto.end(sensorToken);
-    }
-
-    @Override
-    public void dumpProtoMetrics(int sensorId, FileDescriptor fd) {
-    }
-
-    @Override
-    public void dumpInternal(int sensorId, PrintWriter pw) {
-        PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(mSensorId);
-
-        JSONObject dump = new JSONObject();
-        try {
-            dump.put("service", TAG);
-
-            JSONArray sets = new JSONArray();
-            for (UserInfo user : UserManager.get(mContext).getUsers()) {
-                final int userId = user.getUserHandle().getIdentifier();
-                final int c = FaceUtils.getLegacyInstance(mSensorId)
-                        .getBiometricsForUser(mContext, userId).size();
-                JSONObject set = new JSONObject();
-                set.put("id", userId);
-                set.put("count", c);
-                set.put("accept", performanceTracker.getAcceptForUser(userId));
-                set.put("reject", performanceTracker.getRejectForUser(userId));
-                set.put("acquire", performanceTracker.getAcquireForUser(userId));
-                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
-                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
-                // cryptoStats measures statistics about secure face transactions
-                // (e.g. to unlock password storage, make secure purchases, etc.)
-                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
-                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
-                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
-                sets.put(set);
-            }
-
-            dump.put("prints", sets);
-        } catch (JSONException e) {
-            Slog.e(TAG, "dump formatting failure", e);
-        }
-        pw.println(dump);
-        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
-
-        mScheduler.dump(pw);
-        mUsageStats.print(pw);
-    }
-
-    private void scheduleLoadAuthenticatorIds() {
-        // Note that this can be performed on the scheduler (as opposed to being done immediately
-        // when the HAL is (re)loaded, since
-        // 1) If this is truly the first time it's being performed (e.g. system has just started),
-        //    this will be run very early and way before any applications need to generate keys.
-        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
-        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
-        //    is safe because authenticatorIds only change when A) new template has been enrolled,
-        //    or B) all templates are removed.
-        mHandler.post(() -> {
-            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
-                final int targetUserId = user.id;
-                if (!mAuthenticatorIds.containsKey(targetUserId)) {
-                    scheduleUpdateActiveUserWithoutHandler(targetUserId);
-                }
-            }
-        });
-    }
-
-    /**
-     * Schedules the {@link FaceUpdateActiveUserClient} without posting the work onto the handler.
-     * Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
-     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
-     * this operation on the same lambda/runnable as those operations so that the ordering is
-     * correct.
-     */
-    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
-        final boolean hasEnrolled = !getEnrolledFaces(mSensorId, targetUserId).isEmpty();
-        final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
-                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId,
-                createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, hasEnrolled, mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                if (success) {
-                    if (mCurrentUserId != targetUserId) {
-                        // Create new session with updated user ID
-                        mSession = null;
-                    }
-                    mCurrentUserId = targetUserId;
-                } else {
-                    Slog.w(TAG, "Failed to change user, still: " + mCurrentUserId);
-                }
-            }
-        });
-    }
-
-    private BiometricLogger createLogger(int statsAction, int statsClient,
-            AuthenticationStatsCollector authenticationStatsCollector) {
-        return new BiometricLogger(mContext, BiometricsProtoEnums.MODALITY_FACE,
-                statsAction, statsClient, authenticationStatsCollector);
-    }
-
-    /**
-     * Sends a debug message to the HAL with the provided FileDescriptor and arguments.
-     */
-    public void dumpHal(int sensorId, @NonNull FileDescriptor fd, @NonNull String[] args) {
-        // WARNING: CDD restricts image data from leaving TEE unencrypted on
-        //          production devices:
-        // [C-1-10] MUST not allow unencrypted access to identifiable biometric
-        //          data or any data derived from it (such as embeddings) to the
-        //         Application Processor outside the context of the TEE.
-        //  As such, this API should only be enabled for testing purposes on
-        //  engineering and userdebug builds.  All modules in the software stack
-        //  MUST enforce final build products do NOT have this functionality.
-        //  Additionally, the following check MUST NOT be removed.
-        if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
-            return;
-        }
-
-        // Additionally, this flag allows turning off face for a device
-        // (either permanently through the build or on an individual device).
-        if (SystemProperties.getBoolean("ro.face.disable_debug_data", false)
-                || SystemProperties.getBoolean("persist.face.disable_debug_data", false)) {
-            return;
-        }
-
-        // The debug method takes two file descriptors. The first is for text
-        // output, which we will drop.  The second is for binary data, which
-        // will be the protobuf data.
-        final IBiometricsFace daemon = getDaemon();
-        if (daemon != null) {
-            FileOutputStream devnull = null;
-            try {
-                devnull = new FileOutputStream("/dev/null");
-                final NativeHandle handle = new NativeHandle(
-                        new FileDescriptor[]{devnull.getFD(), fd},
-                        new int[0], false);
-                daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
-            } catch (IOException | RemoteException ex) {
-                Slog.d(TAG, "error while reading face debugging data", ex);
-            } finally {
-                if (devnull != null) {
-                    try {
-                        devnull.close();
-                    } catch (IOException ex) {
-                    }
-                }
-            }
-        }
-    }
-
-    void setTestHalEnabled(boolean enabled) {
-        mTestHalEnabled = enabled;
-    }
-
-    @NonNull
-    @Override
-    public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
-            @NonNull String opPackageName) {
-        return new BiometricTestSessionImpl(mContext, mSensorId, callback,
-                this, mHalResultController);
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
deleted file mode 100644
index e44b263..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import static android.adaptiveauth.Flags.reportBiometricAuthAttempts;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.SensorPrivacyManager;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.BiometricManager.Authenticators;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.face.FaceAuthenticateOptions;
-import android.hardware.face.FaceManager;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.internal.R;
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BiometricNotificationUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.face.UsageStats;
-
-import java.util.ArrayList;
-import java.util.function.Supplier;
-
-/**
- * Face-specific authentication client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-class FaceAuthenticationClient
-        extends AuthenticationClient<IBiometricsFace, FaceAuthenticateOptions> {
-
-    private static final String TAG = "FaceAuthenticationClient";
-
-    private final UsageStats mUsageStats;
-
-    private final int[] mBiometricPromptIgnoreList;
-    private final int[] mBiometricPromptIgnoreListVendor;
-    private final int[] mKeyguardIgnoreList;
-    private final int[] mKeyguardIgnoreListVendor;
-
-    private int mLastAcquire;
-    private SensorPrivacyManager mSensorPrivacyManager;
-    @NonNull
-    private final AuthenticationStateListeners mAuthenticationStateListeners;
-
-    FaceAuthenticationClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon,
-            @NonNull IBinder token, long requestId,
-            @NonNull ClientMonitorCallbackConverter listener, long operationId,
-            boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
-            boolean requireConfirmation,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
-            @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
-            @Authenticators.Types int sensorStrength,
-            @NonNull AuthenticationStateListeners authenticationStateListeners) {
-        super(context, lazyDaemon, token, listener, operationId, restricted,
-                options, cookie, requireConfirmation, logger, biometricContext,
-                isStrongBiometric, null /* taskStackListener */,
-                lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
-                sensorStrength);
-        setRequestId(requestId);
-        mUsageStats = usageStats;
-        mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
-        mAuthenticationStateListeners = authenticationStateListeners;
-
-        final Resources resources = getContext().getResources();
-        mBiometricPromptIgnoreList = resources.getIntArray(
-                R.array.config_face_acquire_biometricprompt_ignorelist);
-        mBiometricPromptIgnoreListVendor = resources.getIntArray(
-                R.array.config_face_acquire_vendor_biometricprompt_ignorelist);
-        mKeyguardIgnoreList = resources.getIntArray(
-                R.array.config_face_acquire_keyguard_ignorelist);
-        mKeyguardIgnoreListVendor = resources.getIntArray(
-                R.array.config_face_acquire_vendor_keyguard_ignorelist);
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-        mState = STATE_STARTED;
-    }
-
-    @NonNull
-    @Override
-    protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
-        return new ClientMonitorCompositeCallback(
-                getLogger().getAmbientLightProbe(true /* startWithClient */), callback);
-    }
-
-    @Override
-    protected void startHalOperation() {
-
-        if (mSensorPrivacyManager != null
-                && mSensorPrivacyManager
-                .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
-                SensorPrivacyManager.Sensors.CAMERA)) {
-            onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-            return;
-        }
-
-        try {
-            getFreshDaemon().authenticate(mOperationId);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting auth", e);
-            onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    protected void stopHalOperation() {
-        try {
-            getFreshDaemon().cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting cancel", e);
-            onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public boolean wasUserDetected() {
-        // Do not provide haptic feedback if the user was not detected, and an error (usually
-        // ERROR_TIMEOUT) is received.
-        return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED
-                && mLastAcquire != FaceManager.FACE_ACQUIRED_SENSOR_DIRTY;
-    }
-
-    @Override
-    protected void handleLifecycleAfterAuth(boolean authenticated) {
-        // For face, the authentication lifecycle ends either when
-        // 1) Authenticated == true
-        // 2) Error occurred
-        // 3) Authenticated == false
-        mCallback.onClientFinished(this, true /* success */);
-    }
-
-    @Override
-    public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
-        @LockoutTracker.LockoutMode final int lockoutMode =
-                getLockoutTracker().getLockoutModeForUser(userId);
-        final PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(getSensorId());
-        if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
-            performanceTracker.incrementPermanentLockoutForUser(userId);
-        } else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
-            performanceTracker.incrementTimedLockoutForUser(userId);
-        }
-
-        return lockoutMode;
-    }
-
-    @Override
-    public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated, ArrayList<Byte> token) {
-        super.onAuthenticated(identifier, authenticated, token);
-
-        mState = STATE_STOPPED;
-        mUsageStats.addEvent(new UsageStats.AuthenticationEvent(
-                getStartTimeMs(),
-                System.currentTimeMillis() - getStartTimeMs() /* latency */,
-                authenticated,
-                0 /* error */,
-                0 /* vendorError */,
-                getTargetUserId()));
-
-        if (reportBiometricAuthAttempts()) {
-            if (authenticated) {
-                mAuthenticationStateListeners.onAuthenticationSucceeded(getRequestReason(),
-                        getTargetUserId());
-            } else {
-                mAuthenticationStateListeners.onAuthenticationFailed(getRequestReason(),
-                        getTargetUserId());
-            }
-        }
-    }
-
-    @Override
-    public void onError(@BiometricConstants.Errors int error, int vendorCode) {
-        mUsageStats.addEvent(new UsageStats.AuthenticationEvent(
-                getStartTimeMs(),
-                System.currentTimeMillis() - getStartTimeMs() /* latency */,
-                false /* authenticated */,
-                error,
-                vendorCode,
-                getTargetUserId()));
-
-        super.onError(error, vendorCode);
-    }
-
-    private int[] getAcquireIgnorelist() {
-        return isBiometricPrompt() ? mBiometricPromptIgnoreList : mKeyguardIgnoreList;
-    }
-
-    private int[] getAcquireVendorIgnorelist() {
-        return isBiometricPrompt() ? mBiometricPromptIgnoreListVendor : mKeyguardIgnoreListVendor;
-    }
-
-    private boolean shouldSend(int acquireInfo, int vendorCode) {
-        if (acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR) {
-            return !Utils.listContains(getAcquireVendorIgnorelist(), vendorCode);
-        } else {
-            return !Utils.listContains(getAcquireIgnorelist(), acquireInfo);
-        }
-    }
-
-    @Override
-    public void onAcquired(int acquireInfo, int vendorCode) {
-        mLastAcquire = acquireInfo;
-
-        if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
-            BiometricNotificationUtils.showReEnrollmentNotification(getContext());
-        }
-        @LockoutTracker.LockoutMode final int lockoutMode =
-                getLockoutTracker().getLockoutModeForUser(getTargetUserId());
-        if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
-            PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
-            pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
-        }
-
-        final boolean shouldSend = shouldSend(acquireInfo, vendorCode);
-        onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
deleted file mode 100644
index 815cf91..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.Status;
-import android.hardware.face.Face;
-import android.hardware.face.FaceEnrollOptions;
-import android.hardware.face.FaceManager;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-import android.view.Surface;
-
-import com.android.internal.R;
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricNotificationUtils;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.EnrollClient;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.function.Supplier;
-
-/**
- * Face-specific enroll client supporting the {@link android.hardware.biometrics.face.V1_0} HIDL
- * interface.
- */
-public class FaceEnrollClient extends EnrollClient<IBiometricsFace> {
-
-    private static final String TAG = "FaceEnrollClient";
-
-    @NonNull private final int[] mDisabledFeatures;
-    @NonNull private final int[] mEnrollIgnoreList;
-    @NonNull private final int[] mEnrollIgnoreListVendor;
-
-    FaceEnrollClient(@NonNull Context context, @NonNull Supplier<IBiometricsFace> lazyDaemon,
-            @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
-            @NonNull byte[] hardwareAuthToken, @NonNull String owner, long requestId,
-            @NonNull BiometricUtils<Face> utils, @NonNull int[] disabledFeatures, int timeoutSec,
-            @Nullable Surface previewSurface, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull FaceEnrollOptions options) {
-        super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
-                timeoutSec, sensorId, false /* shouldVibrate */, logger, biometricContext,
-                BiometricFaceConstants.reasonToMetric(options.getEnrollReason()));
-        setRequestId(requestId);
-        mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length);
-        mEnrollIgnoreList = getContext().getResources()
-                .getIntArray(R.array.config_face_acquire_enroll_ignorelist);
-        mEnrollIgnoreListVendor = getContext().getResources()
-                .getIntArray(R.array.config_face_acquire_vendor_enroll_ignorelist);
-
-        Slog.w(TAG, "EnrollOptions "
-                + FaceEnrollOptions.enrollReasonToString(options.getEnrollReason()));
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-
-        BiometricNotificationUtils.cancelFaceEnrollNotification(getContext());
-        BiometricNotificationUtils.cancelFaceReEnrollNotification(getContext());
-    }
-
-    @NonNull
-    @Override
-    protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
-        return new ClientMonitorCompositeCallback(
-                getLogger().getAmbientLightProbe(true /* startWithClient */), callback);
-    }
-
-    @Override
-    protected boolean hasReachedEnrollmentLimit() {
-        final int limit = getContext().getResources().getInteger(
-                com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
-        final int enrolled = mBiometricUtils.getBiometricsForUser(getContext(), getTargetUserId())
-                .size();
-        if (enrolled >= limit) {
-            Slog.w(TAG, "Too many faces registered, user: " + getTargetUserId());
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void onAcquired(int acquireInfo, int vendorCode) {
-        final boolean shouldSend;
-        if (acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR) {
-            shouldSend = !Utils.listContains(mEnrollIgnoreListVendor, vendorCode);
-        } else {
-            shouldSend = !Utils.listContains(mEnrollIgnoreList, acquireInfo);
-        }
-        onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        final ArrayList<Byte> token = new ArrayList<>();
-        for (byte b : mHardwareAuthToken) {
-            token.add(b);
-        }
-        final ArrayList<Integer> disabledFeatures = new ArrayList<>();
-        for (int disabledFeature : mDisabledFeatures) {
-            disabledFeatures.add(disabledFeature);
-        }
-
-        try {
-            final int status = getFreshDaemon().enroll(token, mTimeoutSec, disabledFeatures);
-
-            if (status != Status.OK) {
-                onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
-                mCallback.onClientFinished(this, false /* success */);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting enroll", e);
-            onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    protected void stopHalOperation() {
-        try {
-            getFreshDaemon().cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting cancel", e);
-            onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java
deleted file mode 100644
index 97838a7..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.face.IFaceServiceReceiver;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.internal.util.Preconditions;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.GenerateChallengeClient;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * Face-specific generateChallenge client supporting the
- * {@link android.hardware.biometrics.face.V1_0} HIDL interface.
- */
-public class FaceGenerateChallengeClient extends GenerateChallengeClient<IBiometricsFace> {
-
-    private static final String TAG = "FaceGenerateChallengeClient";
-    static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
-    private static final ClientMonitorCallback EMPTY_CALLBACK = new ClientMonitorCallback() {
-    };
-
-    private final long mCreatedAt;
-    private List<IFaceServiceReceiver> mWaiting;
-    private Long mChallengeResult;
-
-    FaceGenerateChallengeClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon, @NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner,
-            int sensorId, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext, long now) {
-        super(context, lazyDaemon, token, listener, userId, owner, sensorId, logger,
-                biometricContext);
-        mCreatedAt = now;
-        mWaiting = new ArrayList<>();
-    }
-
-    @Override
-    protected void startHalOperation() {
-        mChallengeResult = null;
-        try {
-            mChallengeResult = getFreshDaemon().generateChallenge(CHALLENGE_TIMEOUT_SEC).value;
-            // send the result to the original caller via mCallback and any waiting callers
-            // that called reuseResult
-            sendChallengeResult(getListener(), mCallback);
-            for (IFaceServiceReceiver receiver : mWaiting) {
-                sendChallengeResult(new ClientMonitorCallbackConverter(receiver), EMPTY_CALLBACK);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "generateChallenge failed", e);
-            mCallback.onClientFinished(this, false /* success */);
-        } finally {
-            mWaiting = null;
-        }
-    }
-
-    /** @return An arbitrary time value for caching provided to the constructor. */
-    public long getCreatedAt() {
-        return mCreatedAt;
-    }
-
-    /**
-     * Reuse the result of this operation when it is available. The receiver will be notified
-     * immediately if a challenge has already been generated.
-     *
-     * @param receiver receiver to be notified of challenge result
-     */
-    public void reuseResult(@NonNull IFaceServiceReceiver receiver) {
-        if (mWaiting != null) {
-            mWaiting.add(receiver);
-        } else {
-            sendChallengeResult(new ClientMonitorCallbackConverter(receiver), EMPTY_CALLBACK);
-        }
-    }
-
-    private void sendChallengeResult(@NonNull ClientMonitorCallbackConverter receiver,
-            @NonNull ClientMonitorCallback ownerCallback) {
-        Preconditions.checkState(mChallengeResult != null, "result not available");
-        try {
-            receiver.onChallengeGenerated(getSensorId(), getTargetUserId(), mChallengeResult);
-            ownerCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception", e);
-            ownerCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
deleted file mode 100644
index 47aaeec..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.OptionalBool;
-import android.hardware.biometrics.face.V1_0.Status;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.HalClientMonitor;
-
-import java.util.function.Supplier;
-
-/**
- * Face-specific getFeature client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-public class FaceGetFeatureClient extends HalClientMonitor<IBiometricsFace> {
-
-    private static final String TAG = "FaceGetFeatureClient";
-
-    private final int mFeature;
-    private final int mFaceId;
-    private boolean mValue;
-
-    FaceGetFeatureClient(@NonNull Context context, @NonNull Supplier<IBiometricsFace> lazyDaemon,
-            @NonNull IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
-            @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            int feature, int faceId) {
-        super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
-                logger, biometricContext);
-        mFeature = feature;
-        mFaceId = faceId;
-    }
-
-    @Override
-    public void unableToStart() {
-        try {
-            getListener().onFeatureGet(false /* success */, new int[0], new boolean[0]);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to send error", e);
-        }
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-        startHalOperation();
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            final OptionalBool result = getFreshDaemon().getFeature(mFeature, mFaceId);
-            int[] features = new int[1];
-            boolean[] featureState = new boolean[1];
-            features[0] = mFeature;
-            featureState[0] = result.value;
-            mValue = result.value;
-
-            getListener().onFeatureGet(result.status == Status.OK, features, featureState);
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to getFeature", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    boolean getValue() {
-        return mValue;
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_GET_FEATURE;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java
deleted file mode 100644
index 89a17c6..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.face.Face;
-import android.os.IBinder;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.InternalCleanupClient;
-import com.android.server.biometrics.sensors.InternalEnumerateClient;
-import com.android.server.biometrics.sensors.RemovalClient;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * Face-specific internal cleanup client supporting the
- * {@link android.hardware.biometrics.face.V1_0} HIDL interface.
- */
-class FaceInternalCleanupClient extends InternalCleanupClient<Face, IBiometricsFace> {
-
-    FaceInternalCleanupClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon, int userId, @NonNull String owner,
-            int sensorId, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext,
-            @NonNull BiometricUtils<Face> utils, @NonNull Map<Integer, Long> authenticatorIds) {
-        super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
-                utils, authenticatorIds);
-    }
-
-    @Override
-    protected InternalEnumerateClient<IBiometricsFace> getEnumerateClient(Context context,
-            Supplier<IBiometricsFace> lazyDaemon, IBinder token, int userId, String owner,
-            List<Face> enrolledList, BiometricUtils<Face> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        return new FaceInternalEnumerateClient(context, lazyDaemon, token, userId, owner,
-                enrolledList, utils, sensorId, logger, biometricContext);
-    }
-
-    @Override
-    protected RemovalClient<Face, IBiometricsFace> getRemovalClient(Context context,
-            Supplier<IBiometricsFace> lazyDaemon, IBinder token,
-            int biometricId, int userId, String owner, BiometricUtils<Face> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            Map<Integer, Long> authenticatorIds) {
-        // Internal remove does not need to send results to anyone. Cleanup (enumerate + remove)
-        // is all done internally.
-        return new FaceRemovalClient(context, lazyDaemon, token,
-                null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils,
-                sensorId, logger, biometricContext, authenticatorIds);
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java
deleted file mode 100644
index 250dd7e..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.face.Face;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.InternalEnumerateClient;
-
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * Face-specific internal enumerate client supporting the
- * {@link android.hardware.biometrics.face.V1_0} HIDL interface.
- */
-class FaceInternalEnumerateClient extends InternalEnumerateClient<IBiometricsFace> {
-    private static final String TAG = "FaceInternalEnumerateClient";
-
-    FaceInternalEnumerateClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon, @NonNull IBinder token, int userId,
-            @NonNull String owner, @NonNull List<Face> enrolledList,
-            @NonNull BiometricUtils<Face> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        super(context, lazyDaemon, token, userId, owner, enrolledList, utils, sensorId,
-                logger, biometricContext);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().enumerate();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting enumerate", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
deleted file mode 100644
index 0ee7a35..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.face.Face;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.RemovalClient;
-
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * Face-specific removal client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-class FaceRemovalClient extends RemovalClient<Face, IBiometricsFace> {
-    private static final String TAG = "FaceRemovalClient";
-
-    private final int mBiometricId;
-
-    FaceRemovalClient(@NonNull Context context, @NonNull Supplier<IBiometricsFace> lazyDaemon,
-            @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
-            int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Face> utils,
-            int sensorId, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext,
-            @NonNull Map<Integer, Long> authenticatorIds) {
-        super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, logger,
-                biometricContext, authenticatorIds);
-        mBiometricId = biometricId;
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().remove(mBiometricId);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting remove", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
deleted file mode 100644
index f29b9e8..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.HalClientMonitor;
-
-import java.util.ArrayList;
-import java.util.function.Supplier;
-
-/**
- * Face-specific resetLockout client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-public class FaceResetLockoutClient extends HalClientMonitor<IBiometricsFace> {
-
-    private static final String TAG = "FaceResetLockoutClient";
-
-    private final ArrayList<Byte> mHardwareAuthToken;
-
-    FaceResetLockoutClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon, int userId, String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull byte[] hardwareAuthToken) {
-        super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner,
-                0 /* cookie */, sensorId, logger, biometricContext);
-
-        mHardwareAuthToken = new ArrayList<>();
-        for (byte b : hardwareAuthToken) {
-            mHardwareAuthToken.add(b);
-        }
-    }
-
-    @Override
-    public void unableToStart() {
-        // Nothing to do here
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-        startHalOperation();
-    }
-
-    public boolean interruptsPrecedingClients() {
-        return true;
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().resetLockout(mHardwareAuthToken);
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to reset lockout", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_RESET_LOCKOUT;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java
deleted file mode 100644
index b7b0dc04..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.RevokeChallengeClient;
-
-import java.util.function.Supplier;
-
-/**
- * Face-specific revokeChallenge client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-public class FaceRevokeChallengeClient extends RevokeChallengeClient<IBiometricsFace> {
-
-    private static final String TAG = "FaceRevokeChallengeClient";
-
-    FaceRevokeChallengeClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFace> lazyDaemon, @NonNull IBinder token,
-            int userId, @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        super(context, lazyDaemon, token, userId, owner, sensorId, logger, biometricContext);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().revokeChallenge();
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "revokeChallenge failed", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
deleted file mode 100644
index 3c82f9c..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.Status;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.HalClientMonitor;
-
-import java.util.ArrayList;
-import java.util.function.Supplier;
-
-/**
- * Face-specific setFeature client supporting the {@link android.hardware.biometrics.face.V1_0}
- * HIDL interface.
- */
-public class FaceSetFeatureClient extends HalClientMonitor<IBiometricsFace> {
-
-    private static final String TAG = "FaceSetFeatureClient";
-
-    private final int mFeature;
-    private final boolean mEnabled;
-    private final ArrayList<Byte> mHardwareAuthToken;
-    private final int mFaceId;
-
-    FaceSetFeatureClient(@NonNull Context context, @NonNull Supplier<IBiometricsFace> lazyDaemon,
-            @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
-            @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            int feature, boolean enabled, byte[] hardwareAuthToken, int faceId) {
-        super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
-                logger, biometricContext);
-        mFeature = feature;
-        mEnabled = enabled;
-        mFaceId = faceId;
-
-        mHardwareAuthToken = new ArrayList<>();
-        for (byte b : hardwareAuthToken) {
-            mHardwareAuthToken.add(b);
-        }
-    }
-
-    @Override
-    public void unableToStart() {
-        try {
-            getListener().onFeatureSet(false /* success */, mFeature);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to send error", e);
-        }
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-
-        startHalOperation();
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            final int result = getFreshDaemon()
-                    .setFeature(mFeature, mEnabled, mHardwareAuthToken, mFaceId);
-            getListener().onFeatureSet(result == Status.OK, mFeature);
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to set feature: " + mFeature + " to enabled: " + mEnabled, e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_SET_FEATURE;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSensorAdapter.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSensorAdapter.java
index a004cae4..9a4c29d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSensorAdapter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSensorAdapter.java
@@ -173,9 +173,14 @@
     }
 
     private AidlResponseHandler getAidlResponseHandler() {
-        return new AidlResponseHandler(getContext(), getScheduler(), getSensorProperties().sensorId,
-                mCurrentUserId, mLockoutTracker, mLockoutResetDispatcher,
-                mAuthSessionCoordinator, () -> {}, mAidlResponseHandlerCallback);
+        return new AidlResponseHandler(getContext(),
+                getScheduler(),
+                getSensorProperties().sensorId,
+                mCurrentUserId,
+                mLockoutTracker,
+                mLockoutResetDispatcher,
+                mAuthSessionCoordinator,
+                mAidlResponseHandlerCallback);
     }
 
     private IBiometricsFace getIBiometricsFace() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapter.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapter.java
index fa95361..45d0cfe 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapter.java
@@ -53,7 +53,7 @@
 
     private static final String TAG = "HidlToAidlSessionAdapter";
 
-    private static final int CHALLENGE_TIMEOUT_SEC = 600;
+    @VisibleForTesting static final int CHALLENGE_TIMEOUT_SEC = 600;
     @DurationMillisLong
     private static final int GENERATE_CHALLENGE_REUSE_INTERVAL_MILLIS = 60 * 1000;
     @DurationMillisLong
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index d762914..deda93c7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -72,7 +72,6 @@
 import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Pair;
 import android.util.Slog;
@@ -83,7 +82,6 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.SystemService;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.sensors.AuthenticationStateListeners;
@@ -94,12 +92,8 @@
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
-import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
-import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
-import com.google.android.collect.Lists;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -886,9 +880,9 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
-        public void registerAuthenticatorsLegacy(
+        public void registerAuthenticators(
                 @NonNull FingerprintSensorConfigurations fingerprintSensorConfigurations) {
-            super.registerAuthenticatorsLegacy_enforcePermission();
+            super.registerAuthenticators_enforcePermission();
             if (!fingerprintSensorConfigurations.hasSensorConfigurations()) {
                 Slog.d(TAG, "No fingerprint sensors available.");
                 return;
@@ -897,30 +891,6 @@
         }
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
-        @Override // Binder call
-        public void registerAuthenticators(
-                @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
-            super.registerAuthenticators_enforcePermission();
-
-            mRegistry.registerAll(() -> {
-                List<String> aidlSensors = new ArrayList<>();
-                final String[] instances = mAidlInstanceNameSupplier.get();
-                if (instances != null) {
-                    aidlSensors.addAll(Lists.newArrayList(instances));
-                }
-
-                final Pair<List<FingerprintSensorPropertiesInternal>, List<String>>
-                        filteredInstances = filterAvailableHalInstances(hidlSensors, aidlSensors);
-
-                final List<ServiceProvider> providers = new ArrayList<>();
-                providers.addAll(getHidlProviders(filteredInstances.first));
-                providers.addAll(getAidlProviders(filteredInstances.second));
-
-                return providers;
-            });
-        }
-
-        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void addAuthenticatorsRegisteredCallback(
                 IFingerprintAuthenticatorsRegisteredCallback callback) {
@@ -1086,22 +1056,15 @@
 
                     return null;
                 };
-        if (Flags.deHidl()) {
-            mFingerprintProviderFunction = fingerprintProviderFunction == null
-                    ? (filteredSensorProps, resetLockoutRequiresHardwareAuthToken) ->
-                            new FingerprintProvider(
-                                    getContext(), mBiometricStateCallback,
-                                    mAuthenticationStateListeners,
-                                    filteredSensorProps.second,
-                                    filteredSensorProps.first, mLockoutResetDispatcher,
-                                    mGestureAvailabilityDispatcher,
-                                    mBiometricContext,
-                                    resetLockoutRequiresHardwareAuthToken)
-                    : fingerprintProviderFunction;
-        } else {
-            mFingerprintProviderFunction =
-                    (filteredSensorProps, resetLockoutRequiresHardwareAuthToken) -> null;
-        }
+        mFingerprintProviderFunction = fingerprintProviderFunction != null
+                ? fingerprintProviderFunction :
+                        (filteredSensorProps, resetLockoutRequiresHardwareAuthToken) ->
+                                new FingerprintProvider(getContext(), mBiometricStateCallback,
+                                        mAuthenticationStateListeners, filteredSensorProps.second,
+                                        filteredSensorProps.first, mLockoutResetDispatcher,
+                                        mGestureAvailabilityDispatcher, mBiometricContext,
+                                        resetLockoutRequiresHardwareAuthToken);
+
         mHandler = new Handler(Looper.getMainLooper());
         mRegistry = new FingerprintServiceRegistry(mServiceWrapper, biometricServiceSupplier);
         mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
@@ -1160,74 +1123,6 @@
                 .getSensorPropForInstance(finalSensorInstance));
     }
 
-    private Pair<List<FingerprintSensorPropertiesInternal>, List<String>>
-                filterAvailableHalInstances(
-            @NonNull List<FingerprintSensorPropertiesInternal> hidlInstances,
-            @NonNull List<String> aidlInstances) {
-        if ((hidlInstances.size() + aidlInstances.size()) <= 1) {
-            return new Pair(hidlInstances, aidlInstances);
-        }
-
-        final int virtualAt = aidlInstances.indexOf("virtual");
-        if (Utils.isFingerprintVirtualEnabled(getContext())) {
-            if (virtualAt != -1) {
-                //only virtual instance should be returned
-                Slog.i(TAG, "virtual hal is used");
-                return new Pair(new ArrayList<>(), List.of(aidlInstances.get(virtualAt)));
-            } else {
-                Slog.e(TAG, "Could not find virtual interface while it is enabled");
-                return new Pair(hidlInstances, aidlInstances);
-            }
-        } else {
-            //remove virtual instance
-            aidlInstances = new ArrayList<>(aidlInstances);
-            if (virtualAt != -1) {
-                aidlInstances.remove(virtualAt);
-            }
-            return new Pair(hidlInstances, aidlInstances);
-        }
-    }
-
-    @NonNull
-    private List<ServiceProvider> getHidlProviders(
-            @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
-        final List<ServiceProvider> providers = new ArrayList<>();
-
-        for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {
-            final Fingerprint21 fingerprint21;
-            if ((Build.IS_USERDEBUG || Build.IS_ENG)
-                    && getContext().getResources().getBoolean(R.bool.allow_test_udfps)
-                    && Settings.Secure.getIntForUser(getContext().getContentResolver(),
-                    Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,
-                    UserHandle.USER_CURRENT) != 0) {
-                fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
-                        mBiometricStateCallback, mAuthenticationStateListeners,
-                        hidlSensor, mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
-                        BiometricContext.getInstance(getContext()));
-            } else {
-                fingerprint21 = Fingerprint21.newInstance(getContext(),
-                        mBiometricStateCallback, mAuthenticationStateListeners, hidlSensor,
-                        mHandler, mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
-            }
-            providers.add(fingerprint21);
-        }
-
-        return providers;
-    }
-
-    @NonNull
-    private List<ServiceProvider> getAidlProviders(@NonNull List<String> instances) {
-        final List<ServiceProvider> providers = new ArrayList<>();
-
-        for (String instance : instances) {
-            final FingerprintProvider provider = mFingerprintProvider.apply(instance);
-            Slog.i(TAG, "Adding AIDL provider: " + instance);
-            providers.add(provider);
-        }
-
-        return providers;
-    }
-
     @Override
     public void onStart() {
         publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlResponseHandler.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlResponseHandler.java
index bd21cf4..6d1715f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlResponseHandler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlResponseHandler.java
@@ -25,7 +25,6 @@
 import android.hardware.keymaster.HardwareAuthToken;
 import android.util.Slog;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.HardwareAuthTokenUtils;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.AcquisitionClient;
@@ -53,16 +52,6 @@
     /**
      * Interface to send results to the AidlResponseHandler's owner.
      */
-    public interface HardwareUnavailableCallback {
-        /**
-         * Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
-         */
-        void onHardwareUnavailable();
-    }
-
-    /**
-     * Interface to send results to the AidlResponseHandler's owner.
-     */
     public interface AidlResponseHandlerCallback {
         /**
          * Invoked when enrollment is successful.
@@ -90,8 +79,6 @@
     @NonNull
     private final AuthSessionCoordinator mAuthSessionCoordinator;
     @NonNull
-    private final HardwareUnavailableCallback mHardwareUnavailableCallback;
-    @NonNull
     private final AidlResponseHandlerCallback mAidlResponseHandlerCallback;
 
     public AidlResponseHandler(@NonNull Context context,
@@ -99,24 +86,6 @@
             @NonNull LockoutTracker lockoutTracker,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             @NonNull AuthSessionCoordinator authSessionCoordinator,
-            @NonNull HardwareUnavailableCallback hardwareUnavailableCallback) {
-        this(context, scheduler, sensorId, userId, lockoutTracker, lockoutResetDispatcher,
-                authSessionCoordinator, hardwareUnavailableCallback,
-                new AidlResponseHandlerCallback() {
-                    @Override
-                    public void onEnrollSuccess() {}
-
-                    @Override
-                    public void onHardwareUnavailable() {}
-                });
-    }
-
-    public AidlResponseHandler(@NonNull Context context,
-            @NonNull BiometricScheduler scheduler, int sensorId, int userId,
-            @NonNull LockoutTracker lockoutTracker,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull AuthSessionCoordinator authSessionCoordinator,
-            @NonNull HardwareUnavailableCallback hardwareUnavailableCallback,
             @NonNull AidlResponseHandlerCallback aidlResponseHandlerCallback) {
         mContext = context;
         mScheduler = scheduler;
@@ -125,7 +94,6 @@
         mLockoutTracker = lockoutTracker;
         mLockoutResetDispatcher = lockoutResetDispatcher;
         mAuthSessionCoordinator = authSessionCoordinator;
-        mHardwareUnavailableCallback = hardwareUnavailableCallback;
         mAidlResponseHandlerCallback = aidlResponseHandlerCallback;
     }
 
@@ -171,11 +139,7 @@
         handleResponse(ErrorConsumer.class, (c) -> {
             c.onError(error, vendorCode);
             if (error == Error.HW_UNAVAILABLE) {
-                if (Flags.deHidl()) {
-                    mAidlResponseHandlerCallback.onHardwareUnavailable();
-                } else {
-                    mHardwareUnavailableCallback.onHardwareUnavailable();
-                }
+                mAidlResponseHandlerCallback.onHardwareUnavailable();
             }
         });
     }
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 93d1b6e..5edcbed 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
@@ -31,23 +31,16 @@
 import android.hardware.biometrics.BiometricManager.Authenticators;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.biometrics.common.ICancellationSignal;
-import android.hardware.biometrics.common.OperationState;
 import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.fingerprint.FingerprintAuthenticateOptions;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.Build;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.Slog;
 
-import com.android.internal.R;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.CallbackWithProbe;
@@ -67,7 +60,6 @@
 import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler;
 import com.android.server.biometrics.sensors.fingerprint.Udfps;
 
-import java.time.Clock;
 import java.util.ArrayList;
 import java.util.function.Supplier;
 
@@ -79,30 +71,17 @@
         extends AuthenticationClient<AidlSession, FingerprintAuthenticateOptions>
         implements Udfps, LockoutConsumer, PowerPressHandler {
     private static final String TAG = "FingerprintAuthenticationClient";
-    private static final int MESSAGE_AUTH_SUCCESS = 2;
-    private static final int MESSAGE_FINGER_UP = 3;
     @NonNull
     private final SensorOverlays mSensorOverlays;
     @NonNull
     private final FingerprintSensorPropertiesInternal mSensorProps;
     @NonNull
     private final CallbackWithProbe<Probe> mALSProbeCallback;
-    private final Handler mHandler;
-    private final int mSkipWaitForPowerAcquireMessage;
-    private final int mSkipWaitForPowerVendorAcquireMessage;
-    private final long mFingerUpIgnoresPower = 500;
     private final AuthSessionCoordinator mAuthSessionCoordinator;
     @NonNull private final AuthenticationStateListeners mAuthenticationStateListeners;
     @Nullable
     private ICancellationSignal mCancellationSignal;
     private boolean mIsPointerDown;
-    private long mWaitForAuthKeyguard;
-    private long mWaitForAuthBp;
-    private long mIgnoreAuthFor;
-    private long mSideFpsLastAcquireStartTime;
-    private Runnable mAuthSuccessRunnable;
-    private final Clock mClock;
-
 
     public FingerprintAuthenticationClient(
             @NonNull Context context,
@@ -125,9 +104,7 @@
             @NonNull AuthenticationStateListeners authenticationStateListeners,
             boolean allowBackgroundAuthentication,
             @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @NonNull Handler handler,
             @Authenticators.Types int biometricStrength,
-            @NonNull Clock clock,
             @Nullable LockoutTracker lockoutTracker) {
         super(
                 context,
@@ -156,39 +133,7 @@
         mAuthenticationStateListeners = authenticationStateListeners;
         mSensorProps = sensorProps;
         mALSProbeCallback = getLogger().getAmbientLightProbe(false /* startWithClient */);
-        mHandler = handler;
-
-        mWaitForAuthKeyguard =
-                context.getResources()
-                        .getInteger(R.integer.config_sidefpsKeyguardPowerPressWindow);
-        mWaitForAuthBp =
-                context.getResources().getInteger(R.integer.config_sidefpsBpPowerPressWindow);
-        mIgnoreAuthFor =
-                context.getResources().getInteger(R.integer.config_sidefpsPostAuthDowntime);
-
-        mSkipWaitForPowerAcquireMessage =
-                context.getResources().getInteger(
-                        R.integer.config_sidefpsSkipWaitForPowerAcquireMessage);
-        mSkipWaitForPowerVendorAcquireMessage =
-                context.getResources().getInteger(
-                        R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage);
         mAuthSessionCoordinator = biometricContext.getAuthSessionCoordinator();
-        mSideFpsLastAcquireStartTime = -1;
-        mClock = clock;
-
-        if (mSensorProps.isAnySidefpsType()) {
-            if (Build.isDebuggable()) {
-                mWaitForAuthKeyguard = Settings.Secure.getIntForUser(context.getContentResolver(),
-                        Settings.Secure.FINGERPRINT_SIDE_FPS_KG_POWER_WINDOW,
-                        (int) mWaitForAuthKeyguard, UserHandle.USER_CURRENT);
-                mWaitForAuthBp = Settings.Secure.getIntForUser(context.getContentResolver(),
-                        Settings.Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW, (int) mWaitForAuthBp,
-                        UserHandle.USER_CURRENT);
-                mIgnoreAuthFor = Settings.Secure.getIntForUser(context.getContentResolver(),
-                        Settings.Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME, (int) mIgnoreAuthFor,
-                        UserHandle.USER_CURRENT);
-            }
-        }
     }
 
     @Override
@@ -316,11 +261,7 @@
         }
 
         try {
-            if (Flags.deHidl()) {
-                startAuthentication();
-            } else {
-                mCancellationSignal = doAuthenticate();
-            }
+            doAuthenticate();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
             onError(
@@ -334,49 +275,7 @@
         }
     }
 
-    private ICancellationSignal doAuthenticate() throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-
-        final OperationContextExt opContext = getOperationContext();
-        final ICancellationSignal cancel;
-        if (session.hasContextMethods()) {
-            cancel = session.getSession().authenticateWithContext(
-                    mOperationId, opContext.toAidlContext(getOptions()));
-        } else {
-            cancel = session.getSession().authenticate(mOperationId);
-        }
-
-        getBiometricContext().subscribe(opContext, ctx -> {
-            if (session.hasContextMethods()) {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
-                    if (ctx.operationState != null && ctx.operationState.getTag()
-                            == OperationState.fingerprintOperationState) {
-                        session.getSession().setIgnoreDisplayTouches(
-                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches);
-                    }
-                } 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 (getBiometricContext().isAwake()) {
-            mALSProbeCallback.getProbe().enable();
-        }
-
-        return cancel;
-    }
-
-    private void startAuthentication() {
+    private void doAuthenticate() throws RemoteException {
         final AidlSession session = getFreshDaemon();
         final OperationContextExt opContext = getOperationContext();
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 8d2b46f..1db2fad 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.hardware.biometrics.BiometricRequestConstants;
 import android.hardware.biometrics.common.ICancellationSignal;
-import android.hardware.biometrics.common.OperationState;
 import android.hardware.fingerprint.FingerprintAuthenticateOptions;
 import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.IBinder;
@@ -31,7 +30,6 @@
 import android.util.Slog;
 
 import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -106,13 +104,8 @@
         resetIgnoreDisplayTouches();
         mSensorOverlays.show(getSensorId(), BiometricRequestConstants.REASON_AUTH_KEYGUARD,
                 this);
-
         try {
-            if (Flags.deHidl()) {
-                startDetectInteraction();
-            } else {
-                mCancellationSignal = doDetectInteraction();
-            }
+            doDetectInteraction();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting finger detect", e);
             mSensorOverlays.hide(getSensorId());
@@ -120,33 +113,7 @@
         }
     }
 
-    private ICancellationSignal doDetectInteraction() throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-
-        if (session.hasContextMethods()) {
-            final OperationContextExt opContext = getOperationContext();
-            final ICancellationSignal cancel = session.getSession().detectInteractionWithContext(
-                    opContext.toAidlContext(mOptions));
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
-                    if (ctx.operationState != null && ctx.operationState.getTag()
-                            == OperationState.fingerprintOperationState) {
-                        session.getSession().setIgnoreDisplayTouches(
-                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches);
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
-            return cancel;
-        } else {
-            return session.getSession().detectInteraction();
-        }
-    }
-
-    private void startDetectInteraction() throws RemoteException {
+    private void doDetectInteraction() throws RemoteException {
         final AidlSession session = getFreshDaemon();
 
         if (session.hasContextMethods()) {
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 a24ab1d..86ebabe 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
@@ -26,7 +26,6 @@
 import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
 import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.common.ICancellationSignal;
-import android.hardware.biometrics.common.OperationState;
 import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.fingerprint.Fingerprint;
 import android.hardware.fingerprint.FingerprintEnrollOptions;
@@ -40,7 +39,6 @@
 import android.util.Slog;
 import android.view.accessibility.AccessibilityManager;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.HardwareAuthTokenUtils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -209,11 +207,7 @@
 
         BiometricNotificationUtils.cancelBadCalibrationNotification(getContext());
         try {
-            if (Flags.deHidl()) {
-                startEnroll();
-            } else {
-                mCancellationSignal = doEnroll();
-            }
+            doEnroll();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when requesting enroll", e);
             onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_PROCESS,
@@ -222,35 +216,7 @@
         }
     }
 
-    private ICancellationSignal doEnroll() throws RemoteException {
-        final AidlSession session = getFreshDaemon();
-        final HardwareAuthToken hat =
-                HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
-
-        if (session.hasContextMethods()) {
-            final OperationContextExt opContext = getOperationContext();
-            final ICancellationSignal cancel = session.getSession().enrollWithContext(
-                    hat, opContext.toAidlContext());
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
-                    if (ctx.operationState != null && ctx.operationState.getTag()
-                            == OperationState.fingerprintOperationState) {
-                        session.getSession().setIgnoreDisplayTouches(
-                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches);
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
-            return cancel;
-        } else {
-            return session.getSession().enroll(hat);
-        }
-    }
-
-    private void startEnroll() throws RemoteException {
+    private void doEnroll() throws RemoteException {
         final AidlSession session = getFreshDaemon();
         final HardwareAuthToken hat =
                 HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 9290f8a..beb3f2f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -29,12 +29,10 @@
 import android.content.res.TypedArray;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
 import android.hardware.biometrics.SensorLocationInternal;
-import android.hardware.biometrics.common.ComponentInfo;
 import android.hardware.biometrics.fingerprint.IFingerprint;
 import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.biometrics.fingerprint.SensorProps;
@@ -50,10 +48,8 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
@@ -63,7 +59,6 @@
 import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
 import com.android.server.biometrics.AuthenticationStatsCollector;
 import com.android.server.biometrics.BiometricHandlerProvider;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
@@ -96,10 +91,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
 
 /**
  * Provider for a single instance of the {@link IFingerprint} HAL.
@@ -200,11 +193,7 @@
         mAuthenticationStateListeners = authenticationStateListeners;
         mHalInstanceName = halInstanceName;
         mFingerprintSensors = new SensorList<>(ActivityManager.getService());
-        if (Flags.deHidl()) {
-            mHandler = biometricHandlerProvider.getFingerprintHandler();
-        } else {
-            mHandler = new Handler(Looper.getMainLooper());
-        }
+        mHandler = biometricHandlerProvider.getFingerprintHandler();
         mLockoutResetDispatcher = lockoutResetDispatcher;
         mActivityTaskManager = ActivityTaskManager.getInstance();
         mTaskStackListener = new BiometricTaskStackListener();
@@ -230,66 +219,19 @@
 
     private void initSensors(boolean resetLockoutRequiresHardwareAuthToken, SensorProps[] props,
             GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
-        if (Flags.deHidl()) {
-            if (!resetLockoutRequiresHardwareAuthToken) {
-                Slog.d(getTag(), "Adding HIDL configs");
-                for (SensorProps sensorConfig: props) {
-                    addHidlSensors(sensorConfig, gestureAvailabilityDispatcher,
-                            resetLockoutRequiresHardwareAuthToken);
-                }
-            } else {
-                Slog.d(getTag(), "Adding AIDL configs");
-                final List<SensorLocationInternal> workaroundLocations =
-                        getWorkaroundSensorProps(mContext);
-                for (SensorProps prop : props) {
-                    addAidlSensors(prop, gestureAvailabilityDispatcher, workaroundLocations,
-                            resetLockoutRequiresHardwareAuthToken);
-                }
+        if (!resetLockoutRequiresHardwareAuthToken) {
+            Slog.d(getTag(), "Adding HIDL configs");
+            for (SensorProps sensorConfig: props) {
+                addHidlSensors(sensorConfig, gestureAvailabilityDispatcher,
+                        resetLockoutRequiresHardwareAuthToken);
             }
         } else {
+            Slog.d(getTag(), "Adding AIDL configs");
             final List<SensorLocationInternal> workaroundLocations =
                     getWorkaroundSensorProps(mContext);
-
             for (SensorProps prop : props) {
-                final int sensorId = prop.commonProps.sensorId;
-                final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-                if (prop.commonProps.componentInfo != null) {
-                    for (ComponentInfo info : prop.commonProps.componentInfo) {
-                        componentInfo.add(new ComponentInfoInternal(info.componentId,
-                                info.hardwareVersion, info.firmwareVersion, info.serialNumber,
-                                info.softwareVersion));
-                    }
-                }
-                final FingerprintSensorPropertiesInternal internalProp =
-                        new FingerprintSensorPropertiesInternal(prop.commonProps.sensorId,
-                                prop.commonProps.sensorStrength,
-                                prop.commonProps.maxEnrollmentsPerUser,
-                                componentInfo,
-                                prop.sensorType,
-                                prop.halControlsIllumination,
-                                true /* resetLockoutRequiresHardwareAuthToken */,
-                                !workaroundLocations.isEmpty() ? workaroundLocations :
-                                        Arrays.stream(prop.sensorLocations).map(
-                                                        location -> new SensorLocationInternal(
-                                                                location.display,
-                                                                location.sensorLocationX,
-                                                                location.sensorLocationY,
-                                                                location.sensorRadius))
-                                                .collect(Collectors.toList()));
-                final Sensor sensor = new Sensor(this, mContext, mHandler, internalProp,
-                        mBiometricContext);
-                sensor.init(gestureAvailabilityDispatcher, mLockoutResetDispatcher);
-                final int sessionUserId =
-                        sensor.getLazySession().get() == null ? UserHandle.USER_NULL :
-                                sensor.getLazySession().get().getUserId();
-                mFingerprintSensors.addSensor(sensorId, sensor, sessionUserId,
-                        new SynchronousUserSwitchObserver() {
-                            @Override
-                            public void onUserSwitching(int newUserId) {
-                                scheduleInternalCleanup(sensorId, newUserId, null /* callback */);
-                            }
-                        });
-                Slog.d(getTag(), "Added: " + mFingerprintSensors.get(sensorId).toString());
+                addAidlSensors(prop, gestureAvailabilityDispatcher, workaroundLocations,
+                        resetLockoutRequiresHardwareAuthToken);
             }
         }
     }
@@ -546,23 +488,7 @@
                     mFingerprintSensors.get(sensorId).getSensorProperties(),
                     mUdfpsOverlayController, mSidefpsController,
                     mAuthenticationStateListeners, maxTemplatesPerUser, enrollReason, options);
-            if (Flags.deHidl()) {
-                scheduleForSensor(sensorId, client, mBiometricStateCallback);
-            } else {
-                scheduleForSensor(sensorId, client, new ClientMonitorCompositeCallback(
-                        mBiometricStateCallback, new ClientMonitorCallback() {
-                            @Override
-                            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                                    boolean success) {
-                                ClientMonitorCallback.super.onClientFinished(
-                                        clientMonitor, success);
-                                if (success) {
-                                    scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
-                                    scheduleInvalidationRequest(sensorId, userId);
-                                }
-                            }
-                        }));
-            }
+            scheduleForSensor(sensorId, client, mBiometricStateCallback);
         });
         return id;
     }
@@ -605,13 +531,8 @@
             final int userId = options.getUserId();
             final int sensorId = options.getSensorId();
             final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
-            final LockoutTracker lockoutTracker;
-            if (Flags.deHidl()) {
-                lockoutTracker = mFingerprintSensors.get(sensorId)
-                        .getLockoutTracker(true /* forAuth */);
-            } else {
-                lockoutTracker = null;
-            }
+            final LockoutTracker lockoutTracker = mFingerprintSensors.get(sensorId)
+                    .getLockoutTracker(true /* forAuth */);
             final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
                     mContext, mFingerprintSensors.get(sensorId).getLazySession(), token, requestId,
                     callback, operationId, restricted, options, cookie,
@@ -622,22 +543,16 @@
                     mTaskStackListener,
                     mUdfpsOverlayController, mSidefpsController,
                     mAuthenticationStateListeners, allowBackgroundAuthentication,
-                    mFingerprintSensors.get(sensorId).getSensorProperties(), mHandler,
+                    mFingerprintSensors.get(sensorId).getSensorProperties(),
                     Utils.getCurrentStrength(sensorId),
-                    SystemClock.elapsedRealtimeClock(),
                     lockoutTracker);
             scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
 
                 @Override
                 public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
                     mBiometricStateCallback.onClientStarted(clientMonitor);
-                    if (Flags.deHidl()) {
-                        mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
-                                mAuthSessionCoordinator.authStartedFor(userId, sensorId,
-                                        requestId));
-                    } else {
-                        mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId);
-                    }
+                    mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
+                            mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId));
                 }
 
                 @Override
@@ -649,15 +564,10 @@
                 public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
                         boolean success) {
                     mBiometricStateCallback.onClientFinished(clientMonitor, success);
-                    if (Flags.deHidl()) {
-                        mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
-                                mAuthSessionCoordinator.authEndedFor(userId,
-                                        Utils.getCurrentStrength(sensorId), sensorId, requestId,
-                                        success));
-                    } else {
-                        mAuthSessionCoordinator.authEndedFor(userId,
-                                Utils.getCurrentStrength(sensorId), sensorId, requestId, success);
-                    }
+                    mBiometricHandlerProvider.getBiometricCallbackHandler().post(() ->
+                            mAuthSessionCoordinator.authEndedFor(userId,
+                                    Utils.getCurrentStrength(sensorId), sensorId, requestId,
+                                    success));
                 }
             });
 
@@ -764,10 +674,7 @@
 
     @Override
     public boolean isHardwareDetected(int sensorId) {
-        if (Flags.deHidl()) {
-            return mFingerprintSensors.get(sensorId).isHardwareDetected(mHalInstanceName);
-        }
-        return hasHalInstance();
+        return mFingerprintSensors.get(sensorId).isHardwareDetected(mHalInstanceName);
     }
 
     @Override
@@ -805,12 +712,7 @@
 
     @Override
     public int getLockoutModeForUser(int sensorId, int userId) {
-        if (Flags.deHidl()) {
-            return mFingerprintSensors.get(sensorId).getLockoutModeForUser(userId);
-        } else {
-            return mBiometricContext.getAuthSessionCoordinator().getLockoutStateFor(userId,
-                    Utils.getCurrentStrength(sensorId));
-        }
+        return mFingerprintSensors.get(sensorId).getLockoutModeForUser(userId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index af88c62..b7e3f70 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -42,7 +42,6 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.SensorServiceStateProto;
 import com.android.server.biometrics.SensorStateProto;
 import com.android.server.biometrics.UserStateProto;
@@ -58,7 +57,6 @@
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.StartUserClient;
 import com.android.server.biometrics.sensors.StopUserClient;
-import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.UserSwitchProvider;
 import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
 import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
@@ -110,13 +108,6 @@
     }
 
     Sensor(@NonNull FingerprintProvider provider, @NonNull Context context,
-            @NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
-            @NonNull BiometricContext biometricContext) {
-        this(provider, context, handler, sensorProperties,
-                biometricContext, null);
-    }
-
-    Sensor(@NonNull FingerprintProvider provider, @NonNull Context context,
             @NonNull Handler handler, @NonNull SensorProps sensorProp,
             @NonNull BiometricContext biometricContext,
             @NonNull List<SensorLocationInternal> workaroundLocation,
@@ -131,13 +122,8 @@
      */
     public void init(@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
-        if (Flags.deHidl()) {
-            setScheduler(getBiometricSchedulerForInit(gestureAvailabilityDispatcher,
-                    lockoutResetDispatcher));
-        } else {
-            setScheduler(getUserAwareBiometricSchedulerForInit(gestureAvailabilityDispatcher,
-                    lockoutResetDispatcher));
-        }
+        setScheduler(getBiometricSchedulerForInit(gestureAvailabilityDispatcher,
+                lockoutResetDispatcher));
         mLockoutTracker = new LockoutCache();
         mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
     }
@@ -168,7 +154,7 @@
                         final AidlResponseHandler resultController = new AidlResponseHandler(
                                 mContext, mScheduler, sensorId, newUserId,
                                 mLockoutTracker, lockoutResetDispatcher,
-                                mBiometricContext.getAuthSessionCoordinator(), () -> {},
+                                mBiometricContext.getAuthSessionCoordinator(),
                                 new AidlResponseHandler.AidlResponseHandlerCallback() {
                                     @Override
                                     public void onEnrollSuccess() {
@@ -192,45 +178,6 @@
                 });
     }
 
-    private UserAwareBiometricScheduler<ISession, AidlSession>
-            getUserAwareBiometricSchedulerForInit(
-                    GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
-                    LockoutResetDispatcher lockoutResetDispatcher) {
-        return new UserAwareBiometricScheduler<>(TAG,
-                BiometricScheduler.sensorTypeFromFingerprintProperties(mSensorProperties),
-                gestureAvailabilityDispatcher,
-                () -> mCurrentSession != null ? mCurrentSession.getUserId() : UserHandle.USER_NULL,
-                new UserAwareBiometricScheduler.UserSwitchCallback() {
-                    @NonNull
-                    @Override
-                    public StopUserClient<ISession> getStopUserClient(int userId) {
-                        return new FingerprintStopUserClient(mContext,
-                                () -> mLazySession.get().getSession(), mToken,
-                                userId, mSensorProperties.sensorId,
-                                BiometricLogger.ofUnknown(mContext), mBiometricContext,
-                                () -> mCurrentSession = null);
-                    }
-
-                    @NonNull
-                    @Override
-                    public StartUserClient<IFingerprint, ISession> getStartUserClient(
-                            int newUserId) {
-                        final int sensorId = mSensorProperties.sensorId;
-
-                        final AidlResponseHandler resultController = new AidlResponseHandler(
-                                mContext, mScheduler, sensorId, newUserId,
-                                mLockoutTracker, lockoutResetDispatcher,
-                                mBiometricContext.getAuthSessionCoordinator(), () -> {
-                                    Slog.e(TAG, "Fingerprint hardware unavailable.");
-                                    mCurrentSession = null;
-                                });
-
-                        return Sensor.this.getStartUserClient(resultController, sensorId,
-                                newUserId);
-                    }
-                });
-    }
-
     private FingerprintStartUserClient getStartUserClient(AidlResponseHandler resultController,
             int sensorId, int newUserId) {
         final StartUserClient.UserStartedCallback<ISession> userStartedCallback =
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
deleted file mode 100644
index fc037ae..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.ITestSession;
-import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintEnrollOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-
-/**
- * A test session implementation for the {@link Fingerprint21} provider. See
- * {@link android.hardware.biometrics.BiometricTestSession}.
- */
-public class BiometricTestSessionImpl extends ITestSession.Stub {
-
-    private static final String TAG = "BiometricTestSessionImpl";
-
-    @NonNull private final Context mContext;
-    private final int mSensorId;
-    @NonNull private final ITestSessionCallback mCallback;
-    @NonNull private final BiometricStateCallback mBiometricStateCallback;
-    @NonNull private final Fingerprint21 mFingerprint21;
-    @NonNull private final Fingerprint21.HalResultController mHalResultController;
-    @NonNull private final Set<Integer> mEnrollmentIds;
-    @NonNull private final Random mRandom;
-
-    /**
-     * Internal receiver currently only used for enroll. Results do not need to be forwarded to the
-     * test, since enrollment is a platform-only API. The authentication path is tested through
-     * the public FingerprintManager APIs and does not use this receiver.
-     */
-    private final IFingerprintServiceReceiver mReceiver = new IFingerprintServiceReceiver.Stub() {
-        @Override
-        public void onEnrollResult(Fingerprint fp, int remaining) {
-
-        }
-
-        @Override
-        public void onAcquired(int acquiredInfo, int vendorCode) {
-
-        }
-
-        @Override
-        public void onAuthenticationSucceeded(Fingerprint fp, int userId,
-                boolean isStrongBiometric) {
-
-        }
-
-        @Override
-        public void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) {
-
-        }
-
-        @Override
-        public void onAuthenticationFailed() {
-
-        }
-
-        @Override
-        public void onError(int error, int vendorCode) {
-
-        }
-
-        @Override
-        public void onRemoved(Fingerprint fp, int remaining) {
-
-        }
-
-        @Override
-        public void onChallengeGenerated(int sensorId, int userId, long challenge) {
-
-        }
-
-        @Override
-        public void onUdfpsPointerDown(int sensorId) {
-
-        }
-
-        @Override
-        public void onUdfpsPointerUp(int sensorId) {
-
-        }
-
-        @Override
-        public void onUdfpsOverlayShown() {
-
-        }
-    };
-
-    BiometricTestSessionImpl(@NonNull Context context, int sensorId,
-            @NonNull ITestSessionCallback callback,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull Fingerprint21 fingerprint21,
-            @NonNull Fingerprint21.HalResultController halResultController) {
-        mContext = context;
-        mSensorId = sensorId;
-        mCallback = callback;
-        mFingerprint21 = fingerprint21;
-        mBiometricStateCallback = biometricStateCallback;
-        mHalResultController = halResultController;
-        mEnrollmentIds = new HashSet<>();
-        mRandom = new Random();
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void setTestHalEnabled(boolean enabled) {
-
-        super.setTestHalEnabled_enforcePermission();
-
-        mFingerprint21.setTestHalEnabled(enabled);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void startEnroll(int userId) {
-
-        super.startEnroll_enforcePermission();
-
-        mFingerprint21.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
-                mContext.getOpPackageName(), FingerprintManager.ENROLL_ENROLL,
-                (new FingerprintEnrollOptions.Builder()).build());
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void finishEnroll(int userId) {
-
-        super.finishEnroll_enforcePermission();
-
-        int nextRandomId = mRandom.nextInt();
-        while (mEnrollmentIds.contains(nextRandomId)) {
-            nextRandomId = mRandom.nextInt();
-        }
-
-        mEnrollmentIds.add(nextRandomId);
-        mHalResultController.onEnrollResult(0 /* deviceId */,
-                nextRandomId /* fingerId */, userId, 0);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void acceptAuthentication(int userId)  {
-
-        // Fake authentication with any of the existing fingers
-        super.acceptAuthentication_enforcePermission();
-
-        List<Fingerprint> fingerprints = FingerprintUtils.getLegacyInstance(mSensorId)
-                .getBiometricsForUser(mContext, userId);
-        if (fingerprints.isEmpty()) {
-            Slog.w(TAG, "No fingerprints, returning");
-            return;
-        }
-        final int fid = fingerprints.get(0).getBiometricId();
-        final ArrayList<Byte> hat = new ArrayList<>(Collections.nCopies(69, (byte) 0));
-        mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void rejectAuthentication(int userId)  {
-
-        super.rejectAuthentication_enforcePermission();
-
-        mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* fingerId */, userId, null);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void notifyAcquired(int userId, int acquireInfo)  {
-
-        super.notifyAcquired_enforcePermission();
-
-        mHalResultController.onAcquired(0 /* deviceId */, acquireInfo, 0 /* vendorCode */);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void notifyError(int userId, int errorCode)  {
-
-        super.notifyError_enforcePermission();
-
-        mHalResultController.onError(0 /* deviceId */, errorCode, 0 /* vendorCode */);
-    }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public void cleanupInternalState(int userId)  {
-
-        super.cleanupInternalState_enforcePermission();
-
-        mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                try {
-                    mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                try {
-                    mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-        });
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
deleted file mode 100644
index 33e448b..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.SynchronousUserSwitchObserver;
-import android.app.TaskStackListener;
-import android.app.UserSwitchObserver;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.IInvalidationCallback;
-import android.hardware.biometrics.ITestSession;
-import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.biometrics.fingerprint.PointerContext;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintAuthenticateOptions;
-import android.hardware.fingerprint.FingerprintEnrollOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.hardware.fingerprint.ISidefpsController;
-import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IHwBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
-import com.android.server.biometrics.AuthenticationStatsCollector;
-import com.android.server.biometrics.Flags;
-import com.android.server.biometrics.SensorServiceStateProto;
-import com.android.server.biometrics.SensorStateProto;
-import com.android.server.biometrics.UserStateProto;
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto;
-import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto;
-import com.android.server.biometrics.fingerprint.PerformanceStatsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.AcquisitionClient;
-import com.android.server.biometrics.sensors.AuthSessionCoordinator;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.AuthenticationConsumer;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.EnumerateConsumer;
-import com.android.server.biometrics.sensors.ErrorConsumer;
-import com.android.server.biometrics.sensors.LockoutCache;
-import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.RemovalConsumer;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
-import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
-import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-import com.android.server.biometrics.sensors.fingerprint.aidl.AidlResponseHandler;
-import com.android.server.biometrics.sensors.fingerprint.aidl.AidlSession;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Supplier;
-
-/**
- * Supports a single instance of the {@link android.hardware.biometrics.fingerprint.V2_1} or
- * its extended minor versions.
- */
-public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider {
-
-    private static final String TAG = "Fingerprint21";
-    private static final int ENROLL_TIMEOUT_SEC = 60;
-
-    private boolean mTestHalEnabled;
-
-    final Context mContext;
-    @NonNull private final BiometricStateCallback mBiometricStateCallback;
-    @NonNull private final AuthenticationStateListeners mAuthenticationStateListeners;
-    private final ActivityTaskManager mActivityTaskManager;
-    @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
-    private final BiometricScheduler<IBiometricsFingerprint, AidlSession> mScheduler;
-    private final Handler mHandler;
-    private final LockoutResetDispatcher mLockoutResetDispatcher;
-    private final LockoutFrameworkImpl mLockoutTracker;
-    private final BiometricTaskStackListener mTaskStackListener;
-    private final Supplier<IBiometricsFingerprint> mLazyDaemon;
-    private final Map<Integer, Long> mAuthenticatorIds;
-
-    @Nullable private IBiometricsFingerprint mDaemon;
-    @NonNull private final HalResultController mHalResultController;
-    @Nullable private IUdfpsOverlayController mUdfpsOverlayController;
-
-    // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-    @Nullable private ISidefpsController mSidefpsController;
-    @NonNull private final BiometricContext mBiometricContext;
-    @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
-    // for requests that do not use biometric prompt
-    @NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
-    private int mCurrentUserId = UserHandle.USER_NULL;
-    private final boolean mIsUdfps;
-    private final int mSensorId;
-    private final boolean mIsPowerbuttonFps;
-    private AidlSession mSession;
-
-    private final class BiometricTaskStackListener extends TaskStackListener {
-        @Override
-        public void onTaskStackChanged() {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AuthenticationClient)) {
-                    Slog.e(TAG, "Task stack changed for client: " + client);
-                    return;
-                }
-                if (Utils.isKeyguard(mContext, client.getOwnerString())
-                        || Utils.isSystem(mContext, client.getOwnerString())) {
-                    return; // Keyguard is always allowed
-                }
-
-                if (Utils.isBackground(client.getOwnerString())
-                        && !client.isAlreadyDone()) {
-                    Slog.e(TAG, "Stopping background authentication,"
-                            + " currentClient: " + client);
-                    mScheduler.cancelAuthenticationOrDetection(
-                            client.getToken(), client.getRequestId());
-                }
-            });
-        }
-    }
-
-    private final LockoutFrameworkImpl.LockoutResetCallback mLockoutResetCallback =
-            new LockoutFrameworkImpl.LockoutResetCallback() {
-                @Override
-                public void onLockoutReset(int userId) {
-                    mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorProperties.sensorId);
-                }
-            };
-
-    private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
-        @Override
-        public void onUserSwitching(int newUserId) {
-            scheduleInternalCleanup(newUserId, null /* callback */);
-        }
-    };
-
-    public static class HalResultController extends IBiometricsFingerprintClientCallback.Stub {
-
-        /**
-         * Interface to sends results to the HalResultController's owner.
-         */
-        public interface Callback {
-            /**
-             * Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
-             */
-            void onHardwareUnavailable();
-        }
-
-        private final int mSensorId;
-        @NonNull private final Context mContext;
-        @NonNull final Handler mHandler;
-        @NonNull final BiometricScheduler<IBiometricsFingerprint, AidlSession> mScheduler;
-        @Nullable private Callback mCallback;
-
-        HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
-                @NonNull BiometricScheduler<IBiometricsFingerprint, AidlSession> scheduler) {
-            mSensorId = sensorId;
-            mContext = context;
-            mHandler = handler;
-            mScheduler = scheduler;
-        }
-
-        public void setCallback(@Nullable Callback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof FingerprintEnrollClient)) {
-                    Slog.e(TAG, "onEnrollResult for non-enroll client: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final int currentUserId = client.getTargetUserId();
-                final CharSequence name = FingerprintUtils.getLegacyInstance(mSensorId)
-                        .getUniqueName(mContext, currentUserId);
-                final Fingerprint fingerprint = new Fingerprint(name, groupId, fingerId, deviceId);
-
-                final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client;
-                enrollClient.onEnrollResult(fingerprint, remaining);
-            });
-        }
-
-        @Override
-        public void onAcquired(long deviceId, int acquiredInfo, int vendorCode) {
-            onAcquired_2_2(deviceId, acquiredInfo, vendorCode);
-        }
-
-        @Override
-        public void onAcquired_2_2(long deviceId, int acquiredInfo, int vendorCode) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AcquisitionClient)) {
-                    Slog.e(TAG, "onAcquired for non-acquisition client: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
-                acquisitionClient.onAcquired(acquiredInfo, vendorCode);
-            });
-        }
-
-        @Override
-        public void onAuthenticated(long deviceId, int fingerId, int groupId,
-                ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AuthenticationConsumer)) {
-                    Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final AuthenticationConsumer authenticationConsumer =
-                        (AuthenticationConsumer) client;
-                final boolean authenticated = fingerId != 0;
-                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                authenticationConsumer.onAuthenticated(fp, authenticated, token);
-            });
-        }
-
-        @Override
-        public void onError(long deviceId, int error, int vendorCode) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                Slog.d(TAG, "handleError"
-                        + ", client: " + Utils.getClientName(client)
-                        + ", error: " + error
-                        + ", vendorCode: " + vendorCode);
-                if (!(client instanceof ErrorConsumer)) {
-                    Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
-                    return;
-                }
-
-                final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-                errorConsumer.onError(error, vendorCode);
-
-                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
-                    Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
-                    if (mCallback != null) {
-                        mCallback.onHardwareUnavailable();
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
-            mHandler.post(() -> {
-                Slog.d(TAG, "Removed, fingerId: " + fingerId + ", remaining: " + remaining);
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof RemovalConsumer)) {
-                    Slog.e(TAG, "onRemoved for non-removal consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                final RemovalConsumer removalConsumer = (RemovalConsumer) client;
-                removalConsumer.onRemoved(fp, remaining);
-            });
-        }
-
-        @Override
-        public void onEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof EnumerateConsumer)) {
-                    Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
-                            + Utils.getClientName(client));
-                    return;
-                }
-
-                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
-                enumerateConsumer.onEnumerationResult(fp, remaining);
-            });
-        }
-    }
-
-    @VisibleForTesting
-    Fingerprint21(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @NonNull BiometricScheduler<IBiometricsFingerprint, AidlSession> scheduler,
-            @NonNull Handler handler,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull HalResultController controller,
-            @NonNull BiometricContext biometricContext) {
-        mContext = context;
-        mBiometricStateCallback = biometricStateCallback;
-        mAuthenticationStateListeners = authenticationStateListeners;
-        mBiometricContext = biometricContext;
-
-        mSensorProperties = sensorProps;
-        mSensorId = sensorProps.sensorId;
-        mIsUdfps = sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
-                || sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
-        mIsPowerbuttonFps = sensorProps.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON;
-
-        mScheduler = scheduler;
-        mHandler = handler;
-        mActivityTaskManager = ActivityTaskManager.getInstance();
-        mTaskStackListener = new BiometricTaskStackListener();
-        mAuthenticatorIds = Collections.synchronizedMap(new HashMap<>());
-        mLazyDaemon = Fingerprint21.this::getDaemon;
-        mLockoutResetDispatcher = lockoutResetDispatcher;
-        mLockoutTracker = new LockoutFrameworkImpl(context, mLockoutResetCallback);
-        mHalResultController = controller;
-        mHalResultController.setCallback(() -> {
-            mDaemon = null;
-            mCurrentUserId = UserHandle.USER_NULL;
-        });
-
-        AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
-                new AuthenticationStatsBroadcastReceiver(
-                        mContext,
-                        BiometricsProtoEnums.MODALITY_FINGERPRINT,
-                        (AuthenticationStatsCollector collector) -> {
-                            Slog.d(TAG, "Initializing AuthenticationStatsCollector");
-                            mAuthenticationStatsCollector = collector;
-                        });
-
-        try {
-            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to register user switch observer");
-        }
-    }
-
-    public static Fingerprint21 newInstance(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @NonNull Handler handler,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
-        final BiometricScheduler<IBiometricsFingerprint, AidlSession> scheduler =
-                new BiometricScheduler<>(
-                        BiometricScheduler.sensorTypeFromFingerprintProperties(sensorProps),
-                        gestureAvailabilityDispatcher);
-        final HalResultController controller = new HalResultController(sensorProps.sensorId,
-                context, handler, scheduler);
-        return new Fingerprint21(context, biometricStateCallback, authenticationStateListeners,
-                sensorProps, scheduler, handler, lockoutResetDispatcher, controller,
-                BiometricContext.getInstance(context));
-    }
-
-    @Override
-    public void serviceDied(long cookie) {
-        Slog.e(TAG, "HAL died");
-        mHandler.post(() -> {
-            PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId)
-                    .incrementHALDeathCount();
-            mDaemon = null;
-            mCurrentUserId = UserHandle.USER_NULL;
-
-            final BaseClientMonitor client = mScheduler.getCurrentClient();
-            if (client instanceof ErrorConsumer) {
-                Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
-                final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-                errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                        0 /* vendorCode */);
-
-                FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
-                        BiometricsProtoEnums.MODALITY_FINGERPRINT,
-                        BiometricsProtoEnums.ISSUE_HAL_DEATH,
-                        -1 /* sensorId */);
-            }
-
-            mScheduler.recordCrashState();
-            mScheduler.reset();
-        });
-    }
-
-    synchronized AidlSession getSession() {
-        if (mDaemon != null && mSession != null) {
-            return mSession;
-        } else {
-            return mSession = new AidlSession(this::getDaemon,
-                    mCurrentUserId, new AidlResponseHandler(mContext,
-                    mScheduler, mSensorId, mCurrentUserId, new LockoutCache(),
-                    mLockoutResetDispatcher, new AuthSessionCoordinator(), () -> {
-                        mDaemon = null;
-                        mCurrentUserId = UserHandle.USER_NULL;
-                    }));
-        }
-    }
-
-    @VisibleForTesting
-    synchronized IBiometricsFingerprint getDaemon() {
-        if (mTestHalEnabled) {
-            final TestHal testHal = new TestHal(mContext, mSensorId);
-            testHal.setNotify(mHalResultController);
-            return testHal;
-        }
-
-        if (mDaemon != null) {
-            return mDaemon;
-        }
-
-        Slog.d(TAG, "Daemon was null, reconnecting, current operation: "
-                + mScheduler.getCurrentClient());
-        try {
-            mDaemon = IBiometricsFingerprint.getService();
-        } catch (java.util.NoSuchElementException e) {
-            // Service doesn't exist or cannot be opened.
-            Slog.w(TAG, "NoSuchElementException", e);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to get fingerprint HAL", e);
-        }
-
-        if (mDaemon == null) {
-            Slog.w(TAG, "Fingerprint HAL not available");
-            return null;
-        }
-
-        mDaemon.asBinder().linkToDeath(this, 0 /* flags */);
-
-        // HAL ID for these HIDL versions are only used to determine if callbacks have been
-        // successfully set.
-        long halId = 0;
-        try {
-            halId = mDaemon.setNotify(mHalResultController);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to set callback for fingerprint HAL", e);
-            mDaemon = null;
-        }
-
-        Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId);
-        if (halId != 0) {
-            scheduleLoadAuthenticatorIds();
-            scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */);
-        } else {
-            Slog.e(TAG, "Unable to set callback");
-            mDaemon = null;
-        }
-
-        return mDaemon;
-    }
-
-    @Nullable IUdfpsOverlayController getUdfpsOverlayController() {
-        return mUdfpsOverlayController;
-    }
-
-    private void scheduleLoadAuthenticatorIds() {
-        // Note that this can be performed on the scheduler (as opposed to being done immediately
-        // when the HAL is (re)loaded, since
-        // 1) If this is truly the first time it's being performed (e.g. system has just started),
-        //    this will be run very early and way before any applications need to generate keys.
-        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
-        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
-        //    is safe because authenticatorIds only change when A) new template has been enrolled,
-        //    or B) all templates are removed.
-        mHandler.post(() -> {
-            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
-                final int targetUserId = user.id;
-                if (!mAuthenticatorIds.containsKey(targetUserId)) {
-                    scheduleUpdateActiveUserWithoutHandler(targetUserId, true /* force */);
-                }
-            }
-        });
-    }
-
-    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
-        scheduleUpdateActiveUserWithoutHandler(targetUserId, false /* force */);
-    }
-
-    /**
-     * Schedules the {@link FingerprintUpdateActiveUserClient} without posting the work onto the
-     * handler. Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
-     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
-     * this operation on the same lambda/runnable as those operations so that the ordering is
-     * correct.
-     *
-     * @param targetUserId Switch to this user, and update their authenticatorId
-     * @param force Always retrieve the authenticatorId, even if we are already the targetUserId
-     */
-    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId, boolean force) {
-        final boolean hasEnrolled =
-                !getEnrolledFingerprints(mSensorProperties.sensorId, targetUserId).isEmpty();
-        final FingerprintUpdateActiveUserClientLegacy client =
-                new FingerprintUpdateActiveUserClientLegacy(mContext, mLazyDaemon, targetUserId,
-                        mContext.getOpPackageName(), mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext,
-                        this::getCurrentUser, hasEnrolled, mAuthenticatorIds, force);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                if (success) {
-                    if (mCurrentUserId != targetUserId) {
-                        // Create new session with updated user ID
-                        mSession = null;
-                    }
-                    mCurrentUserId = targetUserId;
-                } else {
-                    Slog.w(TAG, "Failed to change user, still: " + mCurrentUserId);
-                }
-            }
-        });
-    }
-
-    private int getCurrentUser() {
-        return mCurrentUserId;
-    }
-
-    @Override
-    public boolean containsSensor(int sensorId) {
-        return mSensorProperties.sensorId == sensorId;
-    }
-
-    @Override
-    @NonNull
-    public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
-        final List<FingerprintSensorPropertiesInternal> properties = new ArrayList<>();
-        properties.add(mSensorProperties);
-        return properties;
-    }
-
-    @Nullable
-    @Override
-    public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId) {
-        return mSensorProperties;
-    }
-
-    @Override
-    public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) {
-        // Fingerprint2.1 keeps track of lockout in the framework. Let's just do it on the handler
-        // thread.
-        mHandler.post(() -> {
-            if (Flags.deHidl()) {
-                scheduleResetLockoutAidl(sensorId, userId, hardwareAuthToken);
-            } else {
-                scheduleResetLockoutHidl(sensorId, userId);
-            }
-        });
-    }
-
-    private void scheduleResetLockoutAidl(int sensorId, int userId,
-            @Nullable byte[] hardwareAuthToken) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintResetLockoutClient client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintResetLockoutClient(
-                        mContext, this::getSession, userId, mContext.getOpPackageName(),
-                        sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, hardwareAuthToken, mLockoutTracker,
-                        mLockoutResetDispatcher,
-                        Utils.getCurrentStrength(sensorId));
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleResetLockoutHidl(int sensorId, int userId) {
-        final FingerprintResetLockoutClient client = new FingerprintResetLockoutClient(mContext,
-                userId, mContext.getOpPackageName(), sensorId,
-                createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN,
-                        mAuthenticationStatsCollector),
-                mBiometricContext, mLockoutTracker);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    @Override
-    public void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            if (Flags.deHidl()) {
-                scheduleGenerateChallengeAidl(userId, token, receiver, opPackageName);
-            } else {
-                scheduleGenerateChallengeHidl(userId, token, receiver, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleGenerateChallengeAidl(int userId, @NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintGenerateChallengeClient client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintGenerateChallengeClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
-                        mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleGenerateChallengeHidl(int userId, @NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName) {
-        final FingerprintGenerateChallengeClient client =
-                new FingerprintGenerateChallengeClient(mContext, mLazyDaemon, token,
-                        new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
-                        mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    @Override
-    public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
-            @NonNull String opPackageName, long challenge) {
-        mHandler.post(() -> {
-            if (Flags.deHidl()) {
-                scheduleRevokeChallengeAidl(userId, token, opPackageName);
-            } else {
-                scheduleRevokeChallengeHidl(userId, token, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleRevokeChallengeAidl(int userId, @NonNull IBinder token,
-            @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintRevokeChallengeClient client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintRevokeChallengeClient(
-                        mContext, this::getSession,
-                        token, userId, opPackageName,
-                        mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, 0L);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    private void scheduleRevokeChallengeHidl(int userId, @NonNull IBinder token,
-            @NonNull String opPackageName) {
-        final FingerprintRevokeChallengeClient client = new FingerprintRevokeChallengeClient(
-                mContext, mLazyDaemon, token, userId, opPackageName,
-                mSensorProperties.sensorId,
-                createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN,
-                        mAuthenticationStatsCollector),
-                mBiometricContext);
-        mScheduler.scheduleClientMonitor(client);
-    }
-
-    @Override
-    public long scheduleEnroll(int sensorId, @NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName,
-            @FingerprintManager.EnrollReason int enrollReason,
-            @NonNull FingerprintEnrollOptions options) {
-        final long id = mRequestCounter.incrementAndGet();
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleEnrollAidl(token, hardwareAuthToken, userId, receiver,
-                        opPackageName, enrollReason, id, options);
-            } else {
-                scheduleEnrollHidl(token, hardwareAuthToken, userId, receiver,
-                        opPackageName, enrollReason, id, options);
-            }
-        });
-        return id;
-    }
-
-    private void scheduleEnrollHidl(@NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName,
-            @FingerprintManager.EnrollReason int enrollReason, long id,
-            @NonNull FingerprintEnrollOptions options) {
-        final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
-                mLazyDaemon, token, id, new ClientMonitorCallbackConverter(receiver),
-                userId, hardwareAuthToken, opPackageName,
-                FingerprintUtils.getLegacyInstance(mSensorId), ENROLL_TIMEOUT_SEC,
-                mSensorProperties.sensorId,
-                createLogger(BiometricsProtoEnums.ACTION_ENROLL,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, mUdfpsOverlayController,
-                // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-                mSidefpsController,
-                mAuthenticationStateListeners, enrollReason, options);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                mBiometricStateCallback.onClientStarted(clientMonitor);
-            }
-
-            @Override
-            public void onBiometricAction(int action) {
-                mBiometricStateCallback.onBiometricAction(action);
-            }
-
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                mBiometricStateCallback.onClientFinished(clientMonitor, success);
-                if (success) {
-                    // Update authenticatorIds
-                    scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId(),
-                            true /* force */);
-                }
-            }
-        });
-    }
-
-    private void scheduleEnrollAidl(@NonNull IBinder token,
-            @NonNull byte[] hardwareAuthToken, int userId,
-            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName,
-            @FingerprintManager.EnrollReason int enrollReason, long id,
-            @NonNull FingerprintEnrollOptions options) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintEnrollClient
-                client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintEnrollClient(
-                        mContext,
-                        this::getSession, token, id,
-                        new ClientMonitorCallbackConverter(receiver),
-                        userId, hardwareAuthToken, opPackageName,
-                        FingerprintUtils.getLegacyInstance(mSensorId),
-                        mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_ENROLL,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, null /* sensorProps */,
-                        mUdfpsOverlayController,
-                        // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-                        mSidefpsController,
-                        mAuthenticationStateListeners,
-                        mContext.getResources().getInteger(
-                                com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser),
-                        enrollReason, options);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
-            @Override
-            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
-                mBiometricStateCallback.onClientStarted(clientMonitor);
-            }
-
-            @Override
-            public void onBiometricAction(int action) {
-                mBiometricStateCallback.onBiometricAction(action);
-            }
-
-            @Override
-            public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
-                    boolean success) {
-                mBiometricStateCallback.onClientFinished(clientMonitor, success);
-                if (success) {
-                    // Update authenticatorIds
-                    scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId(),
-                            true /* force */);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) {
-        mHandler.post(() -> mScheduler.cancelEnrollment(token, requestId));
-    }
-
-    @Override
-    public long scheduleFingerDetect(@NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            int statsClient) {
-        final long id = mRequestCounter.incrementAndGet();
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(options.getUserId());
-
-            final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
-
-            if (Flags.deHidl()) {
-                scheduleFingerDetectAidl(token, listener, options, statsClient, id,
-                        isStrongBiometric);
-            } else {
-                scheduleFingerDetectHidl(token, listener, options, statsClient, id,
-                        isStrongBiometric);
-            }
-        });
-
-        return id;
-    }
-
-    private void scheduleFingerDetectHidl(@NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            int statsClient, long id, boolean isStrongBiometric) {
-        final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
-                mLazyDaemon, token, id, listener, options,
-                createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                        mAuthenticationStatsCollector),
-                mBiometricContext, mUdfpsOverlayController, isStrongBiometric);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    private void scheduleFingerDetectAidl(@NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            int statsClient, long id, boolean isStrongBiometric) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintDetectClient
-                client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintDetectClient(
-                        mContext,
-                        this::getSession, token, id, listener, options,
-                        createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, mUdfpsOverlayController, isStrongBiometric);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    @Override
-    public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            long requestId, boolean restricted, int statsClient,
-            boolean allowBackgroundAuthentication) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(options.getUserId());
-
-            final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
-
-            if (Flags.deHidl()) {
-                scheduleAuthenticateAidl(token, operationId, cookie, listener, options, requestId,
-                        restricted, statsClient, allowBackgroundAuthentication, isStrongBiometric);
-            } else {
-                scheduleAuthenticateHidl(token, operationId, cookie, listener, options, requestId,
-                        restricted, statsClient, allowBackgroundAuthentication, isStrongBiometric);
-            }
-        });
-    }
-
-    private void scheduleAuthenticateAidl(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            long requestId, boolean restricted, int statsClient,
-            boolean allowBackgroundAuthentication, boolean isStrongBiometric) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintAuthenticationClient
-                client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintAuthenticationClient(
-                        mContext, this::getSession, token, requestId, listener, operationId,
-                        restricted, options, cookie, false /* requireConfirmation */,
-                        createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext, isStrongBiometric,
-                        mTaskStackListener,
-                        mUdfpsOverlayController, mSidefpsController,
-                        mAuthenticationStateListeners,
-                        allowBackgroundAuthentication, mSensorProperties, mHandler,
-                        Utils.getCurrentStrength(mSensorId), null /* clock */, mLockoutTracker);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    private void scheduleAuthenticateHidl(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            long requestId, boolean restricted, int statsClient,
-            boolean allowBackgroundAuthentication, boolean isStrongBiometric) {
-        final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
-                mContext, mLazyDaemon, token, requestId, listener, operationId,
-                restricted, options, cookie, false /* requireConfirmation */,
-                createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
-                        mAuthenticationStatsCollector),
-                mBiometricContext, isStrongBiometric,
-                mTaskStackListener, mLockoutTracker,
-                mUdfpsOverlayController, mSidefpsController,
-                mAuthenticationStateListeners,
-                allowBackgroundAuthentication, mSensorProperties,
-                Utils.getCurrentStrength(mSensorId));
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    @Override
-    public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
-            int cookie, @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
-            boolean allowBackgroundAuthentication) {
-        final long id = mRequestCounter.incrementAndGet();
-
-        scheduleAuthenticate(token, operationId, cookie, listener,
-                options, id, restricted, statsClient, allowBackgroundAuthentication);
-
-        return id;
-    }
-
-    @Override
-    public void startPreparedClient(int sensorId, int cookie) {
-        mHandler.post(() -> mScheduler.startPreparedClient(cookie));
-    }
-
-    @Override
-    public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
-        Slog.d(TAG, "cancelAuthentication, sensorId: " + sensorId);
-        mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token, requestId));
-    }
-
-    @Override
-    public void scheduleRemove(int sensorId, @NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
-            @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleRemoveAidl(token, receiver, fingerId, userId, opPackageName);
-            } else {
-                scheduleRemoveHidl(token, receiver, fingerId, userId, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleRemoveHidl(@NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
-            @NonNull String opPackageName) {
-        final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
-                mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), fingerId,
-                userId, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId),
-                mSensorProperties.sensorId,
-                createLogger(BiometricsProtoEnums.ACTION_REMOVE,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext, mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    private void scheduleRemoveAidl(@NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
-            @NonNull String opPackageName) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintRemovalClient client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintRemovalClient(
-                        mContext, this::getSession, token,
-                        new ClientMonitorCallbackConverter(receiver), new int[]{fingerId}, userId,
-                        opPackageName, FingerprintUtils.getLegacyInstance(mSensorId), mSensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_REMOVE,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                        mBiometricContext, mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
-    }
-
-    @Override
-    public void scheduleRemoveAll(int sensorId, @NonNull IBinder token,
-            @NonNull IFingerprintServiceReceiver receiver, int userId,
-            @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            // For [email protected], remove(0) means remove all enrollments
-            if (Flags.deHidl()) {
-                scheduleRemoveAidl(token, receiver, 0 /* fingerId */, userId, opPackageName);
-            } else {
-                scheduleRemoveHidl(token, receiver, 0 /* fingerId */, userId, opPackageName);
-            }
-        });
-    }
-
-    private void scheduleInternalCleanup(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        mHandler.post(() -> {
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            if (Flags.deHidl()) {
-                scheduleInternalCleanupAidl(userId, callback);
-            } else {
-                scheduleInternalCleanupHidl(userId, callback);
-            }
-        });
-    }
-
-    private void scheduleInternalCleanupHidl(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient(
-                mContext, mLazyDaemon, userId, mContext.getOpPackageName(),
-                mSensorProperties.sensorId,
-                createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
-                        BiometricsProtoEnums.CLIENT_UNKNOWN, mAuthenticationStatsCollector),
-                mBiometricContext,
-                FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, callback);
-    }
-
-    private void scheduleInternalCleanupAidl(int userId,
-            @Nullable ClientMonitorCallback callback) {
-        final com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintInternalCleanupClient
-                client =
-                new com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintInternalCleanupClient(
-                        mContext, this::getSession, userId, mContext.getOpPackageName(),
-                        mSensorProperties.sensorId,
-                        createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
-                                BiometricsProtoEnums.CLIENT_UNKNOWN,
-                                mAuthenticationStatsCollector),
-                        mBiometricContext,
-                        FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, callback);
-    }
-
-    @Override
-    public void scheduleInternalCleanup(int sensorId, int userId,
-            @Nullable ClientMonitorCallback callback) {
-        scheduleInternalCleanup(userId, new ClientMonitorCompositeCallback(callback,
-                mBiometricStateCallback));
-    }
-
-    @Override
-    public void scheduleInternalCleanup(int sensorId, int userId,
-            @Nullable ClientMonitorCallback callback, boolean favorHalEnrollments) {
-        scheduleInternalCleanup(userId, new ClientMonitorCompositeCallback(callback,
-                mBiometricStateCallback));
-    }
-
-    private BiometricLogger createLogger(int statsAction, int statsClient,
-            AuthenticationStatsCollector authenticationStatsCollector) {
-        return new BiometricLogger(mContext, BiometricsProtoEnums.MODALITY_FINGERPRINT,
-                statsAction, statsClient, authenticationStatsCollector);
-    }
-
-    @Override
-    public boolean isHardwareDetected(int sensorId) {
-        return getDaemon() != null;
-    }
-
-    @Override
-    public void rename(int sensorId, int fingerId, int userId, @NonNull String name) {
-        mHandler.post(() -> {
-            FingerprintUtils.getLegacyInstance(mSensorId)
-                    .renameBiometricForUser(mContext, userId, fingerId, name);
-        });
-    }
-
-    @Override
-    @NonNull
-    public List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId) {
-        return FingerprintUtils.getLegacyInstance(mSensorId).getBiometricsForUser(mContext, userId);
-    }
-
-    @Override
-    public boolean hasEnrollments(int sensorId, int userId) {
-        return !getEnrolledFingerprints(sensorId, userId).isEmpty();
-    }
-
-    @Override
-    @LockoutTracker.LockoutMode public int getLockoutModeForUser(int sensorId, int userId) {
-        return mLockoutTracker.getLockoutModeForUser(userId);
-    }
-
-    @Override
-    public long getAuthenticatorId(int sensorId, int userId) {
-        return mAuthenticatorIds.getOrDefault(userId, 0L);
-    }
-
-    @Override
-    public void onPointerDown(long requestId, int sensorId, PointerContext pc) {
-        mScheduler.getCurrentClientIfMatches(requestId, (client) -> {
-            if (!(client instanceof Udfps)) {
-                Slog.w(TAG, "onFingerDown received during client: " + client);
-                return;
-            }
-            ((Udfps) client).onPointerDown(pc);
-        });
-    }
-
-    @Override
-    public void onPointerUp(long requestId, int sensorId, PointerContext pc) {
-        mScheduler.getCurrentClientIfMatches(requestId, (client) -> {
-            if (!(client instanceof Udfps)) {
-                Slog.w(TAG, "onFingerDown received during client: " + client);
-                return;
-            }
-            ((Udfps) client).onPointerUp(pc);
-        });
-    }
-
-    @Override
-    public void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event, long requestId,
-            int sensorId) {
-        mScheduler.getCurrentClientIfMatches(requestId, (client) -> {
-            if (!(client instanceof Udfps)) {
-                Slog.w(TAG, "onUdfpsUiEvent received during client: " + client);
-                return;
-            }
-            ((Udfps) client).onUdfpsUiEvent(event);
-        });
-    }
-
-    @Override
-    public void onPowerPressed() {
-        Slog.e(TAG, "onPowerPressed not supported for HIDL clients");
-    }
-
-    @Override
-    public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
-        mUdfpsOverlayController = controller;
-    }
-
-    // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-    @Override
-    public void setSidefpsController(@NonNull ISidefpsController controller) {
-        mSidefpsController = controller;
-    }
-
-    @Override
-    public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
-            boolean clearSchedulerBuffer) {
-        final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
-
-        proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
-        proto.write(SensorStateProto.MODALITY, SensorStateProto.FINGERPRINT);
-        if (mSensorProperties.isAnyUdfpsType()) {
-            proto.write(SensorStateProto.MODALITY_FLAGS, SensorStateProto.FINGERPRINT_UDFPS);
-        }
-        proto.write(SensorStateProto.CURRENT_STRENGTH,
-                Utils.getCurrentStrength(mSensorProperties.sensorId));
-        proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
-
-        for (UserInfo user : UserManager.get(mContext).getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-
-            final long userToken = proto.start(SensorStateProto.USER_STATES);
-            proto.write(UserStateProto.USER_ID, userId);
-            proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getLegacyInstance(mSensorId)
-                    .getBiometricsForUser(mContext, userId).size());
-            proto.end(userToken);
-        }
-
-        proto.write(SensorStateProto.RESET_LOCKOUT_REQUIRES_HARDWARE_AUTH_TOKEN,
-                mSensorProperties.resetLockoutRequiresHardwareAuthToken);
-        proto.write(SensorStateProto.RESET_LOCKOUT_REQUIRES_CHALLENGE,
-                mSensorProperties.resetLockoutRequiresChallenge);
-
-        proto.end(sensorToken);
-    }
-
-    @Override
-    public void dumpProtoMetrics(int sensorId, FileDescriptor fd) {
-        PerformanceTracker tracker =
-                PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId);
-
-        final ProtoOutputStream proto = new ProtoOutputStream(fd);
-        for (UserInfo user : UserManager.get(mContext).getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-
-            final long userToken = proto.start(FingerprintServiceDumpProto.USERS);
-
-            proto.write(FingerprintUserStatsProto.USER_ID, userId);
-            proto.write(FingerprintUserStatsProto.NUM_FINGERPRINTS,
-                    FingerprintUtils.getLegacyInstance(mSensorId)
-                            .getBiometricsForUser(mContext, userId).size());
-
-            // Normal fingerprint authentications (e.g. lockscreen)
-            long countsToken = proto.start(FingerprintUserStatsProto.NORMAL);
-            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptForUser(userId));
-            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectForUser(userId));
-            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireForUser(userId));
-            proto.write(PerformanceStatsProto.LOCKOUT, tracker.getTimedLockoutForUser(userId));
-            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT,
-                    tracker.getPermanentLockoutForUser(userId));
-            proto.end(countsToken);
-
-            // Statistics about secure fingerprint transactions (e.g. to unlock password
-            // storage, make secure purchases, etc.)
-            countsToken = proto.start(FingerprintUserStatsProto.CRYPTO);
-            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.LOCKOUT, 0); // meaningless for crypto
-            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, 0); // meaningless for crypto
-            proto.end(countsToken);
-
-            proto.end(userToken);
-        }
-        proto.flush();
-        tracker.clear();
-    }
-
-    @Override
-    public void scheduleInvalidateAuthenticatorId(int sensorId, int userId,
-            @NonNull IInvalidationCallback callback) {
-        // TODO (b/179101888): Remove this temporary workaround.
-        try {
-            callback.onCompleted();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to complete InvalidateAuthenticatorId");
-        }
-    }
-
-    @Override
-    public void dumpInternal(int sensorId, @NonNull PrintWriter pw) {
-        PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId);
-
-        JSONObject dump = new JSONObject();
-        try {
-            dump.put("service", TAG);
-            dump.put("isUdfps", mIsUdfps);
-            dump.put("isPowerbuttonFps", mIsPowerbuttonFps);
-
-            JSONArray sets = new JSONArray();
-            for (UserInfo user : UserManager.get(mContext).getUsers()) {
-                final int userId = user.getUserHandle().getIdentifier();
-                final int N = FingerprintUtils.getLegacyInstance(mSensorId)
-                        .getBiometricsForUser(mContext, userId).size();
-                JSONObject set = new JSONObject();
-                set.put("id", userId);
-                set.put("count", N);
-                set.put("accept", performanceTracker.getAcceptForUser(userId));
-                set.put("reject", performanceTracker.getRejectForUser(userId));
-                set.put("acquire", performanceTracker.getAcquireForUser(userId));
-                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
-                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
-                // cryptoStats measures statistics about secure fingerprint transactions
-                // (e.g. to unlock password storage, make secure purchases, etc.)
-                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
-                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
-                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
-                sets.put(set);
-            }
-
-            dump.put("prints", sets);
-        } catch (JSONException e) {
-            Slog.e(TAG, "dump formatting failure", e);
-        }
-        pw.println(dump);
-        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
-        mScheduler.dump(pw);
-    }
-
-    void setTestHalEnabled(boolean enabled) {
-        mTestHalEnabled = enabled;
-    }
-
-    @NonNull
-    @Override
-    public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
-            @NonNull String opPackageName) {
-        return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback,
-                mBiometricStateCallback, this, mHalResultController);
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
deleted file mode 100644
index f857946..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.trust.TrustManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.PointerContext;
-import android.hardware.fingerprint.FingerprintAuthenticateOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Slog;
-import android.util.SparseBooleanArray;
-
-import com.android.internal.R;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.sensors.AuthenticationConsumer;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * A mockable/testable provider of the {@link android.hardware.biometrics.fingerprint.V2_3} HIDL
- * interface. This class is intended simulate UDFPS logic for devices that do not have an actual
- * [email protected] HAL (where UDFPS starts to become supported)
- *
- * UDFPS "accept" can only happen within a set amount of time after a sensor authentication. This is
- * specified by {@link MockHalResultController#AUTH_VALIDITY_MS}. Touches after this duration will
- * be treated as "reject".
- *
- * This class provides framework logic to emulate, for testing only, the UDFPS functionalies below:
- *
- * 1) IF either A) the caller is keyguard, and the device is not in a trusted state (authenticated
- *    via biometric sensor or unlocked with a trust agent {@see android.app.trust.TrustManager}, OR
- *    B) the caller is not keyguard, and regardless of trusted state, AND (following applies to both
- *    (A) and (B) above) {@link FingerprintManager#onFingerDown(int, int, float, float)} is
- *    received, this class will respond with {@link AuthenticationCallback#onAuthenticationFailed()}
- *    after a tunable flat_time + variance_time.
- *
- *    In the case above (1), callers must not receive a successful authentication event here because
- *    the sensor has not actually been authenticated.
- *
- * 2) IF A) the caller is keyguard and the device is not in a trusted state, OR B) the caller is not
- *    keyguard and regardless of trusted state, AND (following applies to both (A) and (B)) the
- *    sensor is touched and the fingerprint is accepted by the HAL, and then
- *    {@link FingerprintManager#onFingerDown(int, int, float, float)} is received, this class will
- *    respond with {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)}
- *    after a tunable flat_time + variance_time. Note that the authentication callback from the
- *    sensor is held until {@link FingerprintManager#onFingerDown(int, int, float, float)} is
- *    invoked.
- *
- *    In the case above (2), callers can receive a successful authentication callback because the
- *    real sensor was authenticated. Note that even though the real sensor was touched, keyguard
- *    fingerprint authentication does not put keyguard into a trusted state because the
- *    authentication callback is held until onFingerDown was invoked. This allows callers such as
- *    keyguard to simulate a realistic path.
- *
- * 3) IF the caller is keyguard AND the device in a trusted state and then
- *    {@link FingerprintManager#onFingerDown(int, int, float, float)} is received, this class will
- *    respond with {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)}
- *    after a tunable flat_time + variance time.
- *
- *    In the case above (3), since the device is already unlockable via trust agent, it's fine to
- *    simulate the successful auth path. Non-keyguard clients will fall into either (1) or (2)
- *    above.
- *
- *  This class currently does not simulate false rejection. Conversely, this class relies on the
- *  real hardware sensor so does not affect false acceptance.
- */
-@SuppressWarnings("deprecation")
-public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManager.TrustListener {
-
-    private static final String TAG = "Fingerprint21UdfpsMock";
-
-    // Secure setting integer. If true, the system will load this class to enable udfps testing.
-    public static final String CONFIG_ENABLE_TEST_UDFPS =
-            "com.android.server.biometrics.sensors.fingerprint.test_udfps.enable";
-    // Secure setting integer. A fixed duration intended to simulate something like the duration
-    // required for image capture.
-    private static final String CONFIG_AUTH_DELAY_PT1 =
-            "com.android.server.biometrics.sensors.fingerprint.test_udfps.auth_delay_pt1";
-    // Secure setting integer. A fixed duration intended to simulate something like the duration
-    // required for template matching to complete.
-    private static final String CONFIG_AUTH_DELAY_PT2 =
-            "com.android.server.biometrics.sensors.fingerprint.test_udfps.auth_delay_pt2";
-    // Secure setting integer. A random value between [-randomness, randomness] will be added to the
-    // capture delay above for each accept/reject.
-    private static final String CONFIG_AUTH_DELAY_RANDOMNESS =
-            "com.android.server.biometrics.sensors.fingerprint.test_udfps.auth_delay_randomness";
-
-    private static final int DEFAULT_AUTH_DELAY_PT1_MS = 300;
-    private static final int DEFAULT_AUTH_DELAY_PT2_MS = 400;
-    private static final int DEFAULT_AUTH_DELAY_RANDOMNESS_MS = 100;
-
-    @NonNull private final TestableBiometricScheduler mScheduler;
-    @NonNull private final Handler mHandler;
-    @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
-    @NonNull private final MockHalResultController mMockHalResultController;
-    @NonNull private final TrustManager mTrustManager;
-    @NonNull private final SparseBooleanArray mUserHasTrust;
-    @NonNull private final Random mRandom;
-    @NonNull private final FakeRejectRunnable mFakeRejectRunnable;
-    @NonNull private final FakeAcceptRunnable mFakeAcceptRunnable;
-    @NonNull private final RestartAuthRunnable mRestartAuthRunnable;
-
-    private static class TestableBiometricScheduler extends BiometricScheduler {
-        @NonNull private Fingerprint21UdfpsMock mFingerprint21;
-
-        TestableBiometricScheduler(
-                @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
-            super(BiometricScheduler.SENSOR_TYPE_FP_OTHER, gestureAvailabilityDispatcher);
-        }
-
-        void init(@NonNull Fingerprint21UdfpsMock fingerprint21) {
-            mFingerprint21 = fingerprint21;
-        }
-    }
-
-    /**
-     * All of the mocking/testing should happen in here. This way we don't need to modify the
-     * {@link BaseClientMonitor} implementations and can run the
-     * real path there.
-     */
-    private static class MockHalResultController extends HalResultController {
-
-        // Duration for which a sensor authentication can be treated as UDFPS success.
-        private static final int AUTH_VALIDITY_MS = 10 * 1000; // 10 seconds
-
-        static class LastAuthArgs {
-            @NonNull final AuthenticationConsumer lastAuthenticatedClient;
-            final long deviceId;
-            final int fingerId;
-            final int groupId;
-            @Nullable final ArrayList<Byte> token;
-
-            LastAuthArgs(@NonNull AuthenticationConsumer authenticationConsumer, long deviceId,
-                    int fingerId, int groupId, @Nullable ArrayList<Byte> token) {
-                lastAuthenticatedClient = authenticationConsumer;
-                this.deviceId = deviceId;
-                this.fingerId = fingerId;
-                this.groupId = groupId;
-                if (token == null) {
-                    this.token = null;
-                } else {
-                    // Store a copy so the owner can be GC'd
-                    this.token = new ArrayList<>(token);
-                }
-            }
-        }
-
-        // Initialized after the constructor, but before it's ever used.
-        @NonNull private RestartAuthRunnable mRestartAuthRunnable;
-        @NonNull private Fingerprint21UdfpsMock mFingerprint21;
-        @Nullable private LastAuthArgs mLastAuthArgs;
-
-        MockHalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
-                @NonNull BiometricScheduler scheduler) {
-            super(sensorId, context, handler, scheduler);
-        }
-
-        void init(@NonNull RestartAuthRunnable restartAuthRunnable,
-                @NonNull Fingerprint21UdfpsMock fingerprint21) {
-            mRestartAuthRunnable = restartAuthRunnable;
-            mFingerprint21 = fingerprint21;
-        }
-
-        @Nullable AuthenticationConsumer getLastAuthenticatedClient() {
-            return mLastAuthArgs != null ? mLastAuthArgs.lastAuthenticatedClient : null;
-        }
-
-        /**
-         * Intercepts the HAL authentication and holds it until the UDFPS simulation decides
-         * that authentication finished.
-         */
-        @Override
-        public void onAuthenticated(long deviceId, int fingerId, int groupId,
-                ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                final BaseClientMonitor client = mScheduler.getCurrentClient();
-                if (!(client instanceof AuthenticationConsumer)) {
-                    Slog.e(TAG, "Non authentication consumer: " + client);
-                    return;
-                }
-
-                final boolean accepted = fingerId != 0;
-                if (accepted) {
-                    mFingerprint21.setDebugMessage("Finger accepted");
-                } else {
-                    mFingerprint21.setDebugMessage("Finger rejected");
-                }
-
-                final AuthenticationConsumer authenticationConsumer =
-                        (AuthenticationConsumer) client;
-                mLastAuthArgs = new LastAuthArgs(authenticationConsumer, deviceId, fingerId,
-                        groupId, token);
-
-                // Remove any existing restart runnbables since auth just started, and put a new
-                // one on the queue.
-                mHandler.removeCallbacks(mRestartAuthRunnable);
-                mRestartAuthRunnable.setLastAuthReference(authenticationConsumer);
-                mHandler.postDelayed(mRestartAuthRunnable, AUTH_VALIDITY_MS);
-            });
-        }
-
-        /**
-         * Calls through to the real interface and notifies clients of accept/reject.
-         */
-        void sendAuthenticated(long deviceId, int fingerId, int groupId,
-                ArrayList<Byte> token) {
-            Slog.d(TAG, "sendAuthenticated: " + (fingerId != 0));
-            mFingerprint21.setDebugMessage("Udfps match: " + (fingerId != 0));
-            super.onAuthenticated(deviceId, fingerId, groupId, token);
-        }
-    }
-
-    public static Fingerprint21UdfpsMock newInstance(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
-            @NonNull BiometricContext biometricContext) {
-        Slog.d(TAG, "Creating Fingerprint23Mock!");
-
-        final Handler handler = new Handler(Looper.getMainLooper());
-        final TestableBiometricScheduler scheduler =
-                new TestableBiometricScheduler(gestureAvailabilityDispatcher);
-        final MockHalResultController controller =
-                new MockHalResultController(sensorProps.sensorId, context, handler, scheduler);
-        return new Fingerprint21UdfpsMock(context, biometricStateCallback,
-                authenticationStateListeners, sensorProps, scheduler, handler,
-                lockoutResetDispatcher, controller, biometricContext);
-    }
-
-    private static abstract class FakeFingerRunnable implements Runnable {
-        private long mFingerDownTime;
-        private int mCaptureDuration;
-
-        /**
-         * @param fingerDownTime System time when onFingerDown occurred
-         * @param captureDuration Duration that the finger needs to be down for
-         */
-        void setSimulationTime(long fingerDownTime, int captureDuration) {
-            mFingerDownTime = fingerDownTime;
-            mCaptureDuration = captureDuration;
-        }
-
-        @SuppressWarnings("BooleanMethodIsAlwaysInverted")
-        boolean isImageCaptureComplete() {
-            return System.currentTimeMillis() - mFingerDownTime > mCaptureDuration;
-        }
-    }
-
-    private final class FakeRejectRunnable extends FakeFingerRunnable {
-        @Override
-        public void run() {
-            mMockHalResultController.sendAuthenticated(0, 0, 0, null);
-        }
-    }
-
-    private final class FakeAcceptRunnable extends FakeFingerRunnable {
-        @Override
-        public void run() {
-            if (mMockHalResultController.mLastAuthArgs == null) {
-                // This can happen if the user has trust agents enabled, which make lockscreen
-                // dismissable. Send a fake non-zero (accept) finger.
-                Slog.d(TAG, "Sending fake finger");
-                mMockHalResultController.sendAuthenticated(1 /* deviceId */,
-                        1 /* fingerId */, 1 /* groupId */, null /* token */);
-            } else {
-                mMockHalResultController.sendAuthenticated(
-                        mMockHalResultController.mLastAuthArgs.deviceId,
-                        mMockHalResultController.mLastAuthArgs.fingerId,
-                        mMockHalResultController.mLastAuthArgs.groupId,
-                        mMockHalResultController.mLastAuthArgs.token);
-            }
-        }
-    }
-
-    /**
-     * The fingerprint HAL allows multiple (5) fingerprint attempts per HIDL invocation of the
-     * authenticate method. However, valid fingerprint authentications are invalidated after
-     * {@link MockHalResultController#AUTH_VALIDITY_MS}, meaning UDFPS touches will be reported as
-     * rejects if touched after that duration. However, since a valid fingerprint was detected, the
-     * HAL and FingerprintService will not look for subsequent fingerprints.
-     *
-     * In order to keep the FingerprintManager API consistent (that multiple fingerprint attempts
-     * are allowed per auth lifecycle), we internally cancel and restart authentication so that the
-     * sensor is responsive again.
-     */
-    private static final class RestartAuthRunnable implements Runnable {
-        @NonNull private final Fingerprint21UdfpsMock mFingerprint21;
-        @NonNull private final TestableBiometricScheduler mScheduler;
-
-        // Store a reference to the auth consumer that should be invalidated.
-        private AuthenticationConsumer mLastAuthConsumer;
-
-        RestartAuthRunnable(@NonNull Fingerprint21UdfpsMock fingerprint21,
-                @NonNull TestableBiometricScheduler scheduler) {
-            mFingerprint21 = fingerprint21;
-            mScheduler = scheduler;
-        }
-
-        void setLastAuthReference(AuthenticationConsumer lastAuthConsumer) {
-            mLastAuthConsumer = lastAuthConsumer;
-        }
-
-        @Override
-        public void run() {
-            final BaseClientMonitor client = mScheduler.getCurrentClient();
-
-            // We don't care about FingerprintDetectClient, since accept/rejects are both OK. UDFPS
-            // rejects will just simulate the path where non-enrolled fingers are presented.
-            if (!(client instanceof FingerprintAuthenticationClient)) {
-                Slog.e(TAG, "Non-FingerprintAuthenticationClient client: " + client);
-                return;
-            }
-
-            // Perhaps the runnable is stale, or the user stopped/started auth manually. Do not
-            // restart auth in this case.
-            if (client != mLastAuthConsumer) {
-                Slog.e(TAG, "Current client: " + client
-                        + " does not match mLastAuthConsumer: " + mLastAuthConsumer);
-                return;
-            }
-
-            Slog.d(TAG, "Restarting auth, current: " + client);
-            mFingerprint21.setDebugMessage("Auth timed out");
-
-            final FingerprintAuthenticationClient authClient =
-                    (FingerprintAuthenticationClient) client;
-            // Store the authClient parameters so it can be rescheduled
-            final IBinder token = client.getToken();
-            final long operationId = authClient.getOperationId();
-            final int cookie = client.getCookie();
-            final ClientMonitorCallbackConverter listener = new ClientMonitorCallbackConverter(
-                    new IFingerprintServiceReceiver.Default());
-            final boolean restricted = authClient.isRestricted();
-            final int statsClient = client.getLogger().getStatsClient();
-            final boolean isKeyguard = authClient.isKeyguard();
-            final FingerprintAuthenticateOptions options =
-                    new FingerprintAuthenticateOptions.Builder()
-                            .setUserId(client.getTargetUserId())
-                            .setOpPackageName(client.getOwnerString())
-                            .build();
-
-            // Don't actually send cancel() to the HAL, since successful auth already finishes
-            // HAL authenticate() lifecycle. Just
-            mScheduler.getInternalCallback().onClientFinished(client, true /* success */);
-
-            // Schedule this only after we invoke onClientFinished for the previous client, so that
-            // internal preemption logic is not run.
-            mFingerprint21.scheduleAuthenticate(token,
-                    operationId, cookie, listener, options, restricted, statsClient,
-                    isKeyguard);
-        }
-    }
-
-    private Fingerprint21UdfpsMock(@NonNull Context context,
-            @NonNull BiometricStateCallback biometricStateCallback,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @NonNull TestableBiometricScheduler scheduler,
-            @NonNull Handler handler,
-            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull MockHalResultController controller,
-            @NonNull BiometricContext biometricContext) {
-        super(context, biometricStateCallback, authenticationStateListeners, sensorProps, scheduler,
-                handler, lockoutResetDispatcher, controller, biometricContext);
-        mScheduler = scheduler;
-        mScheduler.init(this);
-        mHandler = handler;
-        // resetLockout is controlled by the framework, so hardwareAuthToken is not required
-        final boolean resetLockoutRequiresHardwareAuthToken = false;
-        final int maxTemplatesAllowed = mContext.getResources()
-                .getInteger(R.integer.config_fingerprintMaxTemplatesPerUser);
-        mSensorProperties = new FingerprintSensorPropertiesInternal(sensorProps.sensorId,
-                sensorProps.sensorStrength, maxTemplatesAllowed, sensorProps.componentInfo,
-                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, false /* halControlsIllumination */,
-                resetLockoutRequiresHardwareAuthToken, sensorProps.getAllLocations());
-        mMockHalResultController = controller;
-        mUserHasTrust = new SparseBooleanArray();
-        mTrustManager = context.getSystemService(TrustManager.class);
-        mTrustManager.registerTrustListener(this);
-        mRandom = new Random();
-        mFakeRejectRunnable = new FakeRejectRunnable();
-        mFakeAcceptRunnable = new FakeAcceptRunnable();
-        mRestartAuthRunnable = new RestartAuthRunnable(this, mScheduler);
-
-        // We can't initialize this during MockHalresultController's constructor due to a circular
-        // dependency.
-        mMockHalResultController.init(mRestartAuthRunnable, this);
-    }
-
-    @Override
-    public void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
-            List<String> trustGrantedMessages) {
-        mUserHasTrust.put(userId, enabled);
-    }
-
-    @Override
-    public void onTrustManagedChanged(boolean enabled, int userId) {
-
-    }
-
-    @Override
-    public void onTrustError(CharSequence message) {
-
-    }
-
-    @Override
-    public void onEnabledTrustAgentsChanged(int userId) {
-
-    }
-
-    @Override
-    public void onIsActiveUnlockRunningChanged(boolean isRunning, int userId) {
-
-    }
-
-    @Override
-    @NonNull
-    public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
-        final List<FingerprintSensorPropertiesInternal> properties = new ArrayList<>();
-        properties.add(mSensorProperties);
-        return properties;
-    }
-
-    @Override
-    public void onPointerDown(long requestId, int sensorId, PointerContext pc) {
-        mHandler.post(() -> {
-            Slog.d(TAG, "onFingerDown");
-            final AuthenticationConsumer lastAuthenticatedConsumer =
-                    mMockHalResultController.getLastAuthenticatedClient();
-            final BaseClientMonitor currentScheduledClient = mScheduler.getCurrentClient();
-
-            if (currentScheduledClient == null) {
-                Slog.d(TAG, "Not authenticating");
-                return;
-            }
-
-            mHandler.removeCallbacks(mFakeRejectRunnable);
-            mHandler.removeCallbacks(mFakeAcceptRunnable);
-
-            // The sensor was authenticated, is still the currently scheduled client, and the
-            // user touched the UDFPS affordance. Pretend that auth succeeded.
-            final boolean authenticatedClientIsCurrent = lastAuthenticatedConsumer != null
-                    && lastAuthenticatedConsumer == currentScheduledClient;
-            // User is unlocked on keyguard via Trust Agent
-            final boolean keyguardAndTrusted;
-            if (currentScheduledClient instanceof FingerprintAuthenticationClient) {
-                keyguardAndTrusted = ((FingerprintAuthenticationClient) currentScheduledClient)
-                        .isKeyguard()
-                        && mUserHasTrust.get(currentScheduledClient.getTargetUserId(), false);
-            } else {
-                keyguardAndTrusted = false;
-            }
-
-            final int captureDuration = getNewCaptureDuration();
-            final int matchingDuration = getMatchingDuration();
-            final int totalDuration = captureDuration + matchingDuration;
-            setDebugMessage("Duration: " + totalDuration
-                    + " (" + captureDuration + " + " + matchingDuration + ")");
-            if (authenticatedClientIsCurrent || keyguardAndTrusted) {
-                mFakeAcceptRunnable.setSimulationTime(System.currentTimeMillis(), captureDuration);
-                mHandler.postDelayed(mFakeAcceptRunnable, totalDuration);
-            } else if (currentScheduledClient instanceof AuthenticationConsumer) {
-                // Something is authenticating but authentication has not succeeded yet. Pretend
-                // that auth rejected.
-                mFakeRejectRunnable.setSimulationTime(System.currentTimeMillis(), captureDuration);
-                mHandler.postDelayed(mFakeRejectRunnable, totalDuration);
-            }
-        });
-    }
-
-    @Override
-    public void onPointerUp(long requestId, int sensorId, PointerContext pc) {
-        mHandler.post(() -> {
-            Slog.d(TAG, "onFingerUp");
-
-            // Only one of these can be on the handler at any given time (see onFingerDown). If
-            // image capture is not complete, send ACQUIRED_TOO_FAST and remove the runnable from
-            // the handler. Image capture (onFingerDown) needs to happen again.
-            if (mHandler.hasCallbacks(mFakeRejectRunnable)
-                    && !mFakeRejectRunnable.isImageCaptureComplete()) {
-                mHandler.removeCallbacks(mFakeRejectRunnable);
-                mMockHalResultController.onAcquired(0 /* deviceId */,
-                        FingerprintManager.FINGERPRINT_ACQUIRED_TOO_FAST,
-                        0 /* vendorCode */);
-            } else if (mHandler.hasCallbacks(mFakeAcceptRunnable)
-                    && !mFakeAcceptRunnable.isImageCaptureComplete()) {
-                mHandler.removeCallbacks(mFakeAcceptRunnable);
-                mMockHalResultController.onAcquired(0 /* deviceId */,
-                        FingerprintManager.FINGERPRINT_ACQUIRED_TOO_FAST,
-                        0 /* vendorCode */);
-            }
-        });
-    }
-
-    private int getNewCaptureDuration() {
-        final ContentResolver contentResolver = mContext.getContentResolver();
-        final int captureTime = Settings.Secure.getIntForUser(contentResolver,
-                CONFIG_AUTH_DELAY_PT1,
-                DEFAULT_AUTH_DELAY_PT1_MS,
-                UserHandle.USER_CURRENT);
-        final int randomDelayRange = Settings.Secure.getIntForUser(contentResolver,
-                CONFIG_AUTH_DELAY_RANDOMNESS,
-                DEFAULT_AUTH_DELAY_RANDOMNESS_MS,
-                UserHandle.USER_CURRENT);
-        final int randomDelay = mRandom.nextInt(randomDelayRange * 2) - randomDelayRange;
-
-        // Must be at least 0
-        return Math.max(captureTime + randomDelay, 0);
-    }
-
-    private int getMatchingDuration() {
-        final int matchingTime = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                CONFIG_AUTH_DELAY_PT2,
-                DEFAULT_AUTH_DELAY_PT2_MS,
-                UserHandle.USER_CURRENT);
-
-        // Must be at least 0
-        return Math.max(matchingTime, 0);
-    }
-
-    private void setDebugMessage(String message) {
-        try {
-            final IUdfpsOverlayController controller = getUdfpsOverlayController();
-            // Things can happen before SysUI loads and sets the controller.
-            if (controller != null) {
-                Slog.d(TAG, "setDebugMessage: " + message);
-                controller.setDebugMessage(mSensorProperties.sensorId, message);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when sending message: " + message, e);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
deleted file mode 100644
index b6311af..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import static android.adaptiveauth.Flags.reportBiometricAuthAttempts;
-
-import static com.android.systemui.shared.Flags.sidefpsControllerRefactor;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.TaskStackListener;
-import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricFingerprintConstants;
-import android.hardware.biometrics.BiometricManager.Authenticators;
-import android.hardware.biometrics.BiometricSourceType;
-import android.hardware.biometrics.fingerprint.PointerContext;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.FingerprintAuthenticateOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.ISidefpsController;
-import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.log.CallbackWithProbe;
-import com.android.server.biometrics.log.Probe;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BiometricNotificationUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.SensorOverlays;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
-
-import java.util.ArrayList;
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific authentication client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-class FingerprintAuthenticationClient
-        extends AuthenticationClient<IBiometricsFingerprint, FingerprintAuthenticateOptions>
-        implements Udfps {
-
-    private static final String TAG = "Biometrics/FingerprintAuthClient";
-
-    private final LockoutFrameworkImpl mLockoutFrameworkImpl;
-    @NonNull private final SensorOverlays mSensorOverlays;
-    @NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
-    @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
-    @NonNull private final AuthenticationStateListeners mAuthenticationStateListeners;
-
-    private boolean mIsPointerDown;
-
-    FingerprintAuthenticationClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
-            @NonNull IBinder token, long requestId,
-            @NonNull ClientMonitorCallbackConverter listener, long operationId,
-            boolean restricted, @NonNull FingerprintAuthenticateOptions options,
-            int cookie, boolean requireConfirmation, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext, boolean isStrongBiometric,
-            @NonNull TaskStackListener taskStackListener,
-            @NonNull LockoutFrameworkImpl lockoutTracker,
-            @Nullable IUdfpsOverlayController udfpsOverlayController,
-            // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-            @Nullable ISidefpsController sidefpsController,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            boolean allowBackgroundAuthentication,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps,
-            @Authenticators.Types int sensorStrength) {
-        super(context, lazyDaemon, token, listener, operationId, restricted,
-                options, cookie, requireConfirmation, logger, biometricContext,
-                isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
-                false /* shouldVibrate */, sensorStrength);
-        setRequestId(requestId);
-        mLockoutFrameworkImpl = lockoutTracker;
-        if (sidefpsControllerRefactor()) {
-            mSensorOverlays = new SensorOverlays(udfpsOverlayController);
-        } else {
-            mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
-        }
-        mAuthenticationStateListeners = authenticationStateListeners;
-        mSensorProps = sensorProps;
-        mALSProbeCallback = getLogger().getAmbientLightProbe(false /* startWithClient */);
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-
-        if (mSensorProps.isAnyUdfpsType()) {
-            // UDFPS requires user to touch before becoming "active"
-            mState = STATE_STARTED_PAUSED;
-        } else {
-            mState = STATE_STARTED;
-        }
-    }
-
-    @NonNull
-    @Override
-    protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
-        return new ClientMonitorCompositeCallback(mALSProbeCallback, callback);
-    }
-
-    @Override
-    public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated, ArrayList<Byte> token) {
-        super.onAuthenticated(identifier, authenticated, token);
-
-        // Authentication lifecycle ends either when
-        // 1) Authenticated == true
-        // 2) Error occurred (lockout or some other error)
-        // Note that authentication doesn't end when Authenticated == false
-
-        if (authenticated) {
-            mState = STATE_STOPPED;
-            resetFailedAttempts(getTargetUserId());
-            mSensorOverlays.hide(getSensorId());
-            if (sidefpsControllerRefactor()) {
-                mAuthenticationStateListeners.onAuthenticationStopped();
-            }
-            if (reportBiometricAuthAttempts()) {
-                mAuthenticationStateListeners.onAuthenticationSucceeded(getRequestReason(),
-                        getTargetUserId());
-            }
-        } else {
-            mState = STATE_STARTED_PAUSED_ATTEMPTED;
-            final @LockoutTracker.LockoutMode int lockoutMode =
-                    mLockoutFrameworkImpl.getLockoutModeForUser(getTargetUserId());
-            if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
-                Slog.w(TAG, "Fingerprint locked out, lockoutMode(" + lockoutMode + ")");
-                final int errorCode = lockoutMode == LockoutTracker.LOCKOUT_TIMED
-                        ? BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
-                        : BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
-                // Send the error, but do not invoke the FinishCallback yet. Since lockout is not
-                // controlled by the HAL, the framework must stop the sensor before finishing the
-                // client.
-                mSensorOverlays.hide(getSensorId());
-                if (sidefpsControllerRefactor()) {
-                    mAuthenticationStateListeners.onAuthenticationStopped();
-                }
-                onErrorInternal(errorCode, 0 /* vendorCode */, false /* finish */);
-                cancel();
-            }
-            if (reportBiometricAuthAttempts()) {
-                mAuthenticationStateListeners.onAuthenticationFailed(getRequestReason(),
-                        getTargetUserId());
-            }
-        }
-    }
-
-    @Override
-    public void onError(int errorCode, int vendorCode) {
-        super.onError(errorCode, vendorCode);
-
-        if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBRATION) {
-            BiometricNotificationUtils.showBadCalibrationNotification(getContext());
-        }
-
-        mSensorOverlays.hide(getSensorId());
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStopped();
-        }
-    }
-
-    private void resetFailedAttempts(int userId) {
-        mLockoutFrameworkImpl.resetFailedAttemptsForUser(true /* clearAttemptCounter */, userId);
-    }
-
-    @Override
-    protected void handleLifecycleAfterAuth(boolean authenticated) {
-        if (authenticated) {
-            mCallback.onClientFinished(this, true /* success */);
-        }
-    }
-
-    @Override
-    public void onAcquired(int acquiredInfo, int vendorCode) {
-        mAuthenticationStateListeners.onAuthenticationAcquired(
-                BiometricSourceType.FINGERPRINT, getRequestReason(), acquiredInfo);
-        super.onAcquired(acquiredInfo, vendorCode);
-
-        @LockoutTracker.LockoutMode final int lockoutMode =
-                getLockoutTracker().getLockoutModeForUser(getTargetUserId());
-        if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
-            PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
-            pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
-        }
-    }
-
-    @Override
-    public boolean wasUserDetected() {
-        // TODO: Update if it needs to be used for fingerprint, i.e. success/reject, error_timeout
-        return false;
-    }
-
-    @Override
-    public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
-        mLockoutFrameworkImpl.addFailedAttemptForUser(userId);
-        @LockoutTracker.LockoutMode final int lockoutMode =
-                getLockoutTracker().getLockoutModeForUser(userId);
-        final PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(getSensorId());
-        if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
-            performanceTracker.incrementPermanentLockoutForUser(userId);
-        } else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
-            performanceTracker.incrementTimedLockoutForUser(userId);
-        }
-
-        return lockoutMode;
-    }
-
-    @Override
-    protected void startHalOperation() {
-        mSensorOverlays.show(getSensorId(), getRequestReason(), this);
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStarted(getRequestReason());
-        }
-
-        try {
-            // GroupId was never used. In fact, groupId is always the same as userId.
-            getFreshDaemon().authenticate(mOperationId, getTargetUserId());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting auth", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mSensorOverlays.hide(getSensorId());
-            if (sidefpsControllerRefactor()) {
-                mAuthenticationStateListeners.onAuthenticationStopped();
-            }
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    protected void stopHalOperation() {
-        mSensorOverlays.hide(getSensorId());
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStopped();
-        }
-
-        try {
-            getFreshDaemon().cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting cancel", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public void onPointerDown(PointerContext pc) {
-        mIsPointerDown = true;
-        mState = STATE_STARTED;
-        mALSProbeCallback.getProbe().enable();
-        UdfpsHelper.onFingerDown(getFreshDaemon(), (int) pc.x, (int) pc.y, pc.minor, pc.major);
-
-        try {
-            getListener().onUdfpsPointerDown(getSensorId());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception", e);
-        }
-    }
-
-    @Override
-    public void onPointerUp(PointerContext pc) {
-        mIsPointerDown = false;
-        mState = STATE_STARTED_PAUSED_ATTEMPTED;
-        mALSProbeCallback.getProbe().disable();
-        UdfpsHelper.onFingerUp(getFreshDaemon());
-
-        try {
-            getListener().onUdfpsPointerUp(getSensorId());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception", e);
-        }
-    }
-
-    @Override
-    public boolean isPointerDown() {
-        return mIsPointerDown;
-    }
-
-    @Override
-    public void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event) {
-        // Unsupported in HIDL.
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
deleted file mode 100644
index 50e48fe..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import static com.android.systemui.shared.Flags.sidefpsControllerRefactor;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricFingerprintConstants;
-import android.hardware.biometrics.BiometricRequestConstants;
-import android.hardware.biometrics.fingerprint.PointerContext;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.FingerprintAuthenticateOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.AcquisitionClient;
-import com.android.server.biometrics.sensors.AuthenticationConsumer;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.SensorOverlays;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
-
-import java.util.ArrayList;
-import java.util.function.Supplier;
-
-/**
- * Performs fingerprint detection without exposing any matching information (e.g. accept/reject
- * have the same haptic, lockout counter is not increased).
- */
-class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
-        implements AuthenticationConsumer, Udfps {
-
-    private static final String TAG = "FingerprintDetectClient";
-
-    private final boolean mIsStrongBiometric;
-    @NonNull private final SensorOverlays mSensorOverlays;
-    private boolean mIsPointerDown;
-
-    public FingerprintDetectClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
-            @NonNull IBinder token, long requestId,
-            @NonNull ClientMonitorCallbackConverter listener,
-            @NonNull FingerprintAuthenticateOptions options,
-            @NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
-            @Nullable IUdfpsOverlayController udfpsOverlayController,
-            boolean isStrongBiometric) {
-        super(context, lazyDaemon, token, listener, options.getUserId(),
-                options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
-                true /* shouldVibrate */, biometricLogger, biometricContext);
-        setRequestId(requestId);
-        if (sidefpsControllerRefactor()) {
-            mSensorOverlays = new SensorOverlays(udfpsOverlayController);
-        } else {
-            mSensorOverlays = new SensorOverlays(
-                    udfpsOverlayController, null /* sideFpsController */);
-        }
-        mIsStrongBiometric = isStrongBiometric;
-    }
-
-    @Override
-    protected void stopHalOperation() {
-        mSensorOverlays.hide(getSensorId());
-
-        try {
-            getFreshDaemon().cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting cancel", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-        startHalOperation();
-    }
-
-    @Override
-    protected void startHalOperation() {
-        mSensorOverlays.show(getSensorId(), BiometricRequestConstants.REASON_AUTH_KEYGUARD,
-                this);
-
-        try {
-            getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting auth", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mSensorOverlays.hide(getSensorId());
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public void onPointerDown(PointerContext pc) {
-        mIsPointerDown = true;
-        UdfpsHelper.onFingerDown(getFreshDaemon(), (int) pc.x, (int) pc.y, pc.minor, pc.major);
-    }
-
-    @Override
-    public void onPointerUp(PointerContext pc) {
-        mIsPointerDown = false;
-        UdfpsHelper.onFingerUp(getFreshDaemon());
-    }
-
-    @Override
-    public boolean isPointerDown() {
-        return mIsPointerDown;
-    }
-
-    @Override
-    public void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event) {
-        // Unsupported in HIDL.
-    }
-
-    @Override
-    public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated, ArrayList<Byte> hardwareAuthToken) {
-        getLogger().logOnAuthenticated(getContext(), getOperationContext(),
-                authenticated, false /* requireConfirmation */,
-                getTargetUserId(), false /* isBiometricPrompt */);
-
-        // Do not distinguish between success/failures.
-        vibrateSuccess();
-
-        final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
-        pm.incrementAuthForUser(getTargetUserId(), authenticated);
-
-        try {
-            getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when sending onDetected", e);
-        }
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_DETECT_INTERACTION;
-    }
-
-    @Override
-    public boolean interruptsPrecedingClients() {
-        return true;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
deleted file mode 100644
index 8f937fc..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import static com.android.systemui.shared.Flags.sidefpsControllerRefactor;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricFingerprintConstants;
-import android.hardware.biometrics.BiometricStateListener;
-import android.hardware.biometrics.fingerprint.PointerContext;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintEnrollOptions;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.ISidefpsController;
-import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BiometricNotificationUtils;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
-import com.android.server.biometrics.sensors.EnrollClient;
-import com.android.server.biometrics.sensors.SensorOverlays;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
-
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific enroll client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint>
-        implements Udfps {
-
-    private static final String TAG = "FingerprintEnrollClient";
-
-    @NonNull private final SensorOverlays mSensorOverlays;
-    private final @FingerprintManager.EnrollReason int mEnrollReason;
-    @NonNull private final AuthenticationStateListeners mAuthenticationStateListeners;
-    private boolean mIsPointerDown;
-
-    FingerprintEnrollClient(
-            @NonNull Context context, @NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
-            @NonNull IBinder token, long requestId,
-            @NonNull ClientMonitorCallbackConverter listener, int userId,
-            @NonNull byte[] hardwareAuthToken, @NonNull String owner,
-            @NonNull BiometricUtils<Fingerprint> utils, int timeoutSec, int sensorId,
-            @NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
-            @Nullable IUdfpsOverlayController udfpsOverlayController,
-            // TODO(b/288175061): remove with Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
-            @Nullable ISidefpsController sidefpsController,
-            @NonNull AuthenticationStateListeners authenticationStateListeners,
-            @FingerprintManager.EnrollReason int enrollReason,
-            @NonNull FingerprintEnrollOptions options) {
-        super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
-                timeoutSec, sensorId, true /* shouldVibrate */, biometricLogger,
-                biometricContext,
-                BiometricFingerprintConstants.reasonToMetric(options.getEnrollReason()));
-        setRequestId(requestId);
-        if (sidefpsControllerRefactor()) {
-            mSensorOverlays = new SensorOverlays(udfpsOverlayController);
-        } else {
-            mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
-        }
-        mAuthenticationStateListeners = authenticationStateListeners;
-
-        mEnrollReason = enrollReason;
-        if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
-            getLogger().disableMetrics();
-        }
-        Slog.w(TAG, "EnrollOptions "
-                + FingerprintEnrollOptions.enrollReasonToString(options.getEnrollReason()));
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-
-        BiometricNotificationUtils.cancelFingerprintEnrollNotification(getContext());
-    }
-
-    @NonNull
-    @Override
-    protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
-        return new ClientMonitorCompositeCallback(
-                getLogger().getAmbientLightProbe(true /* startWithClient */), callback);
-    }
-
-    @Override
-    protected boolean hasReachedEnrollmentLimit() {
-        final int limit = getContext().getResources().getInteger(
-                com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
-        final int enrolled = mBiometricUtils.getBiometricsForUser(getContext(), getTargetUserId())
-                .size();
-        if (enrolled >= limit) {
-            Slog.w(TAG, "Too many fingerprints registered, user: " + getTargetUserId());
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected void startHalOperation() {
-        mSensorOverlays.show(getSensorId(), getRequestReasonFromEnrollReason(mEnrollReason),
-                this);
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStarted(
-                    getRequestReasonFromEnrollReason(mEnrollReason));
-        }
-
-        BiometricNotificationUtils.cancelBadCalibrationNotification(getContext());
-        try {
-            // GroupId was never used. In fact, groupId is always the same as userId.
-            getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting enroll", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mSensorOverlays.hide(getSensorId());
-            if (sidefpsControllerRefactor()) {
-                mAuthenticationStateListeners.onAuthenticationStopped();
-            }
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    protected void stopHalOperation() {
-        mSensorOverlays.hide(getSensorId());
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStopped();
-        }
-
-        try {
-            getFreshDaemon().cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting cancel", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
-                    0 /* vendorCode */);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
-        super.onEnrollResult(identifier, remaining);
-
-        mSensorOverlays.ifUdfps(
-                controller -> controller.onEnrollmentProgress(getSensorId(), remaining));
-
-        if (remaining == 0) {
-            mSensorOverlays.hide(getSensorId());
-            if (sidefpsControllerRefactor()) {
-                mAuthenticationStateListeners.onAuthenticationStopped();
-            }
-        }
-    }
-
-    @Override
-    public void onAcquired(int acquiredInfo, int vendorCode) {
-        super.onAcquired(acquiredInfo, vendorCode);
-
-        mSensorOverlays.ifUdfps(controller -> {
-            if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
-                controller.onEnrollmentHelp(getSensorId());
-            }
-        });
-
-        mCallback.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
-    }
-
-    @Override
-    public void onError(int errorCode, int vendorCode) {
-        super.onError(errorCode, vendorCode);
-
-        mSensorOverlays.hide(getSensorId());
-        if (sidefpsControllerRefactor()) {
-            mAuthenticationStateListeners.onAuthenticationStopped();
-        }
-    }
-
-    @Override
-    public void onPointerDown(PointerContext pc) {
-        mIsPointerDown = true;
-        UdfpsHelper.onFingerDown(getFreshDaemon(), (int) pc.x, (int) pc.y, pc.minor, pc.major);
-    }
-
-    @Override
-    public void onPointerUp(PointerContext pc) {
-        mIsPointerDown = false;
-        UdfpsHelper.onFingerUp(getFreshDaemon());
-    }
-
-    @Override
-    public boolean isPointerDown() {
-        return mIsPointerDown;
-    }
-
-    @Override
-    public void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event) {
-        // Unsupported in HIDL.
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java
deleted file mode 100644
index 3bb7135..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.GenerateChallengeClient;
-
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific generateChallenge/preEnroll client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-public class FingerprintGenerateChallengeClient
-        extends GenerateChallengeClient<IBiometricsFingerprint> {
-
-    private static final String TAG = "FingerprintGenerateChallengeClient";
-
-    FingerprintGenerateChallengeClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner,
-            int sensorId, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext) {
-        super(context, lazyDaemon, token, listener, userId, owner, sensorId, logger,
-                biometricContext);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            final long challenge = getFreshDaemon().preEnroll();
-            try {
-                getListener().onChallengeGenerated(getSensorId(), getTargetUserId(), challenge);
-                mCallback.onClientFinished(this, true /* success */);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote exception", e);
-                mCallback.onClientFinished(this, false /* success */);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "preEnroll failed", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalCleanupClient.java
deleted file mode 100644
index 8b61f59..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalCleanupClient.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.Fingerprint;
-import android.os.IBinder;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.InternalCleanupClient;
-import com.android.server.biometrics.sensors.InternalEnumerateClient;
-import com.android.server.biometrics.sensors.RemovalClient;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific internal cleanup client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-class FingerprintInternalCleanupClient
-        extends InternalCleanupClient<Fingerprint, IBiometricsFingerprint> {
-
-    FingerprintInternalCleanupClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, int userId,
-            @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull BiometricUtils<Fingerprint> utils,
-            @NonNull Map<Integer, Long> authenticatorIds) {
-        super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
-                utils, authenticatorIds);
-    }
-
-    @Override
-    protected InternalEnumerateClient<IBiometricsFingerprint> getEnumerateClient(
-            Context context, Supplier<IBiometricsFingerprint> lazyDaemon, IBinder token,
-            int userId, String owner, List<Fingerprint> enrolledList,
-            BiometricUtils<Fingerprint> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        return new FingerprintInternalEnumerateClient(context, lazyDaemon, token, userId, owner,
-                enrolledList, utils, sensorId, logger, biometricContext);
-    }
-
-    @Override
-    protected RemovalClient<Fingerprint, IBiometricsFingerprint> getRemovalClient(Context context,
-            Supplier<IBiometricsFingerprint> lazyDaemon, IBinder token,
-            int biometricId, int userId, String owner, BiometricUtils<Fingerprint> utils,
-            int sensorId, @NonNull BiometricLogger logger,
-            @NonNull BiometricContext biometricContext, Map<Integer, Long> authenticatorIds) {
-        // Internal remove does not need to send results to anyone. Cleanup (enumerate + remove)
-        // is all done internally.
-        return new FingerprintRemovalClient(context, lazyDaemon, token,
-                null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils,
-                sensorId, logger, biometricContext, authenticatorIds);
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalEnumerateClient.java
deleted file mode 100644
index 0840f1b..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintInternalEnumerateClient.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.Fingerprint;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.InternalEnumerateClient;
-
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific internal enumerate client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-class FingerprintInternalEnumerateClient extends InternalEnumerateClient<IBiometricsFingerprint> {
-    private static final String TAG = "FingerprintInternalEnumerateClient";
-
-    FingerprintInternalEnumerateClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
-            int userId, @NonNull String owner, @NonNull List<Fingerprint> enrolledList,
-            @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        super(context, lazyDaemon, token, userId, owner, enrolledList, utils, sensorId,
-                logger, biometricContext);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().enumerate();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting enumerate", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java
deleted file mode 100644
index 9ec56c2..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.Fingerprint;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.RemovalClient;
-
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific removal client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-class FingerprintRemovalClient extends RemovalClient<Fingerprint, IBiometricsFingerprint> {
-    private static final String TAG = "FingerprintRemovalClient";
-
-    private final int mBiometricId;
-
-    FingerprintRemovalClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
-            @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId,
-            @NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull Map<Integer, Long> authenticatorIds) {
-        super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
-                logger, biometricContext, authenticatorIds);
-        mBiometricId = biometricId;
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            // GroupId was never used. In fact, groupId is always the same as userId.
-            getFreshDaemon().remove(getTargetUserId(), mBiometricId);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when requesting remove", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java
deleted file mode 100644
index 843fcc8..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java
+++ /dev/null
@@ -1,61 +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.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-
-/**
- * Clears lockout, which is handled in the framework (and not the HAL) for the
- * [email protected] interface.
- */
-public class FingerprintResetLockoutClient extends BaseClientMonitor {
-
-    @NonNull final LockoutFrameworkImpl mLockoutTracker;
-
-    public FingerprintResetLockoutClient(@NonNull Context context, int userId,
-            @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull LockoutFrameworkImpl lockoutTracker) {
-        super(context, null /* token */, null /* listener */, userId, owner, 0 /* cookie */,
-                sensorId, logger, biometricContext);
-        mLockoutTracker = lockoutTracker;
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-        mLockoutTracker.resetFailedAttemptsForUser(true /* clearAttemptCounter */,
-                getTargetUserId());
-        callback.onClientFinished(this, true /* success */);
-    }
-
-    public boolean interruptsPrecedingClients() {
-        return true;
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_RESET_LOCKOUT;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRevokeChallengeClient.java
deleted file mode 100644
index 6273417..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRevokeChallengeClient.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.RevokeChallengeClient;
-
-import java.util.function.Supplier;
-
-/**
- * Fingerprint-specific revokeChallenge client supporting the
- * {@link android.hardware.biometrics.fingerprint.V2_1} and
- * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
- */
-public class FingerprintRevokeChallengeClient
-        extends RevokeChallengeClient<IBiometricsFingerprint> {
-
-    private static final String TAG = "FingerprintRevokeChallengeClient";
-
-    FingerprintRevokeChallengeClient(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
-            int userId, @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
-        super(context, lazyDaemon, token, userId, owner, sensorId, logger, biometricContext);
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            getFreshDaemon().postEnroll();
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "revokeChallenge/postEnroll failed", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClientLegacy.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClientLegacy.java
deleted file mode 100644
index fc85402..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClientLegacy.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.os.Build;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.os.SELinux;
-import android.util.Slog;
-
-import com.android.server.biometrics.BiometricsProto;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.HalClientMonitor;
-
-import java.io.File;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * TODO(b/304604965): Delete this class once Flags.DE_HIDL is ready for release.
- */
-public class FingerprintUpdateActiveUserClientLegacy extends
-        HalClientMonitor<IBiometricsFingerprint> {
-    private static final String TAG = "FingerprintUpdateActiveUserClient";
-    private static final String FP_DATA_DIR = "fpdata";
-
-    private final Supplier<Integer> mCurrentUserId;
-    private final boolean mForceUpdateAuthenticatorId;
-    private final boolean mHasEnrolledBiometrics;
-    private final Map<Integer, Long> mAuthenticatorIds;
-    private File mDirectory;
-
-    FingerprintUpdateActiveUserClientLegacy(@NonNull Context context,
-            @NonNull Supplier<IBiometricsFingerprint> lazyDaemon, int userId,
-            @NonNull String owner, int sensorId,
-            @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
-            @NonNull Supplier<Integer> currentUserId,
-            boolean hasEnrolledBiometrics, @NonNull Map<Integer, Long> authenticatorIds,
-            boolean forceUpdateAuthenticatorId) {
-        super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner,
-                0 /* cookie */, sensorId, logger, biometricContext);
-        mCurrentUserId = currentUserId;
-        mForceUpdateAuthenticatorId = forceUpdateAuthenticatorId;
-        mHasEnrolledBiometrics = hasEnrolledBiometrics;
-        mAuthenticatorIds = authenticatorIds;
-    }
-
-    @Override
-    public void start(@NonNull ClientMonitorCallback callback) {
-        super.start(callback);
-
-        if (mCurrentUserId.get() == getTargetUserId() && !mForceUpdateAuthenticatorId) {
-            Slog.d(TAG, "Already user: " + mCurrentUserId + ", returning");
-            callback.onClientFinished(this, true /* success */);
-            return;
-        }
-
-        int firstSdkInt = Build.VERSION.DEVICE_INITIAL_SDK_INT;
-        if (firstSdkInt < Build.VERSION_CODES.BASE) {
-            Slog.e(TAG, "First SDK version " + firstSdkInt + " is invalid; must be "
-                    + "at least VERSION_CODES.BASE");
-        }
-        File baseDir;
-        if (firstSdkInt <= Build.VERSION_CODES.O_MR1) {
-            baseDir = Environment.getUserSystemDirectory(getTargetUserId());
-        } else {
-            baseDir = Environment.getDataVendorDeDirectory(getTargetUserId());
-        }
-
-        mDirectory = new File(baseDir, FP_DATA_DIR);
-        if (!mDirectory.exists()) {
-            if (!mDirectory.mkdir()) {
-                Slog.e(TAG, "Cannot make directory: " + mDirectory.getAbsolutePath());
-                callback.onClientFinished(this, false /* success */);
-                return;
-            }
-            // Calling mkdir() from this process will create a directory with our
-            // permissions (inherited from the containing dir). This command fixes
-            // the label.
-            if (!SELinux.restorecon(mDirectory)) {
-                Slog.e(TAG, "Restorecons failed. Directory will have wrong label.");
-                callback.onClientFinished(this, false /* success */);
-                return;
-            }
-        }
-
-        startHalOperation();
-    }
-
-    @Override
-    public void unableToStart() {
-        // Nothing to do here
-    }
-
-    @Override
-    protected void startHalOperation() {
-        try {
-            final int targetId = getTargetUserId();
-            Slog.d(TAG, "Setting active user: " + targetId);
-            getFreshDaemon().setActiveGroup(targetId, mDirectory.getAbsolutePath());
-            mAuthenticatorIds.put(targetId, mHasEnrolledBiometrics
-                    ? getFreshDaemon().getAuthenticatorId() : 0L);
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to setActiveGroup: " + e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
-    }
-
-    @Override
-    public int getProtoEnum() {
-        return BiometricsProto.CM_UPDATE_ACTIVE_USER;
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSensorAdapter.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSensorAdapter.java
index 47fdcdb9..3214b6d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSensorAdapter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSensorAdapter.java
@@ -186,7 +186,7 @@
                 mLockoutTracker,
                 mLockoutResetDispatcher,
                 mAuthSessionCoordinator,
-                () -> {}, mAidlResponseHandlerCallback);
+                mAidlResponseHandlerCallback);
     }
 
     @VisibleForTesting IBiometricsFingerprint getIBiometricsFingerprint() {
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index d060c7c..54cb9c9 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -4885,7 +4885,6 @@
         if (type == WAKE_TYPE_PARTIAL) {
             // Only care about partial wake locks, since full wake locks
             // will be canceled when the user puts the screen to sleep.
-            aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
             if (historyName == null) {
                 historyName = name;
             }
@@ -5205,20 +5204,14 @@
     }
 
     @GuardedBy("this")
-    void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) {
+    public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
         if (mLastWakeupReason != null) {
             long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs;
             SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
             timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds
             mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason,
                     mLastWakeupElapsedTimeMs);
-            mLastWakeupReason = null;
         }
-    }
-
-    @GuardedBy("this")
-    public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
-        aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
         mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason);
         mLastWakeupReason = reason;
         mLastWakeupUptimeMs = uptimeMs;
diff --git a/services/core/java/com/android/server/tracing/TracingServiceProxy.java b/services/core/java/com/android/server/tracing/TracingServiceProxy.java
index 10e868d..c1d92cf 100644
--- a/services/core/java/com/android/server/tracing/TracingServiceProxy.java
+++ b/services/core/java/com/android/server/tracing/TracingServiceProxy.java
@@ -119,8 +119,13 @@
     }
 
     @Override
-    public void onStart() {
-        publishBinderService(TRACING_SERVICE_PROXY_BINDER_NAME, mTracingServiceProxy);
+    public void onStart() {}
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+            publishBinderService(TRACING_SERVICE_PROXY_BINDER_NAME, mTracingServiceProxy);
+        }
     }
 
     private void notifyTraceur(boolean sessionStolen) {
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 5e34596..a821f545 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -35,6 +35,7 @@
 import android.provider.Settings;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
+import android.util.Slog;
 import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
@@ -201,6 +202,7 @@
             ActivityManager.getService().killPackageDependents(packageName,
                     UserHandle.USER_ALL);
         } catch (RemoteException e) {
+            Slog.wtf(TAG, "failed to call killPackageDependents for " + packageName, e);
         }
     }
 
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 532ff98..dcf20f9 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -186,9 +186,12 @@
                 }
                 onWebViewProviderChanged(mCurrentWebViewPackage);
             }
+        } catch (WebViewPackageMissingException e) {
+            Slog.e(TAG, "Could not find valid WebView package to create relro with", e);
         } catch (Throwable t) {
-            // Log and discard errors at this stage as we must not crash the system server.
-            Slog.e(TAG, "error preparing webview provider from system server", t);
+            // We don't know a case when this should happen but we log and discard errors at this
+            // stage as we must not crash the system server.
+            Slog.wtf(TAG, "error preparing webview provider from system server", t);
         }
 
         if (getCurrentWebViewPackage() == null) {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
index fb338ba..993597e 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
@@ -247,9 +247,12 @@
                 attemptRepair();
             }
 
+        } catch (WebViewPackageMissingException e) {
+            Slog.e(TAG, "Could not find valid WebView package to create relro with", e);
         } catch (Throwable t) {
-            // Log and discard errors at this stage as we must not crash the system server.
-            Slog.e(TAG, "error preparing webview provider from system server", t);
+            // We don't know a case when this should happen but we log and discard errors at this
+            // stage as we must not crash the system server.
+            Slog.wtf(TAG, "error preparing webview provider from system server", t);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
index 9647a62..521f64f 100644
--- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
+++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
@@ -389,7 +389,11 @@
             return mCheckedOptions;
         }
 
-        /** Returns the {@link Runnable} object to clear options Animation. */
+        /**
+         * Returns the {@link Runnable} object to clear options Animation. Note that the runnable
+         * should not be executed inside a lock because the implementation of runnable holds window
+         * manager's lock.
+         */
         @Nullable
         public Runnable getClearOptionsAnimationRunnable() {
             return mClearOptionsAnimation;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 42373aa..bf094ed 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4479,6 +4479,7 @@
         getDisplayContent().mOpeningApps.remove(this);
         getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
         mWmService.mSnapshotController.onAppRemoved(this);
+        mAtmService.mStartingProcessActivities.remove(this);
 
         mTaskSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
         mTaskSupervisor.mStoppingActivities.remove(this);
@@ -6221,6 +6222,10 @@
     }
 
     boolean shouldBeVisible() {
+        return shouldBeVisible(false /* ignoringKeyguard */);
+    }
+
+    boolean shouldBeVisible(boolean ignoringKeyguard) {
         final Task task = getTask();
         if (task == null) {
             return false;
@@ -6228,7 +6233,7 @@
 
         final boolean behindOccludedContainer = !task.shouldBeVisible(null /* starting */)
                 || task.getOccludingActivityAbove(this) != null;
-        return shouldBeVisible(behindOccludedContainer, false /* ignoringKeyguard */);
+        return shouldBeVisible(behindOccludedContainer, ignoringKeyguard);
     }
 
     void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
@@ -10510,8 +10515,7 @@
         if (!getTurnScreenOnFlag()) {
             return false;
         }
-        final Task rootTask = getRootTask();
-        return mCurrentLaunchCanTurnScreenOn && rootTask != null
+        return mCurrentLaunchCanTurnScreenOn
                 && mTaskSupervisor.getKeyguardController().checkKeyguardVisibility(this);
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 182e1c1..2cccd33 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -523,8 +523,11 @@
     void onActivityLaunched(TaskInfo taskInfo, ActivityRecord r) {
         final SparseArray<ActivityInterceptorCallback> callbacks =
                 mService.getActivityInterceptorCallbacks();
-        ActivityInterceptorCallback.ActivityInterceptorInfo info = getInterceptorInfo(
-                r::clearOptionsAnimationForSiblings);
+        final ActivityInterceptorCallback.ActivityInterceptorInfo info = getInterceptorInfo(() -> {
+            synchronized (mService.mGlobalLock) {
+                r.clearOptionsAnimationForSiblings();
+            }
+        });
         for (int i = 0; i < callbacks.size(); i++) {
             final ActivityInterceptorCallback callback = callbacks.valueAt(i);
             callback.onActivityLaunched(taskInfo, r.info, info);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index a0f615b..d984fb1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -390,6 +390,9 @@
 
     final VisibleActivityProcessTracker mVisibleActivityProcessTracker;
 
+    /** The starting activities which are waiting for their processes to attach. */
+    final ArrayList<ActivityRecord> mStartingProcessActivities = new ArrayList<>();
+
     /* Global service lock used by the package the owns this service. */
     final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
     /**
@@ -4331,6 +4334,9 @@
             if (mDemoteTopAppReasons != 0) {
                 pw.println("  mDemoteTopAppReasons=" + mDemoteTopAppReasons);
             }
+            if (!mStartingProcessActivities.isEmpty()) {
+                pw.println("  mStartingProcessActivities=" + mStartingProcessActivities);
+            }
         }
 
         if (!printedAnything) {
@@ -5178,6 +5184,13 @@
 
     void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
             String hostingType) {
+        if (!mStartingProcessActivities.contains(activity)) {
+            mStartingProcessActivities.add(activity);
+        } else if (mProcessNames.get(
+                activity.processName, activity.info.applicationInfo.uid) != null) {
+            // The process is already starting. Wait for it to attach.
+            return;
+        }
         try {
             if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
@@ -6174,7 +6187,20 @@
         @Override
         public void onProcessRemoved(String name, int uid) {
             synchronized (mGlobalLockWithoutBoost) {
-                mProcessNames.remove(name, uid);
+                final WindowProcessController proc = mProcessNames.remove(name, uid);
+                if (proc != null && !mStartingProcessActivities.isEmpty()) {
+                    for (int i = mStartingProcessActivities.size() - 1; i >= 0; i--) {
+                        final ActivityRecord r = mStartingProcessActivities.get(i);
+                        if (uid == r.info.applicationInfo.uid && name.equals(r.processName)) {
+                            Slog.w(TAG, proc + " is removed with pending start " + r);
+                            mStartingProcessActivities.remove(i);
+                            // If visible, finish it to avoid getting stuck on screen.
+                            if (r.isVisibleRequested()) {
+                                r.finishIfPossible("starting-proc-removed", false /* oomAdj */);
+                            }
+                        }
+                    }
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index d709fa5..d0c6e15 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -811,6 +811,13 @@
         return mAnimationHandler.isTarget(wc, wc.isVisibleRequested() /* open */);
     }
 
+    boolean shouldPauseTouch(WindowContainer wc) {
+        // Once the close transition is ready, it means the onBackInvoked callback has invoked, and
+        // app is ready to trigger next transition, no matter what it will be.
+        return mAnimationHandler.mComposed && mWaitTransitionFinish == null
+                && mAnimationHandler.isTarget(wc, wc.isVisibleRequested() /* open */);
+    }
+
     /**
      * Cleanup animation, this can either happen when legacy transition ready, or when the Shell
      * transition finish.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index e9a877e..1e88fe4 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -72,7 +72,6 @@
 import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
 import static com.android.server.wm.Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
 import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
-import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_INVISIBLE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -270,8 +269,6 @@
     private int mTmpTaskLayerRank;
     private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable();
 
-    private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper();
-
     private String mDestroyAllActivitiesReason;
     private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
         @Override
@@ -1838,11 +1835,39 @@
     }
 
     boolean attachApplication(WindowProcessController app) throws RemoteException {
-        try {
-            return mAttachApplicationHelper.process(app);
-        } finally {
-            mAttachApplicationHelper.reset();
+        final ArrayList<ActivityRecord> activities = mService.mStartingProcessActivities;
+        RemoteException remoteException = null;
+        boolean hasActivityStarted = false;
+        for (int i = activities.size() - 1; i >= 0; i--) {
+            final ActivityRecord r = activities.get(i);
+            if (app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
+                // The attaching process does not match the starting activity.
+                continue;
+            }
+            // Consume the pending record.
+            activities.remove(i);
+            final TaskFragment tf = r.getTaskFragment();
+            if (tf == null || r.finishing || r.app != null
+                    // Ignore keyguard because the app may use show-when-locked when creating.
+                    || !r.shouldBeVisible(true /* ignoringKeyguard */)
+                    || !r.showToCurrentUser()) {
+                continue;
+            }
+            try {
+                final boolean canResume = r.isFocusable() && r == tf.topRunningActivity();
+                if (mTaskSupervisor.realStartActivityLocked(r, app, canResume,
+                        true /* checkConfig */)) {
+                    hasActivityStarted = true;
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Exception in new process when starting " + r, e);
+                remoteException = e;
+            }
         }
+        if (remoteException != null) {
+            throw remoteException;
+        }
+        return hasActivityStarted;
     }
 
     /**
@@ -3748,67 +3773,4 @@
             }
         }
     }
-
-    private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
-        private boolean mHasActivityStarted;
-        private RemoteException mRemoteException;
-        private WindowProcessController mApp;
-        private ActivityRecord mTop;
-
-        void reset() {
-            mHasActivityStarted = false;
-            mRemoteException = null;
-            mApp = null;
-            mTop = null;
-        }
-
-        boolean process(WindowProcessController app) throws RemoteException {
-            mApp = app;
-            for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-                getChildAt(displayNdx).forAllRootTasks(this);
-                if (mRemoteException != null) {
-                    throw mRemoteException;
-                }
-            }
-            if (!mHasActivityStarted) {
-                ensureActivitiesVisible();
-            }
-            return mHasActivityStarted;
-        }
-
-        @Override
-        public void accept(Task rootTask) {
-            if (mRemoteException != null) {
-                return;
-            }
-            if (rootTask.getVisibility(null /* starting */)
-                    == TASK_FRAGMENT_VISIBILITY_INVISIBLE) {
-                return;
-            }
-            mTop = rootTask.topRunningActivity();
-            rootTask.forAllActivities(this);
-        }
-
-        @Override
-        public boolean test(ActivityRecord r) {
-            if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
-                    || r.app != null || mApp.mUid != r.info.applicationInfo.uid
-                    || !mApp.mName.equals(r.processName)) {
-                return false;
-            }
-
-            try {
-                if (mTaskSupervisor.realStartActivityLocked(r, mApp,
-                        mTop == r && r.getTask().canBeResumed(r) /* andResume */,
-                        true /* checkConfig */)) {
-                    mHasActivityStarted = true;
-                }
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Exception in new application when starting activity " + mTop, e);
-                mRemoteException = e;
-                return true;
-            }
-            return false;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ed88b5a..143605a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2446,6 +2446,9 @@
             ProtoLog.i(WM_DEBUG_SCREEN_ON,
                     "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
                             viewVisibility, new RuntimeException().fillInStackTrace());
+            if (becameVisible) {
+                onWindowVisible(win);
+            }
 
             win.setDisplayLayoutNeeded();
             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
@@ -10168,7 +10171,7 @@
      * Called to notify WMS that the specified window has become visible. This shows a Toast if the
      * window is deemed to hold sensitive content.
      */
-    void onWindowVisible(@NonNull WindowState w) {
+    private void onWindowVisible(@NonNull WindowState w) {
         showToastIfBlockingScreenCapture(w);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index d340272..1f06bfa 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -1549,9 +1549,9 @@
         pw.println("        both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
         pw.println("        be ignored and framework implementation will determine aspect ratio.");
         pw.println("      --cornerRadius radius");
-        pw.println("        Corners radius for activities in the letterbox mode. If radius < 0,");
-        pw.println("        both it and R.integer.config_letterboxActivityCornersRadius will be");
-        pw.println("        ignored and corners of the activity won't be rounded.");
+        pw.println("        Corners radius (in pixels) for activities in the letterbox mode.");
+        pw.println("        If radius < 0, both R.integer.config_letterboxActivityCornersRadius");
+        pw.println("        and it will be ignored and corners of the activity won't be rounded.");
         pw.println("      --backgroundType [reset|solid_color|app_color_background");
         pw.println("          |app_color_background_floating|wallpaper]");
         pw.println("        Type of background used in the letterbox mode.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4d9fc6c..2fcee50 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -28,7 +28,6 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 import static android.os.PowerManager.DRAW_WAKE_LOCK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.permission.flags.Flags.sensitiveContentImprovements;
 import static android.view.SurfaceControl.Transaction;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
@@ -2139,9 +2138,6 @@
                 }
             }
             setDisplayLayoutNeeded();
-            if (sensitiveContentImprovements() && visible) {
-                mWmService.onWindowVisible(this);
-            }
         }
     }
 
@@ -2974,6 +2970,11 @@
             return true;
         }
 
+        // Do not allow back predictive animation target to receive touch, app can trigger an
+        // unexpected transition so basically unable to polish it.
+        if (mWmService.mAtmService.mBackNavigationController.shouldPauseTouch(mActivityRecord)) {
+            return false;
+        }
         return !mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
                 && mActivityRecord.isVisibleRequested();
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
index 94c1374..d1830126 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
@@ -215,6 +215,9 @@
         } catch (PackageManager.NameNotFoundException e) {
             return false;
         }
+        if (packageInfo.applicationInfo == null || packageInfo.applicationInfo.metaData == null) {
+            return false;
+        }
         final String metadataKey = sActionToMetadataKeyMap.get(provisioningAction);
         return packageInfo.applicationInfo.metaData.getBoolean(metadataKey);
     }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index 7e04277..90b131a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -16,10 +16,10 @@
 
 package com.android.server.biometrics;
 
-import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS;
 import static android.Manifest.permission.MANAGE_BIOMETRIC;
 import static android.Manifest.permission.TEST_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS;
@@ -65,8 +65,6 @@
 import android.os.UserHandle;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -204,43 +202,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(com.android.server.biometrics.Flags.FLAG_DE_HIDL)
-    public void testRegisterAuthenticator_registerAuthenticators() throws Exception {
-        final int fingerprintId = 0;
-        final int fingerprintStrength = 15;
-
-        final int faceId = 1;
-        final int faceStrength = 15;
-
-        final String[] config = {
-                // ID0:Fingerprint:Strong
-                String.format("%d:2:%d", fingerprintId, fingerprintStrength),
-                // ID2:Face:Convenience
-                String.format("%d:8:%d", faceId, faceStrength)
-        };
-
-        when(mInjector.getConfiguration(any())).thenReturn(config);
-
-        mAuthService = new AuthService(mContext, mInjector);
-        mAuthService.onStart();
-
-        verify(mFingerprintService).registerAuthenticators(mFingerprintPropsCaptor.capture());
-        final FingerprintSensorPropertiesInternal fingerprintProp =
-                mFingerprintPropsCaptor.getValue().get(0);
-        assertEquals(fingerprintProp.sensorId, fingerprintId);
-        assertEquals(fingerprintProp.sensorStrength,
-                Utils.authenticatorStrengthToPropertyStrength(fingerprintStrength));
-
-        verify(mFaceService).registerAuthenticators(mFacePropsCaptor.capture());
-        final FaceSensorPropertiesInternal faceProp = mFacePropsCaptor.getValue().get(0);
-        assertEquals(faceProp.sensorId, faceId);
-        assertEquals(faceProp.sensorStrength,
-                Utils.authenticatorStrengthToPropertyStrength(faceStrength));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(com.android.server.biometrics.Flags.FLAG_DE_HIDL)
-    public void testRegisterAuthenticator_registerAuthenticatorsLegacy() throws RemoteException {
+    public void testRegisterAuthenticator_registerAuthenticators() throws RemoteException {
         final int fingerprintId = 0;
         final int fingerprintStrength = 15;
 
@@ -265,7 +227,7 @@
         mFingerprintLooper.dispatchAll();
         mFaceLooper.dispatchAll();
 
-        verify(mFingerprintService).registerAuthenticatorsLegacy(
+        verify(mFingerprintService).registerAuthenticators(
                 mFingerprintSensorConfigurationsCaptor.capture());
 
         final SensorProps[] fingerprintProp = mFingerprintSensorConfigurationsCaptor.getValue()
@@ -275,8 +237,7 @@
         assertEquals(fingerprintProp[0].commonProps.sensorStrength,
                 Utils.authenticatorStrengthToPropertyStrength(fingerprintStrength));
 
-        verify(mFaceService).registerAuthenticatorsLegacy(
-                mFaceSensorConfigurationsCaptor.capture());
+        verify(mFaceService).registerAuthenticators(mFaceSensorConfigurationsCaptor.capture());
 
         final android.hardware.biometrics.face.SensorProps[] faceProp =
                 mFaceSensorConfigurationsCaptor.getValue()
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 5fd29c2..503ab8e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -76,7 +76,6 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
@@ -90,7 +89,6 @@
 import android.view.DisplayInfo;
 import android.view.WindowManager;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
@@ -246,14 +244,8 @@
         when(mInjector.getGateKeeperService()).thenReturn(mGateKeeperService);
         when(mInjector.getNotificationLogger()).thenReturn(mNotificationLogger);
         when(mGateKeeperService.getSecureUserId(anyInt())).thenReturn(42L);
-
-        if (com.android.server.biometrics.Flags.deHidl()) {
-            when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
-                    new Handler(TestableLooper.get(this).getLooper()));
-        } else {
-            when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
-                    new Handler(Looper.getMainLooper()));
-        }
+        when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
+                new Handler(TestableLooper.get(this).getLooper()));
 
         final String[] config = {
                 "0:2:15",  // ID0:Fingerprint:Strong
@@ -2037,11 +2029,7 @@
     }
 
     private void waitForIdle() {
-        if (com.android.server.biometrics.Flags.deHidl()) {
-            TestableLooper.get(this).processAllMessages();
-        } else {
-            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        }
+        TestableLooper.get(this).processAllMessages();
     }
 
     private byte[] generateRandomHAT() {
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 c7300bb..960357f 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
@@ -87,8 +87,12 @@
     private ISessionListener mSessionListener;
     @Mock
     private WindowManager mWindowManager;
+    @Mock
+    private Consumer<OperationContext> mStartHalConsumer;
 
-    private OperationContextExt mOpContext = new OperationContextExt(true);
+    private final FingerprintAuthenticateOptions mAuthenticateOptions =
+            new FingerprintAuthenticateOptions.Builder().build();
+    private final OperationContextExt mOpContext = new OperationContextExt(true);
     private IBiometricContextListener mListener;
     private BiometricContextProvider mProvider;
 
@@ -200,11 +204,11 @@
         final List<Integer> actual = new ArrayList<>();
         final List<Integer> expected = List.of(FoldState.FULLY_CLOSED, FoldState.FULLY_OPENED,
                 FoldState.UNKNOWN, FoldState.HALF_OPENED);
-        mProvider.subscribe(mOpContext, ctx -> {
+        mProvider.subscribe(mOpContext, mStartHalConsumer, ctx -> {
             assertThat(ctx).isSameInstanceAs(mOpContext.toAidlContext());
             assertThat(mProvider.getFoldState()).isEqualTo(ctx.foldState);
             actual.add(ctx.foldState);
-        });
+        }, mAuthenticateOptions);
 
         for (int v : expected) {
             mListener.onFoldChanged(v);
@@ -228,11 +232,11 @@
                 AuthenticateOptions.DISPLAY_STATE_NO_UI,
                 AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN);
 
-        mProvider.subscribe(mOpContext, ctx -> {
+        mProvider.subscribe(mOpContext, mStartHalConsumer, ctx -> {
             assertThat(ctx).isSameInstanceAs(mOpContext.toAidlContext());
             assertThat(mProvider.getDisplayState()).isEqualTo(ctx.displayState);
             actual.add(ctx.displayState);
-        });
+        }, mAuthenticateOptions);
 
         for (int v : expected) {
             mListener.onDisplayStateChanged(v);
@@ -250,11 +254,11 @@
     public void testSubscribesToAod() throws RemoteException {
         final List<Boolean> actual = new ArrayList<>();
 
-        mProvider.subscribe(mOpContext, ctx -> {
+        mProvider.subscribe(mOpContext, mStartHalConsumer, ctx -> {
             assertThat(ctx).isSameInstanceAs(mOpContext.toAidlContext());
             assertThat(mProvider.isAod()).isEqualTo(ctx.isAod);
             actual.add(ctx.isAod);
-        });
+        }, mAuthenticateOptions);
 
         for (int v : List.of(
                 AuthenticateOptions.DISPLAY_STATE_AOD,
@@ -273,10 +277,10 @@
     public void testSubscribesToAwake() throws RemoteException {
         final List<Boolean> actual = new ArrayList<>();
 
-        mProvider.subscribe(mOpContext, ctx -> {
+        mProvider.subscribe(mOpContext, mStartHalConsumer, ctx -> {
             assertThat(ctx).isSameInstanceAs(mOpContext.toAidlContext());
             actual.add(mProvider.isAwake());
-        });
+        }, mAuthenticateOptions);
 
         for (int v : List.of(
                 AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN,
@@ -295,14 +299,15 @@
     public void testSubscribesWithDifferentState() throws RemoteException {
         final Consumer<OperationContext> nonEmptyConsumer = mock(Consumer.class);
         mListener.onDisplayStateChanged(AuthenticateOptions.DISPLAY_STATE_AOD);
-        mProvider.subscribe(mOpContext, nonEmptyConsumer);
-        verify(nonEmptyConsumer).accept(same(mOpContext.toAidlContext()));
+        mProvider.subscribe(mOpContext, mStartHalConsumer, nonEmptyConsumer, mAuthenticateOptions);
+
+        assertThat(mOpContext.getDisplayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD);
     }
 
     @Test
     public void testUnsubscribes() throws RemoteException {
         final Consumer<OperationContext> emptyConsumer = mock(Consumer.class);
-        mProvider.subscribe(mOpContext, emptyConsumer);
+        mProvider.subscribe(mOpContext, mStartHalConsumer, emptyConsumer, mAuthenticateOptions);
         mProvider.unsubscribe(mOpContext);
 
         mListener.onDisplayStateChanged(AuthenticateOptions.DISPLAY_STATE_AOD);
@@ -311,7 +316,7 @@
         mListener.onDisplayStateChanged(AuthenticateOptions.DISPLAY_STATE_UNKNOWN);
 
         final Consumer<OperationContext> nonEmptyConsumer = mock(Consumer.class);
-        mProvider.subscribe(mOpContext, nonEmptyConsumer);
+        mProvider.subscribe(mOpContext, mStartHalConsumer, nonEmptyConsumer, mAuthenticateOptions);
         mListener.onDisplayStateChanged(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN);
         mProvider.unsubscribe(mOpContext);
         mListener.onDisplayStateChanged(AuthenticateOptions.DISPLAY_STATE_NO_UI);
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 971323a..fc573d2 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
@@ -52,13 +52,12 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
-import android.testing.TestableLooper;
 import android.util.Slog;
 
 import androidx.annotation.NonNull;
@@ -66,7 +65,6 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.nano.BiometricSchedulerProto;
@@ -79,7 +77,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -90,7 +89,6 @@
 @Presubmit
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
[email protected](setAsMainLooper = true)
 public class BiometricSchedulerTest {
 
     private static final String TAG = "BiometricSchedulerTest";
@@ -105,6 +103,9 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule =
             DeviceFlagsValueProvider.createCheckFlagsRule();
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
     private BiometricScheduler<IFingerprint, ISession> mScheduler;
     private IBinder mToken;
     private int mCurrentUserId = UserHandle.USER_SYSTEM;
@@ -121,8 +122,10 @@
                 mUsersStoppedCount++;
                 mCurrentUserId = UserHandle.USER_NULL;
             };
+    private TestLooper mLooper;
     private boolean mStartOperationsFinish = true;
     private int mStartUserClientCount = 0;
+
     @Mock
     private IBiometricService mBiometricService;
     @Mock
@@ -140,44 +143,39 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
         mToken = new Binder();
+        mLooper = new TestLooper();
+
         when(mAuthSessionCoordinator.getLockoutStateFor(anyInt(), anyInt())).thenReturn(
                 BIOMETRIC_SUCCESS);
         when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
-        if (Flags.deHidl()) {
-            mScheduler = new BiometricScheduler<>(
-                    new Handler(TestableLooper.get(this).getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_UNKNOWN,
-                    null /* gestureAvailabilityDispatcher */,
-                    mBiometricService,
-                    LOG_NUM_RECENT_OPERATIONS,
-                    () -> mCurrentUserId,
-                    new UserSwitchProvider<IFingerprint, ISession>() {
-                        @NonNull
-                        @Override
-                        public StopUserClient<ISession> getStopUserClient(int userId) {
-                            return new TestStopUserClient(mContext, () -> mSession, mToken, userId,
-                                    TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
-                                    mUserStoppedCallback, () -> mShouldFailStopUser);
-                        }
 
-                        @NonNull
-                        @Override
-                        public StartUserClient<IFingerprint, ISession> getStartUserClient(
-                                int newUserId) {
-                            mStartUserClientCount++;
-                            return new TestStartUserClient(mContext, () -> mFingerprint, mToken,
-                                    newUserId, TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
-                                    mUserStartedCallback, mStartOperationsFinish);
-                        }
-                    });
-        } else {
-            mScheduler = new BiometricScheduler<>(
-                    new Handler(TestableLooper.get(this).getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityTracker */,
-                    mBiometricService, LOG_NUM_RECENT_OPERATIONS);
-        }
+        mScheduler = new BiometricScheduler<>(
+                new Handler(mLooper.getLooper()),
+                BiometricScheduler.SENSOR_TYPE_UNKNOWN,
+                null /* gestureAvailabilityDispatcher */,
+                mBiometricService,
+                LOG_NUM_RECENT_OPERATIONS,
+                () -> mCurrentUserId,
+                new UserSwitchProvider<IFingerprint, ISession>() {
+                    @NonNull
+                    @Override
+                    public StopUserClient<ISession> getStopUserClient(int userId) {
+                        return new TestStopUserClient(mContext, () -> mSession, mToken, userId,
+                                TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
+                                mUserStoppedCallback, () -> mShouldFailStopUser);
+                    }
+
+                    @NonNull
+                    @Override
+                    public StartUserClient<IFingerprint, ISession> getStartUserClient(
+                            int newUserId) {
+                        mStartUserClientCount++;
+                        return new TestStartUserClient(mContext, () -> mFingerprint, mToken,
+                                newUserId, TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
+                                mUserStartedCallback, mStartOperationsFinish);
+                    }
+                });
     }
 
     @Test
@@ -657,7 +655,6 @@
     @Test
     public void testClearBiometricQueue_clearsHungAuthOperation() {
         // Creating a hung client
-        final TestableLooper looper = TestableLooper.get(this);
         final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
         final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
                 lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
@@ -676,9 +673,9 @@
         assertNotNull(mScheduler.mCurrentOperation);
         assertEquals(0, mScheduler.getCurrentPendingCount());
 
-        looper.moveTimeForward(10000);
+        mLooper.moveTimeForward(10000);
         waitForIdle();
-        looper.moveTimeForward(3000);
+        mLooper.moveTimeForward(3000);
         waitForIdle();
 
         // The hung client did not honor this operation, verify onError and authenticated
@@ -693,7 +690,6 @@
     @Test
     public void testAuthWorks_afterClearBiometricQueue() {
         // Creating a hung client
-        final TestableLooper looper = TestableLooper.get(this);
         final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
         final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
                 lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
@@ -714,10 +710,10 @@
         waitForIdle();
 
         // The watchdog should kick off the cancellation
-        looper.moveTimeForward(10000);
+        mLooper.moveTimeForward(10000);
         waitForIdle();
         // After 10 seconds the HAL has 3 seconds to respond to a cancel
-        looper.moveTimeForward(3000);
+        mLooper.moveTimeForward(3000);
         waitForIdle();
 
         // The hung client did not honor this operation, verify onError and authenticated
@@ -752,10 +748,10 @@
         client2.getCallback().onClientFinished(client2, true);
         waitForIdle();
 
-        looper.moveTimeForward(10000);
+        mLooper.moveTimeForward(10000);
         waitForIdle();
         // After 10 seconds the HAL has 3 seconds to respond to a cancel
-        looper.moveTimeForward(3000);
+        mLooper.moveTimeForward(3000);
         waitForIdle();
 
         //Asserting auth client passes
@@ -766,7 +762,6 @@
     @Test
     public void testClearBiometricQueue_doesNotClearOperationsWhenQueueNotStuck() {
         //Creating clients
-        final TestableLooper looper = TestableLooper.get(this);
         final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
         final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
                 lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
@@ -793,10 +788,10 @@
         waitForIdle();
 
         // The watchdog should kick off the cancellation
-        looper.moveTimeForward(10000);
+        mLooper.moveTimeForward(10000);
         waitForIdle();
         // After 10 seconds the HAL has 3 seconds to respond to a cancel
-        looper.moveTimeForward(3000);
+        mLooper.moveTimeForward(3000);
         waitForIdle();
 
         //Watchdog does not clear pending operations
@@ -855,7 +850,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleOperation_whenNoUser() {
         mCurrentUserId = UserHandle.USER_NULL;
 
@@ -871,7 +865,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleOperation_whenNoUser_notStarted() {
         mCurrentUserId = UserHandle.USER_NULL;
         mStartOperationsFinish = false;
@@ -896,7 +889,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleOperation_whenNoUser_notStarted_andReset() {
         mCurrentUserId = UserHandle.USER_NULL;
         mStartOperationsFinish = false;
@@ -923,7 +915,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleOperation_whenSameUser() {
         mCurrentUserId = 10;
 
@@ -940,7 +931,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleOperation_whenDifferentUser() {
         mCurrentUserId = 10;
 
@@ -961,7 +951,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testStartUser_alwaysStartsNextOperation() {
         mCurrentUserId = UserHandle.USER_NULL;
 
@@ -990,7 +979,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testStartUser_failsClearsStopUserClient() {
         mCurrentUserId = UserHandle.USER_NULL;
 
@@ -1033,7 +1021,7 @@
     }
 
     private void waitForIdle() {
-        TestableLooper.get(this).processAllMessages();
+        mLooper.dispatchAll();
     }
 
     private static class TestAuthenticateOptions implements AuthenticateOptions {
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
deleted file mode 100644
index dd5d826..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
+++ /dev/null
@@ -1,393 +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 android.testing.TestableLooper.RunWithLooper;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-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.content.Context;
-import android.hardware.biometrics.IBiometricService;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.UserHandle;
-import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.biometrics.Flags;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-
-@Presubmit
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class UserAwareBiometricSchedulerTest {
-
-    private static final String TAG = "UserAwareBiometricSchedulerTest";
-    private static final int TEST_SENSOR_ID = 0;
-
-    @Rule
-    public final MockitoRule mockito = MockitoJUnit.rule();
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule =
-            DeviceFlagsValueProvider.createCheckFlagsRule();
-
-    private Handler mHandler;
-    private UserAwareBiometricScheduler mScheduler;
-    private final IBinder mToken = new Binder();
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private IBiometricService mBiometricService;
-    @Mock
-    private BiometricLogger mBiometricLogger;
-    @Mock
-    private BiometricContext mBiometricContext;
-
-    private boolean mShouldFailStopUser = false;
-    private final StopUserClientShouldFail mStopUserClientShouldFail =
-            () -> {
-                return mShouldFailStopUser;
-            };
-    private final TestUserStartedCallback mUserStartedCallback = new TestUserStartedCallback();
-    private final TestUserStoppedCallback mUserStoppedCallback = new TestUserStoppedCallback();
-    private int mCurrentUserId = UserHandle.USER_NULL;
-    private boolean mStartOperationsFinish = true;
-    private int mStartUserClientCount = 0;
-
-    @Before
-    public void setUp() {
-        mShouldFailStopUser = false;
-        mHandler = new Handler(TestableLooper.get(this).getLooper());
-        mScheduler = new UserAwareBiometricScheduler(TAG,
-                mHandler,
-                BiometricScheduler.SENSOR_TYPE_UNKNOWN,
-                null /* gestureAvailabilityDispatcher */,
-                mBiometricService,
-                () -> mCurrentUserId,
-                new UserAwareBiometricScheduler.UserSwitchCallback() {
-                    @NonNull
-                    @Override
-                    public StopUserClient<?> getStopUserClient(int userId) {
-                        return new TestStopUserClient(mContext, Object::new, mToken, userId,
-                                TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
-                                mUserStoppedCallback, mStopUserClientShouldFail);
-                    }
-
-                    @NonNull
-                    @Override
-                    public StartUserClient<?, ?> getStartUserClient(int newUserId) {
-                        mStartUserClientCount++;
-                        return new TestStartUserClient(mContext, Object::new, mToken, newUserId,
-                                TEST_SENSOR_ID,  mBiometricLogger, mBiometricContext,
-                                mUserStartedCallback, mStartOperationsFinish);
-                    }
-                });
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void testScheduleOperation_whenNoUser() {
-        mCurrentUserId = UserHandle.USER_NULL;
-
-        final BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(0);
-
-        mScheduler.scheduleClientMonitor(nextClient);
-        waitForIdle();
-
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(0);
-        assertThat(mUserStartedCallback.mStartedUsers).containsExactly(0);
-        verify(nextClient).start(any());
-    }
-
-    @Test
-    public void testScheduleOperation_whenNoUser_notStarted() {
-        mCurrentUserId = UserHandle.USER_NULL;
-        mStartOperationsFinish = false;
-
-        final BaseClientMonitor[] nextClients = new BaseClientMonitor[]{
-                mock(BaseClientMonitor.class),
-                mock(BaseClientMonitor.class),
-                mock(BaseClientMonitor.class)
-        };
-        for (BaseClientMonitor client : nextClients) {
-            when(client.getTargetUserId()).thenReturn(5);
-            mScheduler.scheduleClientMonitor(client);
-            waitForIdle();
-        }
-
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(0);
-        assertThat(mUserStartedCallback.mStartedUsers).isEmpty();
-        assertThat(mStartUserClientCount).isEqualTo(1);
-        for (BaseClientMonitor client : nextClients) {
-            verify(client, never()).start(any());
-        }
-    }
-
-    @Test
-    public void testScheduleOperation_whenNoUser_notStarted_andReset() {
-        mCurrentUserId = UserHandle.USER_NULL;
-        mStartOperationsFinish = false;
-
-        final BaseClientMonitor client = mock(BaseClientMonitor.class);
-        when(client.getTargetUserId()).thenReturn(5);
-        mScheduler.scheduleClientMonitor(client);
-        waitForIdle();
-
-        final TestStartUserClient startUserClient =
-                (TestStartUserClient) mScheduler.mCurrentOperation.getClientMonitor();
-        mScheduler.reset();
-        assertThat(mScheduler.mCurrentOperation).isNull();
-
-        final BiometricSchedulerOperation fakeOperation = new BiometricSchedulerOperation(
-                mock(BaseClientMonitor.class), new ClientMonitorCallback() {});
-        mScheduler.mCurrentOperation = fakeOperation;
-        startUserClient.mCallback.onClientFinished(startUserClient, true);
-        assertThat(fakeOperation).isSameInstanceAs(mScheduler.mCurrentOperation);
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void testScheduleOperation_whenSameUser() {
-        mCurrentUserId = 10;
-
-        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(mCurrentUserId);
-
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-
-        verify(nextClient).start(any());
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(0);
-        assertThat(mUserStartedCallback.mStartedUsers).isEmpty();
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void testScheduleOperation_whenDifferentUser() {
-        mCurrentUserId = 10;
-
-        final int nextUserId = 11;
-        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(nextUserId);
-
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(1);
-
-        waitForIdle();
-        assertThat(mUserStartedCallback.mStartedUsers).containsExactly(nextUserId);
-
-        waitForIdle();
-        verify(nextClient).start(any());
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void testStartUser_alwaysStartsNextOperation() {
-        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(10);
-
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-        verify(nextClient).start(any());
-
-        // finish first operation
-        mScheduler.getInternalCallback().onClientFinished(nextClient, true /* success */);
-        waitForIdle();
-
-        // schedule second operation but swap out the current operation
-        // before it runs so that it's not current when it's completion callback runs
-        nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(11);
-        mUserStartedCallback.mAfterStart = () -> mScheduler.mCurrentOperation = null;
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-        verify(nextClient).start(any());
-        assertThat(mUserStartedCallback.mStartedUsers).containsExactly(10, 11).inOrder();
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(1);
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void testStartUser_failsClearsStopUserClient() {
-        // When a stop user client fails, check that mStopUserClient
-        // is set to null to prevent the scheduler from getting stuck.
-        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(10);
-
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-        verify(nextClient).start(any());
-
-        // finish first operation
-        mScheduler.getInternalCallback().onClientFinished(nextClient, true /* success */);
-        waitForIdle();
-
-        // schedule second operation but swap out the current operation
-        // before it runs so that it's not current when it's completion callback runs
-        nextClient = mock(BaseClientMonitor.class);
-        when(nextClient.getTargetUserId()).thenReturn(11);
-        mUserStartedCallback.mAfterStart = () -> mScheduler.mCurrentOperation = null;
-        mShouldFailStopUser = true;
-        mScheduler.scheduleClientMonitor(nextClient);
-
-        waitForIdle();
-        assertThat(mUserStartedCallback.mStartedUsers).containsExactly(10, 11).inOrder();
-        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(0);
-        assertThat(mScheduler.getStopUserClient()).isEqualTo(null);
-    }
-
-    private void waitForIdle() {
-        TestableLooper.get(this).processAllMessages();
-    }
-
-    private class TestUserStoppedCallback implements StopUserClient.UserStoppedCallback {
-        int mNumInvocations;
-
-        @Override
-        public void onUserStopped() {
-            mNumInvocations++;
-            mCurrentUserId = UserHandle.USER_NULL;
-        }
-    }
-
-    private class TestUserStartedCallback implements StartUserClient.UserStartedCallback<Object> {
-        final List<Integer> mStartedUsers = new ArrayList<>();
-        Runnable mAfterStart = null;
-
-        @Override
-        public void onUserStarted(int newUserId, Object newObject, int halInterfaceVersion) {
-            mStartedUsers.add(newUserId);
-            mCurrentUserId = newUserId;
-            if (mAfterStart != null) {
-                mAfterStart.run();
-            }
-        }
-    }
-
-    private interface StopUserClientShouldFail {
-        boolean shouldFail();
-    }
-
-    private class TestStopUserClient extends StopUserClient<Object> {
-        private StopUserClientShouldFail mShouldFailClient;
-        public TestStopUserClient(@NonNull Context context,
-                @NonNull Supplier<Object> lazyDaemon, @Nullable IBinder token, int userId,
-                int sensorId, @NonNull BiometricLogger logger,
-                @NonNull BiometricContext biometricContext,
-                @NonNull UserStoppedCallback callback, StopUserClientShouldFail shouldFail) {
-            super(context, lazyDaemon, token, userId, sensorId, logger, biometricContext, callback);
-            mShouldFailClient = shouldFail;
-        }
-
-        @Override
-        protected void startHalOperation() {
-
-        }
-
-        @Override
-        public void start(@NonNull ClientMonitorCallback callback) {
-            super.start(callback);
-            if (mShouldFailClient.shouldFail()) {
-                getCallback().onClientFinished(this, false /* success */);
-                // When the above fails, it means that the HAL has died, in this case we
-                // need to ensure the UserSwitchCallback correctly returns the NULL user handle.
-                mCurrentUserId = UserHandle.USER_NULL;
-            } else {
-                onUserStopped();
-            }
-        }
-
-        @Override
-        public void unableToStart() {
-
-        }
-    }
-
-    private static class TestStartUserClient extends StartUserClient<Object, Object> {
-        private final boolean mShouldFinish;
-
-        ClientMonitorCallback mCallback;
-
-        public TestStartUserClient(@NonNull Context context,
-                @NonNull Supplier<Object> lazyDaemon, @Nullable IBinder token, int userId,
-                int sensorId, @NonNull BiometricLogger logger,
-                @NonNull BiometricContext biometricContext,
-                @NonNull UserStartedCallback<Object> callback, boolean shouldFinish) {
-            super(context, lazyDaemon, token, userId, sensorId, logger, biometricContext, callback);
-            mShouldFinish = shouldFinish;
-        }
-
-        @Override
-        protected void startHalOperation() {
-
-        }
-
-        @Override
-        public void start(@NonNull ClientMonitorCallback callback) {
-            super.start(callback);
-
-            mCallback = callback;
-            if (mShouldFinish) {
-                mUserStartedCallback.onUserStarted(
-                        getTargetUserId(), new Object(), 1 /* halInterfaceVersion */);
-                callback.onClientFinished(this, true /* success */);
-            }
-        }
-
-        @Override
-        public void unableToStart() {
-
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
index e4c56a7..1ca36a3 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
@@ -147,11 +147,10 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
-    public void registerAuthenticatorsLegacy_defaultOnly() throws Exception {
+    public void registerAuthenticators_defaultOnly() throws Exception {
         initService();
 
-        mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT),
@@ -161,13 +160,13 @@
     }
 
     @Test
-    @RequiresFlagsEnabled({Flags.FLAG_DE_HIDL, Flags.FLAG_FACE_VHAL_FEATURE})
+    @RequiresFlagsEnabled(Flags.FLAG_FACE_VHAL_FEATURE)
     public void registerAuthenticatorsLegacy_virtualOnly() throws Exception {
         initService();
         Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
                 Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
 
-        mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL),
@@ -176,13 +175,13 @@
     }
 
     @Test
-    @RequiresFlagsEnabled({Flags.FLAG_DE_HIDL, Flags.FLAG_FACE_VHAL_FEATURE})
-    public void registerAuthenticatorsLegacy_virtualFaceOnly() throws Exception {
+    @RequiresFlagsEnabled(Flags.FLAG_FACE_VHAL_FEATURE)
+    public void registerAuthenticators_virtualFaceOnly() throws Exception {
         initService();
         Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
                 Settings.Secure.BIOMETRIC_FACE_VIRTUAL_ENABLED, 1);
 
-        mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL),
@@ -191,13 +190,12 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
-    public void registerAuthenticatorsLegacy_virtualAlwaysWhenNoOther() throws Exception {
+    public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
         mFaceSensorConfigurations = new FaceSensorConfigurations(false);
         mFaceSensorConfigurations.addAidlConfigs(new String[]{NAME_VIRTUAL});
         initService();
 
-        mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL),
@@ -210,7 +208,7 @@
         FaceAuthenticateOptions faceAuthenticateOptions = new FaceAuthenticateOptions.Builder()
                 .build();
         initService();
-        mFaceService.mServiceWrapper.registerAuthenticators(List.of());
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
 
         final long operationId = 5;
@@ -230,7 +228,7 @@
                 R.string.config_keyguardComponent,
                 OP_PACKAGE_NAME);
         initService();
-        mFaceService.mServiceWrapper.registerAuthenticators(List.of());
+        mFaceService.mServiceWrapper.registerAuthenticators(mFaceSensorConfigurations);
         waitForRegistration();
         mFaceService.mServiceWrapper.detectFace(mToken, mFaceServiceReceiver,
                 faceAuthenticateOptions);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index 84c3684..a556f52 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -50,8 +50,6 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -60,7 +58,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -137,6 +134,8 @@
     private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
     @Captor
     private ArgumentCaptor<Consumer<OperationContext>> mStartHalConsumerCaptor;
+    @Captor
+    private ArgumentCaptor<FaceAuthenticateOptions> mFaceAuthenticateOptionsCaptor;
 
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
@@ -159,21 +158,26 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
     public void authWithContext_v2() throws RemoteException {
         final FaceAuthenticationClient client = createClient(2);
         client.start(mCallback);
 
+        verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
+                mStartHalConsumerCaptor.capture(), mContextInjector.capture(),
+                mFaceAuthenticateOptionsCaptor.capture());
+
+        mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor.getValue().toAidlContext(
+                mFaceAuthenticateOptionsCaptor.getValue()));
         InOrder order = inOrder(mHal, mBiometricContext);
         order.verify(mBiometricContext).updateContext(
                 mOperationContextCaptor.capture(), anyBoolean());
 
         final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext();
+
         order.verify(mHal).authenticateWithContext(eq(OP_ID), same(aidlContext));
         assertThat(aidlContext.wakeReason).isEqualTo(WAKE_REASON);
         assertThat(aidlContext.authenticateReason.getFaceAuthenticateReason())
                 .isEqualTo(AUTH_REASON);
-
         verify(mHal, never()).authenticate(anyLong());
     }
 
@@ -200,30 +204,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FaceAuthenticationClient client = createClient();
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).authenticateWithContext(eq(OP_ID), captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        assertThat(opContext).isSameInstanceAs(
-                mOperationContextCaptor.getValue().toAidlContext());
-        mContextInjector.getValue().accept(opContext);
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FaceAuthenticationClient client = createClient();
         client.start(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
index e626f73..fd3f054 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
@@ -20,7 +20,6 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.verify;
@@ -37,8 +36,6 @@
 import android.os.RemoteException;
 import android.os.Vibrator;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.TestableContext;
@@ -46,7 +43,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -58,7 +54,6 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -124,49 +119,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void detectWithContext_v2() throws RemoteException {
-        final FaceDetectClient client = createClient(2);
-        client.start(mCallback);
-
-        InOrder order = inOrder(mHal, mBiometricContext);
-        order.verify(mBiometricContext).updateContext(
-                mOperationContextCaptor.capture(), anyBoolean());
-
-        final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext();
-        order.verify(mHal).detectInteractionWithContext(same(aidlContext));
-        assertThat(aidlContext.wakeReason).isEqualTo(WAKE_REASON);
-        assertThat(aidlContext.authenticateReason.getFaceAuthenticateReason())
-                .isEqualTo(AUTH_REASON);
-
-        verify(mHal, never()).detectInteraction();
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FaceDetectClient client = createClient();
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).detectInteractionWithContext(captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        assertThat(opContext).isSameInstanceAs(
-                mOperationContextCaptor.getValue().toAidlContext());
-        mContextInjector.getValue().accept(opContext);
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FaceDetectClient client = createClient();
         client.start(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClientTest.java
index 02363cd..d6b5789 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClientTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.verify;
@@ -38,8 +37,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.TestableContext;
@@ -47,7 +44,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -60,7 +56,6 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -124,45 +119,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void enrollWithContext_v2() throws RemoteException {
-        final FaceEnrollClient client = createClient(2);
-        client.start(mCallback);
-
-        InOrder order = inOrder(mHal, mBiometricContext);
-        order.verify(mBiometricContext).updateContext(
-                mOperationContextCaptor.capture(), anyBoolean());
-
-        final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext();
-        order.verify(mHal).enrollWithContext(any(), anyByte(), any(), any(), same(aidlContext));
-        verify(mHal, never()).enroll(any(), anyByte(), any(), any());
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FaceEnrollClient client = createClient(3);
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).enrollWithContext(any(), anyByte(), any(), any(), captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        assertThat(opContext).isSameInstanceAs(
-                mOperationContextCaptor.getValue().toAidlContext());
-        mContextInjector.getValue().accept(opContext);
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FaceEnrollClient client = createClient(3);
         client.start(mCallback);
@@ -192,16 +148,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void enrollWithFaceOptions() throws RemoteException {
-        final FaceEnrollClient client = createClient(4);
-        client.start(mCallback);
-
-        verify(mHal).enrollWithOptions(any());
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void enrollWithFaceOptionsAfterSubscribingContext() throws RemoteException {
         final FaceEnrollClient client = createClient(4);
         client.start(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
index 9eca93e..c4e51f8 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceProviderTest.java
@@ -44,22 +44,18 @@
 import android.hardware.face.HidlFaceSensorConfig;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
 import com.android.server.biometrics.BiometricHandlerProvider;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
 import com.android.server.biometrics.sensors.AuthenticationStateListeners;
@@ -134,13 +130,8 @@
         when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
                 mBiometricCallbackHandler);
         when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
-        if (Flags.deHidl()) {
-            when(mBiometricHandlerProvider.getFaceHandler()).thenReturn(new Handler(
-                    mLooper.getLooper()));
-        } else {
-            when(mBiometricHandlerProvider.getFaceHandler()).thenReturn(new Handler(
-                    Looper.getMainLooper()));
-        }
+        when(mBiometricHandlerProvider.getFaceHandler()).thenReturn(new Handler(
+                mLooper.getLooper()));
 
         final SensorProps sensor1 = new SensorProps();
         sensor1.commonProps = new CommonProps();
@@ -176,7 +167,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testAddingHidlSensors() {
         when(mResources.getIntArray(anyInt())).thenReturn(new int[]{});
         when(mResources.getBoolean(anyInt())).thenReturn(false);
@@ -247,7 +237,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testAuthenticateCallbackHandler() {
         waitForIdle();
 
@@ -295,10 +284,6 @@
     }
 
     private void waitForIdle() {
-        if (Flags.deHidl()) {
-            mLooper.dispatchAll();
-        } else {
-            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        }
+        mLooper.dispatchAll();
     }
 }
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 fe9cd43..6780e60 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
@@ -41,7 +41,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
@@ -50,7 +49,6 @@
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.UserSwitchProvider;
 
 import org.junit.Before;
@@ -75,12 +73,8 @@
     @Mock
     private ISession mSession;
     @Mock
-    private UserAwareBiometricScheduler.UserSwitchCallback mUserSwitchCallback;
-    @Mock
     private UserSwitchProvider<IFace, ISession> mUserSwitchProvider;
     @Mock
-    private AidlResponseHandler.HardwareUnavailableCallback mHardwareUnavailableCallback;
-    @Mock
     private LockoutResetDispatcher mLockoutResetDispatcher;
     @Mock
     private BiometricLogger mBiometricLogger;
@@ -94,6 +88,8 @@
     private BaseClientMonitor mClientMonitor;
     @Mock
     private AidlSession mCurrentSession;
+    @Mock
+    private AidlResponseHandler.AidlResponseHandlerCallback mAidlResponseHandlerCallback;
 
     private final TestLooper mLooper = new TestLooper();
     private final LockoutCache mLockoutCache = new LockoutCache();
@@ -108,27 +104,17 @@
         when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(mBiometricService);
         when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
 
-        if (Flags.deHidl()) {
-            mScheduler = new BiometricScheduler<>(
-                    new Handler(mLooper.getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_FACE,
-                    null /* gestureAvailabilityDispatcher */,
-                    mBiometricService,
-                    2 /* recentOperationsLimit */,
-                    () -> USER_ID,
-                    mUserSwitchProvider);
-        } else {
-            mScheduler = new UserAwareBiometricScheduler<>(TAG,
-                    new Handler(mLooper.getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_FACE,
-                    null /* gestureAvailabilityDispatcher */,
-                    mBiometricService,
-                    () -> USER_ID,
-                    mUserSwitchCallback);
-        }
+        mScheduler = new BiometricScheduler<>(
+                new Handler(mLooper.getLooper()),
+                BiometricScheduler.SENSOR_TYPE_FACE,
+                null /* gestureAvailabilityDispatcher */,
+                mBiometricService,
+                2 /* recentOperationsLimit */,
+                () -> USER_ID,
+                mUserSwitchProvider);
         mHalCallback = new AidlResponseHandler(mContext, mScheduler, SENSOR_ID, USER_ID,
                 mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
-                mHardwareUnavailableCallback);
+                mAidlResponseHandlerCallback);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java
deleted file mode 100644
index 949d6ee..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.face.hidl;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.biometrics.ComponentInfoInternal;
-import android.hardware.biometrics.SensorProperties;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.face.IFaceServiceReceiver;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.UserManager;
-import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.R;
-import com.android.server.biometrics.Flags;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.time.Clock;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.IntStream;
-
-@Presubmit
-@SmallTest
-public class Face10Test {
-
-    private static final String TAG = "Face10Test";
-    private static final int SENSOR_ID = 1;
-    private static final int USER_ID = 20;
-    private static final float FRR_THRESHOLD = 0.2f;
-
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule =
-            DeviceFlagsValueProvider.createCheckFlagsRule();
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private BiometricScheduler mScheduler;
-    @Mock
-    private BiometricContext mBiometricContext;
-    @Mock
-    private BiometricStateCallback mBiometricStateCallback;
-    @Mock
-    private AuthenticationStateListeners mAuthenticationStateListeners;
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private LockoutResetDispatcher mLockoutResetDispatcher;
-    private com.android.server.biometrics.sensors.face.hidl.Face10 mFace10;
-    private IBinder mBinder;
-
-    private static void waitForIdle() {
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mUserManager.getAliveUsers()).thenReturn(new ArrayList<>());
-
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getFraction(R.fraction.config_biometricNotificationFrrThreshold, 1, 1))
-                .thenReturn(FRR_THRESHOLD);
-
-        mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
-
-        final int maxEnrollmentsPerUser = 1;
-        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-        final boolean supportsFaceDetection = false;
-        final boolean supportsSelfIllumination = false;
-        final boolean resetLockoutRequiresChallenge = false;
-        final FaceSensorPropertiesInternal sensorProps = new FaceSensorPropertiesInternal(SENSOR_ID,
-                SensorProperties.STRENGTH_STRONG, maxEnrollmentsPerUser, componentInfo,
-                FaceSensorProperties.TYPE_UNKNOWN, supportsFaceDetection, supportsSelfIllumination,
-                resetLockoutRequiresChallenge);
-
-        Face10.sSystemClock = Clock.fixed(
-                Instant.ofEpochMilli(100), ZoneId.of("America/Los_Angeles"));
-        mFace10 = new Face10(mContext, mBiometricStateCallback, mAuthenticationStateListeners,
-                sensorProps, mLockoutResetDispatcher, mHandler, mScheduler, mBiometricContext);
-        mBinder = new Binder();
-    }
-
-    private void tick(long seconds) {
-        waitForIdle();
-        Face10.sSystemClock = Clock.fixed(Instant.ofEpochSecond(
-                Face10.sSystemClock.instant().getEpochSecond() + seconds),
-                ZoneId.of("America/Los_Angeles"));
-    }
-
-    @Test
-    public void getAuthenticatorId_doesNotCrashWhenIdNotFound() {
-        assertEquals(0, mFace10.getAuthenticatorId(0 /* sensorId */, 111 /* userId */));
-        waitForIdle();
-    }
-
-    @Test
-    public void scheduleRevokeChallenge_doesNotCrash() {
-        mFace10.scheduleRevokeChallenge(0 /* sensorId */, 0 /* userId */, mBinder, TAG,
-                0 /* challenge */);
-        waitForIdle();
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void scheduleGenerateChallenge_cachesResult() {
-        final IFaceServiceReceiver[] mocks = IntStream.range(0, 3)
-                .mapToObj(i -> mock(IFaceServiceReceiver.class))
-                .toArray(IFaceServiceReceiver[]::new);
-        for (IFaceServiceReceiver mock : mocks) {
-            mFace10.scheduleGenerateChallenge(SENSOR_ID, USER_ID, mBinder, mock, TAG);
-            tick(10);
-        }
-        tick(120);
-        mFace10.scheduleGenerateChallenge(
-                SENSOR_ID, USER_ID, mBinder, mock(IFaceServiceReceiver.class), TAG);
-        waitForIdle();
-
-        verify(mScheduler, times(2))
-                .scheduleClientMonitor(isA(FaceGenerateChallengeClient.class), any());
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void scheduleRevokeChallenge_waitsUntilEmpty() {
-        final long challenge = 22;
-        final IFaceServiceReceiver[] mocks = IntStream.range(0, 3)
-                .mapToObj(i -> mock(IFaceServiceReceiver.class))
-                .toArray(IFaceServiceReceiver[]::new);
-        for (IFaceServiceReceiver mock : mocks) {
-            mFace10.scheduleGenerateChallenge(SENSOR_ID, USER_ID, mBinder, mock, TAG);
-            tick(10);
-        }
-        for (IFaceServiceReceiver mock : mocks) {
-            mFace10.scheduleRevokeChallenge(SENSOR_ID, USER_ID, mBinder, TAG, challenge);
-            tick(10);
-        }
-        waitForIdle();
-
-        verify(mScheduler).scheduleClientMonitor(isA(FaceRevokeChallengeClient.class), any());
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void scheduleRevokeChallenge_doesNotWaitForever() {
-        mFace10.scheduleGenerateChallenge(
-                SENSOR_ID, USER_ID, mBinder, mock(IFaceServiceReceiver.class), TAG);
-        mFace10.scheduleGenerateChallenge(
-                SENSOR_ID, USER_ID, mBinder, mock(IFaceServiceReceiver.class), TAG);
-        tick(10000);
-        mFace10.scheduleGenerateChallenge(
-                SENSOR_ID, USER_ID, mBinder, mock(IFaceServiceReceiver.class), TAG);
-        mFace10.scheduleRevokeChallenge(
-                SENSOR_ID, USER_ID, mBinder, TAG, 8 /* challenge */);
-        waitForIdle();
-
-        verify(mScheduler).scheduleClientMonitor(isA(FaceRevokeChallengeClient.class), any());
-    }
-
-    @Test
-    public void halServiceDied_resetsScheduler() {
-        // It's difficult to test the linkToDeath --> serviceDied path, so let's just invoke
-        // serviceDied directly.
-        mFace10.serviceDied(0 /* cookie */);
-        waitForIdle();
-        verify(mScheduler).reset();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClientTest.java
deleted file mode 100644
index ec08329..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClientTest.java
+++ /dev/null
@@ -1,111 +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.face.hidl;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.OptionalUint64;
-import android.hardware.face.IFaceServiceReceiver;
-import android.os.Binder;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@Presubmit
-@SmallTest
-public class FaceGenerateChallengeClientTest {
-
-    private static final String TAG = "FaceGenerateChallengeClientTest";
-    private static final int USER_ID = 2;
-    private static final int SENSOR_ID = 4;
-    private static final long START_TIME = 5000;
-    private static final long CHALLENGE = 200;
-
-    private final Context mContext = ApplicationProvider.getApplicationContext();
-
-    @Mock
-    private IBiometricsFace mIBiometricsFace;
-    @Mock
-    private IFaceServiceReceiver mClientReceiver;
-    @Mock
-    private IFaceServiceReceiver mOtherReceiver;
-    @Mock
-    private ClientMonitorCallback mMonitorCallback;
-    @Mock
-    private BiometricLogger mBiometricLogger;
-    @Mock
-    private BiometricContext mBiometricContext;
-
-    private FaceGenerateChallengeClient mClient;
-
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        final OptionalUint64 challenge = new OptionalUint64();
-        challenge.value = CHALLENGE;
-        when(mIBiometricsFace.generateChallenge(anyInt())).thenReturn(challenge);
-
-        mClient = new FaceGenerateChallengeClient(mContext, () -> mIBiometricsFace, new Binder(),
-                new ClientMonitorCallbackConverter(mClientReceiver), USER_ID,
-                TAG, SENSOR_ID, mBiometricLogger, mBiometricContext , START_TIME);
-    }
-
-    @Test
-    public void getCreatedAt() {
-        assertEquals(START_TIME, mClient.getCreatedAt());
-    }
-
-    @Test
-    public void reuseResult_whenNotReady() throws Exception {
-        mClient.reuseResult(mOtherReceiver);
-        verify(mOtherReceiver, never()).onChallengeGenerated(anyInt(), anyInt(), anyInt());
-    }
-
-    @Test
-    public void reuseResult_whenReady() throws Exception {
-        mClient.start(mMonitorCallback);
-        mClient.reuseResult(mOtherReceiver);
-        verify(mOtherReceiver).onChallengeGenerated(eq(SENSOR_ID), eq(USER_ID), eq(CHALLENGE));
-    }
-
-    @Test
-    public void reuseResult_whenReallyReady() throws Exception {
-        mClient.reuseResult(mOtherReceiver);
-        mClient.start(mMonitorCallback);
-        verify(mOtherReceiver).onChallengeGenerated(eq(SENSOR_ID), eq(USER_ID), eq(CHALLENGE));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java
index b5d73d2..44da431 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java
@@ -16,8 +16,8 @@
 
 package com.android.server.biometrics.sensors.face.hidl;
 
-import static com.android.server.biometrics.sensors.face.hidl.FaceGenerateChallengeClient.CHALLENGE_TIMEOUT_SEC;
 import static com.android.server.biometrics.sensors.face.hidl.HidlToAidlSessionAdapter.ENROLL_TIMEOUT_SEC;
+import static com.android.server.biometrics.sensors.face.hidl.HidlToAidlSessionAdapter.CHALLENGE_TIMEOUT_SEC;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index 9a8cd48..6126af5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -51,7 +51,6 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.provider.Settings;
@@ -64,7 +63,6 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
 import com.android.server.LocalServices;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
@@ -90,8 +88,6 @@
     private static final int ID_VIRTUAL = 6;
     private static final String NAME_DEFAULT = "default";
     private static final String NAME_VIRTUAL = "virtual";
-    private static final List<FingerprintSensorPropertiesInternal> HIDL_AUTHENTICATORS =
-            List.of();
     private static final String OP_PACKAGE_NAME = "FingerprintServiceTest/SystemUi";
 
     @Rule
@@ -185,7 +181,7 @@
 
     private void initServiceWithAndWait(String... aidlInstances) throws Exception {
         initServiceWith(aidlInstances);
-        mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
+        mService.mServiceWrapper.registerAuthenticators(mFingerprintSensorConfigurations);
         waitForRegistration();
     }
 
@@ -193,18 +189,7 @@
     public void registerAuthenticators_defaultOnly() throws Exception {
         initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
 
-        mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
-        waitForRegistration();
-
-        verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
-    public void registerAuthenticatorsLegacy_defaultOnly() throws Exception {
-        initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
-
-        mService.mServiceWrapper.registerAuthenticatorsLegacy(mFingerprintSensorConfigurations);
+        mService.mServiceWrapper.registerAuthenticators(mFingerprintSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
@@ -216,7 +201,7 @@
         Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
                 Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
 
-        mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
+        mService.mServiceWrapper.registerAuthenticators(mFingerprintSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -228,20 +213,7 @@
         Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
                 Settings.Secure.BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED, 1);
 
-        mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
-        waitForRegistration();
-
-        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
-    public void registerAuthenticatorsLegacy_virtualOnly() throws Exception {
-        initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
-        Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
-                Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
-
-        mService.mServiceWrapper.registerAuthenticatorsLegacy(mFingerprintSensorConfigurations);
+        mService.mServiceWrapper.registerAuthenticators(mFingerprintSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -249,23 +221,12 @@
 
     @Test
     public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
-        initServiceWith(NAME_VIRTUAL);
-
-        mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
-        waitForRegistration();
-
-        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
-    public void registerAuthenticatorsLegacy_virtualAlwaysWhenNoOther() throws Exception {
         mFingerprintSensorConfigurations =
                 new FingerprintSensorConfigurations(true);
         mFingerprintSensorConfigurations.addAidlSensors(new String[]{NAME_VIRTUAL});
         initServiceWith(NAME_VIRTUAL);
 
-        mService.mServiceWrapper.registerAuthenticatorsLegacy(mFingerprintSensorConfigurations);
+        mService.mServiceWrapper.registerAuthenticators(mFingerprintSensorConfigurations);
         waitForRegistration();
 
         verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
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 7a77392..db9fe7f 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
@@ -30,7 +30,6 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyLong;
 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;
@@ -42,7 +41,6 @@
 import android.app.ActivityTaskManager;
 import android.content.ComponentName;
 import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.common.AuthenticateReason;
 import android.hardware.biometrics.common.ICancellationSignal;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.fingerprint.ISession;
@@ -52,13 +50,10 @@
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -67,7 +62,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.CallbackWithProbe;
@@ -84,7 +78,6 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -180,36 +173,18 @@
     public void authNoContext_v1() throws RemoteException {
         final FingerprintAuthenticationClient client = createClient(1);
         client.start(mCallback);
-        if (Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
-                    mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
-            mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
-                    .getValue().toAidlContext());
-        }
+
+        verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
+                mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
+
+        mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
+                .getValue().toAidlContext());
 
         verify(mHal).authenticate(eq(OP_ID));
         verify(mHal, never()).authenticateWithContext(anyLong(), any());
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void authWithContext_v2() throws RemoteException {
-        final FingerprintAuthenticationClient client = createClient(2);
-        client.start(mCallback);
-
-        InOrder order = inOrder(mHal, mBiometricContext);
-        order.verify(mBiometricContext).updateContext(
-                mOperationContextCaptor.capture(), anyBoolean());
-
-        final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext();
-        order.verify(mHal).authenticateWithContext(eq(OP_ID), same(aidlContext));
-        assertThat(aidlContext.authenticateReason.getFingerprintAuthenticateReason())
-                .isEqualTo(AuthenticateReason.Fingerprint.UNKNOWN);
-
-        verify(mHal, never()).authenticate(anyLong());
-    }
-
-    @Test
     public void pointerUp_v1() throws RemoteException {
         final FingerprintAuthenticationClient client = createClient(1);
         client.start(mCallback);
@@ -277,21 +252,18 @@
 
         final FingerprintAuthenticationClient client = createClient();
         client.start(mCallback);
-        if (Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
-                    mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
-            mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
-                    .getValue().toAidlContext());
-        }
+
+        verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
+                mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
+
+        mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
+                .getValue().toAidlContext());
 
         final ArgumentCaptor<OperationContext> captor =
                 ArgumentCaptor.forClass(OperationContext.class);
         verify(mHal).authenticateWithContext(eq(OP_ID), captor.capture());
         OperationContext opContext = captor.getValue();
-        if (!Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(
-                    mOperationContextCaptor.capture(), mContextInjector.capture());
-        }
+
         assertThat(mOperationContextCaptor.getValue().toAidlContext())
                 .isSameInstanceAs(opContext);
 
@@ -326,12 +298,12 @@
         when(mBiometricContext.isAod()).thenReturn(false);
         final FingerprintAuthenticationClient client = createClient();
         client.start(mCallback);
-        if (Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
-                    mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
-            mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
-                    .getValue().toAidlContext());
-        }
+
+        verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
+                mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
+
+        mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
+                .getValue().toAidlContext());
 
         verify(mLuxProbe, isAwake ? times(1) : never()).enable();
     }
@@ -342,21 +314,18 @@
         when(mBiometricContext.isAod()).thenReturn(true);
         final FingerprintAuthenticationClient client = createClient();
         client.start(mCallback);
-        if (Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
-                    mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
-            mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
-                    .getValue().toAidlContext());
-        }
+
+        verify(mBiometricContext).subscribe(mOperationContextCaptor.capture(),
+                mStartHalConsumerCaptor.capture(), mContextInjector.capture(), any());
+
+        mStartHalConsumerCaptor.getValue().accept(mOperationContextCaptor
+                .getValue().toAidlContext());
 
         final ArgumentCaptor<OperationContext> captor =
                 ArgumentCaptor.forClass(OperationContext.class);
         verify(mHal).authenticateWithContext(eq(OP_ID), captor.capture());
         OperationContext opContext = captor.getValue();
-        if (!Flags.deHidl()) {
-            verify(mBiometricContext).subscribe(
-                    mOperationContextCaptor.capture(), mContextInjector.capture());
-        }
+
         assertThat(opContext).isSameInstanceAs(
                 mOperationContextCaptor.getValue().toAidlContext());
 
@@ -380,30 +349,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FingerprintAuthenticationClient client = createClient();
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).authenticateWithContext(eq(OP_ID), captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        assertThat(opContext).isSameInstanceAs(
-                mOperationContextCaptor.getValue().toAidlContext());
-        mContextInjector.getValue().accept(opContext);
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FingerprintAuthenticationClient client = createClient();
         client.start(mCallback);
@@ -603,7 +548,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testLockoutTracker_authFailed() throws RemoteException {
         final FingerprintAuthenticationClient client = createClient(1 /* version */,
                 true /* allowBackgroundAuthentication */, mClientMonitorCallbackConverter,
@@ -658,8 +602,7 @@
                 null /* taskStackListener */,
                 mUdfpsOverlayController, mSideFpsController, mAuthenticationStateListeners,
                 allowBackgroundAuthentication,
-                mSensorProps,
-                new Handler(mLooper.getLooper()), 0 /* biometricStrength */, mClock,
+                mSensorProps, 0 /* biometricStrength */,
                 lockoutTracker) {
             @Override
             protected ActivityTaskManager getActivityTaskManager() {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
index 9edb8dd..6b8c3cd 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
@@ -21,13 +21,11 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.hardware.biometrics.common.AuthenticateReason;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.fingerprint.FingerprintAuthenticateOptions;
@@ -35,8 +33,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.TestableContext;
@@ -44,7 +40,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
@@ -56,7 +51,6 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -119,49 +113,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void detectNoContext_v2() throws RemoteException {
-        final FingerprintDetectClient client = createClient(2);
-
-        client.start(mCallback);
-
-        InOrder order = inOrder(mHal, mBiometricContext);
-        order.verify(mBiometricContext).updateContext(
-                mOperationContextCaptor.capture(), anyBoolean());
-
-        final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext();
-        order.verify(mHal).detectInteractionWithContext(same(aidlContext));
-        assertThat(aidlContext.authenticateReason.getFingerprintAuthenticateReason())
-                .isEqualTo(AuthenticateReason.Fingerprint.UNKNOWN);
-
-        verify(mHal, never()).detectInteraction();
-    }
-
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FingerprintDetectClient client = createClient();
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).detectInteractionWithContext(captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        assertThat(opContext).isSameInstanceAs(
-                mOperationContextCaptor.getValue().toAidlContext());
-        mContextInjector.getValue().accept(opContext);
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FingerprintDetectClient client = createClient();
         client.start(mCallback);
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 916f696..d2e1c3c 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
@@ -24,7 +24,6 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.times;
@@ -44,8 +43,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -54,7 +51,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.CallbackWithProbe;
@@ -70,7 +66,6 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -156,21 +151,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void enrollWithContext_v2() throws RemoteException {
-        final FingerprintEnrollClient client = createClient(2);
-
-        client.start(mCallback);
-
-        InOrder order = inOrder(mHal, mBiometricContext);
-        order.verify(mBiometricContext).updateContext(
-                mOperationContextCaptor.capture(), anyBoolean());
-        order.verify(mHal).enrollWithContext(any(),
-                same(mOperationContextCaptor.getValue().toAidlContext()));
-        verify(mHal, never()).enroll(any());
-    }
-
-    @Test
     public void pointerUp_v1() throws RemoteException {
         final FingerprintEnrollClient client = createClient(1);
         client.start(mCallback);
@@ -253,29 +233,6 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_DE_HIDL)
-    public void notifyHalWhenContextChanges() throws RemoteException {
-        final FingerprintEnrollClient client = createClient();
-        client.start(mCallback);
-
-        final ArgumentCaptor<OperationContext> captor =
-                ArgumentCaptor.forClass(OperationContext.class);
-        verify(mHal).enrollWithContext(any(), captor.capture());
-        OperationContext opContext = captor.getValue();
-
-        // fake an update to the context
-        verify(mBiometricContext).subscribe(
-                mOperationContextCaptor.capture(), mContextInjector.capture());
-        mContextInjector.getValue().accept(
-                mOperationContextCaptor.getValue().toAidlContext());
-        verify(mHal).onContextChanged(same(opContext));
-
-        client.stopHalOperation();
-        verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void subscribeContextAndStartHal() throws RemoteException {
         final FingerprintEnrollClient client = createClient();
         client.start(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
index 0a35037..1f288b2 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
@@ -47,21 +47,17 @@
 import android.hardware.fingerprint.HidlFingerprintSensorConfig;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.biometrics.BiometricHandlerProvider;
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
 import com.android.server.biometrics.sensors.AuthenticationStateListeners;
@@ -136,13 +132,8 @@
         when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
         when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
                 mBiometricCallbackHandler);
-        if (Flags.deHidl()) {
-            when(mBiometricHandlerProvider.getFingerprintHandler()).thenReturn(
-                    new Handler(mLooper.getLooper()));
-        } else {
-            when(mBiometricHandlerProvider.getFingerprintHandler()).thenReturn(
-                    new Handler(Looper.getMainLooper()));
-        }
+        when(mBiometricHandlerProvider.getFingerprintHandler()).thenReturn(
+                new Handler(mLooper.getLooper()));
 
         final SensorProps sensor1 = new SensorProps();
         sensor1.commonProps = new CommonProps();
@@ -176,7 +167,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testAddingHidlSensors() {
         when(mResources.getIntArray(anyInt())).thenReturn(new int[]{});
         when(mResources.getBoolean(anyInt())).thenReturn(false);
@@ -252,7 +242,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void testScheduleAuthenticate() {
         waitForIdle();
 
@@ -302,10 +291,6 @@
     }
 
     private void waitForIdle() {
-        if (Flags.deHidl()) {
-            mLooper.dispatchAll();
-        } else {
-            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        }
+        mLooper.dispatchAll();
     }
 }
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 b4c2ee8..698db2e 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
@@ -42,7 +42,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.server.biometrics.Flags;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
@@ -51,7 +50,6 @@
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
 import com.android.server.biometrics.sensors.UserSwitchProvider;
 import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
 
@@ -77,12 +75,8 @@
     @Mock
     private ISession mSession;
     @Mock
-    private UserAwareBiometricScheduler.UserSwitchCallback mUserSwitchCallback;
-    @Mock
     private UserSwitchProvider<IFingerprint, ISession> mUserSwitchProvider;
     @Mock
-    private AidlResponseHandler.HardwareUnavailableCallback mHardwareUnavailableCallback;
-    @Mock
     private LockoutResetDispatcher mLockoutResetDispatcher;
     @Mock
     private BiometricLogger mLogger;
@@ -100,6 +94,8 @@
     private BaseClientMonitor mClientMonitor;
     @Mock
     private HandlerThread mThread;
+    @Mock
+    AidlResponseHandler.AidlResponseHandlerCallback mAidlResponseHandlerCallback;
 
     private final TestLooper mLooper = new TestLooper();
     private final LockoutCache mLockoutCache = new LockoutCache();
@@ -115,27 +111,17 @@
         when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
         when(mThread.getLooper()).thenReturn(mLooper.getLooper());
 
-        if (Flags.deHidl()) {
-            mScheduler = new BiometricScheduler<>(
-                    new Handler(mLooper.getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_FP_OTHER,
-                    null /* gestureAvailabilityDispatcher */,
-                    mBiometricService,
-                    2 /* recentOperationsLimit */,
-                    () -> USER_ID,
-                    mUserSwitchProvider);
-        } else {
-            mScheduler = new UserAwareBiometricScheduler<>(TAG,
-                    new Handler(mLooper.getLooper()),
-                    BiometricScheduler.SENSOR_TYPE_FP_OTHER,
-                    null /* gestureAvailabilityDispatcher */,
-                    mBiometricService,
-                    () -> USER_ID,
-                    mUserSwitchCallback);
-        }
+        mScheduler = new BiometricScheduler<>(
+                new Handler(mLooper.getLooper()),
+                BiometricScheduler.SENSOR_TYPE_FP_OTHER,
+                null /* gestureAvailabilityDispatcher */,
+                mBiometricService,
+                2 /* recentOperationsLimit */,
+                () -> USER_ID,
+                mUserSwitchProvider);
         mHalCallback = new AidlResponseHandler(mContext, mScheduler, SENSOR_ID, USER_ID,
                 mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
-                mHardwareUnavailableCallback);
+                mAidlResponseHandlerCallback);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java
deleted file mode 100644
index 0d3f192..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint.hidl;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.biometrics.ComponentInfoInternal;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserManager;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.annotation.NonNull;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.R;
-import com.android.server.biometrics.log.BiometricContext;
-import com.android.server.biometrics.sensors.AuthenticationStateListeners;
-import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.BiometricStateCallback;
-import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Presubmit
-@SmallTest
-public class Fingerprint21Test {
-
-    private static final String TAG = "Fingerprint21Test";
-    private static final int SENSOR_ID = 1;
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    Fingerprint21.HalResultController mHalResultController;
-    @Mock
-    private BiometricScheduler mScheduler;
-    @Mock
-    private AuthenticationStateListeners mAuthenticationStateListeners;
-    @Mock
-    private BiometricStateCallback mBiometricStateCallback;
-    @Mock
-    private BiometricContext mBiometricContext;
-
-    private LockoutResetDispatcher mLockoutResetDispatcher;
-    private Fingerprint21 mFingerprint21;
-
-    private static void waitForIdle() {
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mUserManager.getAliveUsers()).thenReturn(new ArrayList<>());
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getInteger(eq(R.integer.config_fingerprintMaxTemplatesPerUser)))
-                .thenReturn(5);
-
-        mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
-
-        final int maxEnrollmentsPerUser = 1;
-        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-        final boolean resetLockoutRequiresHardwareAuthToken = false;
-        final FingerprintSensorPropertiesInternal sensorProps =
-                new FingerprintSensorPropertiesInternal(SENSOR_ID,
-                        FingerprintSensorProperties.STRENGTH_WEAK, maxEnrollmentsPerUser,
-                        componentInfo, FingerprintSensorProperties.TYPE_UNKNOWN,
-                        resetLockoutRequiresHardwareAuthToken);
-
-        mFingerprint21 = new TestableFingerprint21(mContext, mBiometricStateCallback,
-                mAuthenticationStateListeners, sensorProps, mScheduler,
-                new Handler(Looper.getMainLooper()), mLockoutResetDispatcher, mHalResultController,
-                mBiometricContext);
-    }
-
-    @Test
-    public void getAuthenticatorId_doesNotCrashWhenIdNotFound() {
-        assertEquals(0, mFingerprint21.getAuthenticatorId(0 /* sensorId */, 111 /* userId */));
-        waitForIdle();
-    }
-
-    @Test
-    public void halServiceDied_resetsScheduler() {
-        // It's difficult to test the linkToDeath --> serviceDied path, so let's just invoke
-        // serviceDied directly.
-        mFingerprint21.serviceDied(0 /* cookie */);
-        waitForIdle();
-        verify(mScheduler).reset();
-    }
-
-    private static class TestableFingerprint21 extends Fingerprint21 {
-
-        TestableFingerprint21(@NonNull Context context,
-                @NonNull BiometricStateCallback biometricStateCallback,
-                @NonNull AuthenticationStateListeners authenticationStateListeners,
-                @NonNull FingerprintSensorPropertiesInternal sensorProps,
-                @NonNull BiometricScheduler scheduler, @NonNull Handler handler,
-                @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-                @NonNull HalResultController controller,
-                @NonNull BiometricContext biometricContext) {
-            super(context, biometricStateCallback, authenticationStateListeners, sensorProps,
-                    scheduler, handler, lockoutResetDispatcher, controller, biometricContext);
-        }
-
-        @Override
-        synchronized IBiometricsFingerprint getDaemon() {
-            return mock(IBiometricsFingerprint.class);
-        }
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 649f520..dcf3dadc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -74,6 +74,7 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
@@ -237,6 +238,24 @@
         assertFalse(wpc.hasActivities());
     }
 
+    @Test
+    public void testAttachApplication() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        activity.detachFromProcess();
+        mAtm.startProcessAsync(activity, false /* knownToBeDead */,
+                true /* isTop */, "test" /* hostingType */);
+        final WindowProcessController proc = mSystemServicesTestRule.addProcess(
+                activity.packageName, activity.processName,
+                6789 /* pid */, activity.info.applicationInfo.uid);
+        try {
+            mRootWindowContainer.attachApplication(proc);
+            verify(mSupervisor).realStartActivityLocked(eq(activity), eq(proc), anyBoolean(),
+                    anyBoolean());
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
     /**
      * This test ensures that we do not try to restore a task based off an invalid task id. We
      * should expect {@code null} to be returned in this case.