Merge "Add pixel_connectivity_gps to native list." into main
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index d659ddd..4e88b0e 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -607,7 +607,8 @@
     }
 
     @Override
-    public final void drawMesh(@NonNull Mesh mesh, BlendMode blendMode, @NonNull Paint paint) {
+    public final void drawMesh(@NonNull Mesh mesh, @Nullable BlendMode blendMode,
+            @NonNull Paint paint) {
         if (blendMode == null) {
             blendMode = BlendMode.MODULATE;
         }
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index bba9c97..f84107e 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -111,7 +111,11 @@
       : PointerController(
                 policy, looper, spriteController, enabled,
                 [](const sp<android::gui::WindowInfosListener>& listener) {
-                    SurfaceComposerClient::getDefault()->addWindowInfosListener(listener);
+                    auto initialInfo = std::make_pair(std::vector<android::gui::WindowInfo>{},
+                                                      std::vector<android::gui::DisplayInfo>{});
+                    SurfaceComposerClient::getDefault()->addWindowInfosListener(listener,
+                                                                                &initialInfo);
+                    return initialInfo.second;
                 },
                 [](const sp<android::gui::WindowInfosListener>& listener) {
                     SurfaceComposerClient::getDefault()->removeWindowInfosListener(listener);
@@ -119,8 +123,9 @@
 
 PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
                                      const sp<Looper>& looper, SpriteController& spriteController,
-                                     bool enabled, WindowListenerConsumer registerListener,
-                                     WindowListenerConsumer unregisterListener)
+                                     bool enabled,
+                                     const WindowListenerRegisterConsumer& registerListener,
+                                     WindowListenerUnregisterConsumer unregisterListener)
       : mEnabled(enabled),
         mContext(policy, looper, spriteController, *this),
         mCursorController(mContext),
@@ -128,7 +133,8 @@
         mUnregisterWindowInfosListener(std::move(unregisterListener)) {
     std::scoped_lock lock(getLock());
     mLocked.presentation = Presentation::SPOT;
-    registerListener(mDisplayInfoListener);
+    const auto& initialDisplayInfos = registerListener(mDisplayInfoListener);
+    onDisplayInfosChangedLocked(initialDisplayInfos);
 }
 
 PointerController::~PointerController() {
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index a8b9633..6ee5707 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -79,14 +79,16 @@
     std::string dump() override;
 
 protected:
-    using WindowListenerConsumer =
+    using WindowListenerRegisterConsumer = std::function<std::vector<gui::DisplayInfo>(
+            const sp<android::gui::WindowInfosListener>&)>;
+    using WindowListenerUnregisterConsumer =
             std::function<void(const sp<android::gui::WindowInfosListener>&)>;
 
     // Constructor used to test WindowInfosListener registration.
     PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
                       SpriteController& spriteController, bool enabled,
-                      WindowListenerConsumer registerListener,
-                      WindowListenerConsumer unregisterListener);
+                      const WindowListenerRegisterConsumer& registerListener,
+                      WindowListenerUnregisterConsumer unregisterListener);
 
     PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
                       SpriteController& spriteController, bool enabled);
@@ -129,7 +131,7 @@
     };
 
     sp<DisplayInfoListener> mDisplayInfoListener;
-    const WindowListenerConsumer mUnregisterWindowInfosListener;
+    const WindowListenerUnregisterConsumer mUnregisterWindowInfosListener;
 
     const ui::Transform& getTransformForDisplayLocked(int displayId) const REQUIRES(getLock());
 
diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp
index b8de919..99952aa 100644
--- a/libs/input/TouchSpotController.cpp
+++ b/libs/input/TouchSpotController.cpp
@@ -93,7 +93,7 @@
         const PointerCoords& c = spotCoords[spotIdToIndex[id]];
         ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f, displayId=%" PRId32 ".", id,
               c.getAxisValue(AMOTION_EVENT_AXIS_X), c.getAxisValue(AMOTION_EVENT_AXIS_Y),
-              c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), displayId);
+              c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), mDisplayId);
     }
 #endif
 
diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp
index adfa91e..a1bb5b3 100644
--- a/libs/input/tests/PointerController_test.cpp
+++ b/libs/input/tests/PointerController_test.cpp
@@ -160,9 +160,11 @@
           : PointerController(
                     policy, looper, spriteController,
                     /*enabled=*/true,
-                    [&registeredListener](const sp<android::gui::WindowInfosListener>& listener) {
+                    [&registeredListener](const sp<android::gui::WindowInfosListener>& listener)
+                            -> std::vector<gui::DisplayInfo> {
                         // Register listener
                         registeredListener = listener;
+                        return {};
                     },
                     [&registeredListener](const sp<android::gui::WindowInfosListener>& listener) {
                         // Unregister listener
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bc221b8..09b02f8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1732,6 +1732,8 @@
     <dimen name="communal_right_edge_swipe_region_width">16dp</dimen>
     <!-- Height of area at top of communal hub where swipes should open the notification shade -->
     <dimen name="communal_top_edge_swipe_region_height">32dp</dimen>
+    <!-- Height of area at bottom of communal hub where swipes should open the bouncer -->
+    <dimen name="communal_bottom_edge_swipe_region_height">32dp</dimen>
 
     <dimen name="drag_and_drop_icon_size">70dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fe96099..3e8c6a7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1644,11 +1644,11 @@
     void setAssistantVisible(boolean assistantVisible) {
         mAssistantVisible = assistantVisible;
         mLogger.logAssistantVisible(mAssistantVisible);
-        if (getFaceAuthInteractor() != null) {
-            getFaceAuthInteractor().onAssistantTriggeredOnLockScreen();
-        }
         updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
         if (mAssistantVisible) {
+            if (getFaceAuthInteractor() != null) {
+                getFaceAuthInteractor().onAssistantTriggeredOnLockScreen();
+            }
             requestActiveUnlock(
                     ActiveUnlockConfig.ActiveUnlockRequestOrigin.ASSISTANT,
                     "assistant",
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 5cebd96..50caf17 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2507,8 +2507,18 @@
             String message = "";
             switch (msg.what) {
                 case SHOW:
-                    message = "SHOW";
-                    handleShow((Bundle) msg.obj);
+                    // There is a potential race condition when SysUI starts up. CentralSurfaces
+                    // must invoke #registerCentralSurfaces on this class before any messages can be
+                    // processed. If this happens, repost the message with a small delay and try
+                    // again.
+                    if (mCentralSurfaces == null) {
+                        message = "DELAYING SHOW";
+                        Message newMsg = mHandler.obtainMessage(SHOW, (Bundle) msg.obj);
+                        mHandler.sendMessageDelayed(newMsg, 100);
+                    } else {
+                        message = "SHOW";
+                        handleShow((Bundle) msg.obj);
+                    }
                     break;
                 case HIDE:
                     message = "HIDE";
@@ -2595,8 +2605,18 @@
                     Trace.endSection();
                     break;
                 case SYSTEM_READY:
-                    message = "SYSTEM_READY";
-                    handleSystemReady();
+                    // There is a potential race condition when SysUI starts up. CentralSurfaces
+                    // must invoke #registerCentralSurfaces on this class before any messages can be
+                    // processed. If this happens, repost the message with a small delay and try
+                    // again.
+                    if (mCentralSurfaces == null) {
+                        message = "DELAYING SYSTEM_READY";
+                        Message newMsg = mHandler.obtainMessage(SYSTEM_READY);
+                        mHandler.sendMessageDelayed(newMsg, 100);
+                    } else {
+                        message = "SYSTEM_READY";
+                        handleSystemReady();
+                    }
                     break;
             }
             Log.d(TAG, "KeyguardViewMediator queue processing message: " + message);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 7b1466c..a97c152 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -17,14 +17,14 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.animation.ValueAnimator
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.toQuad
-import com.android.systemui.util.kotlin.Utils.Companion.toQuint
+import com.android.systemui.util.kotlin.Utils.Companion.sample
 import com.android.systemui.util.kotlin.sample
 import com.android.wm.shell.animation.Interpolators
 import javax.inject.Inject
@@ -32,7 +32,6 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.launch
 
@@ -46,6 +45,7 @@
     @Background bgDispatcher: CoroutineDispatcher,
     @Main mainDispatcher: CoroutineDispatcher,
     private val keyguardInteractor: KeyguardInteractor,
+    private val communalInteractor: CommunalInteractor,
     private val powerInteractor: PowerInteractor,
 ) :
     TransitionInteractor(
@@ -57,12 +57,12 @@
 
     override fun start() {
         listenForAlternateBouncerToGone()
-        listenForAlternateBouncerToLockscreenAodOrDozing()
+        listenForAlternateBouncerToLockscreenHubAodOrDozing()
         listenForAlternateBouncerToPrimaryBouncer()
         listenForTransitionToCamera(scope, keyguardInteractor)
     }
 
-    private fun listenForAlternateBouncerToLockscreenAodOrDozing() {
+    private fun listenForAlternateBouncerToLockscreenHubAodOrDozing() {
         scope.launch {
             keyguardInteractor.alternateBouncerShowing
                 // Add a slight delay, as alternateBouncer and primaryBouncer showing event changes
@@ -70,14 +70,11 @@
                 // happening prematurely.
                 .onEach { delay(50) }
                 .sample(
-                    combine(
-                        keyguardInteractor.primaryBouncerShowing,
-                        startedKeyguardTransitionStep,
-                        powerInteractor.isAwake,
-                        keyguardInteractor.isAodAvailable,
-                        ::toQuad
-                    ),
-                    ::toQuint
+                    keyguardInteractor.primaryBouncerShowing,
+                    startedKeyguardTransitionStep,
+                    powerInteractor.isAwake,
+                    keyguardInteractor.isAodAvailable,
+                    communalInteractor.isIdleOnCommunal
                 )
                 .collect {
                     (
@@ -85,7 +82,8 @@
                         isPrimaryBouncerShowing,
                         lastStartedTransitionStep,
                         isAwake,
-                        isAodAvailable) ->
+                        isAodAvailable,
+                        isIdleOnCommunal) ->
                     if (
                         !isAlternateBouncerShowing &&
                             !isPrimaryBouncerShowing &&
@@ -99,7 +97,11 @@
                                     KeyguardState.DOZING
                                 }
                             } else {
-                                KeyguardState.LOCKSCREEN
+                                if (isIdleOnCommunal) {
+                                    KeyguardState.GLANCEABLE_HUB
+                                } else {
+                                    KeyguardState.LOCKSCREEN
+                                }
                             }
                         startTransitionTo(to)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index 4df5d50..9d6b30f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.animation.ValueAnimator
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.Flags
 import com.android.systemui.communal.shared.model.CommunalSceneKey
 import com.android.systemui.dagger.SysUISingleton
@@ -40,6 +41,7 @@
 constructor(
     @Background private val scope: CoroutineScope,
     private val glanceableHubTransitions: GlanceableHubTransitions,
+    private val keyguardInteractor: KeyguardInteractor,
     override val transitionRepository: KeyguardTransitionRepository,
     transitionInteractor: KeyguardTransitionInteractor,
     private val powerInteractor: PowerInteractor,
@@ -58,6 +60,8 @@
         }
         listenForHubToLockscreen()
         listenForHubToDozing()
+        listenForHubToPrimaryBouncer()
+        listenForHubToAlternateBouncer()
     }
 
     override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
@@ -75,10 +79,42 @@
         glanceableHubTransitions.listenForLockscreenAndHubTransition(
             transitionName = "listenForHubToLockscreen",
             transitionOwnerName = TAG,
-            toScene = CommunalSceneKey.Blank
+            toScene = CommunalSceneKey.Blank,
         )
     }
 
+    private fun listenForHubToPrimaryBouncer() {
+        scope.launch("$TAG#listenForHubToPrimaryBouncer") {
+            keyguardInteractor.primaryBouncerShowing
+                .sample(startedKeyguardTransitionStep, ::Pair)
+                .collect { pair ->
+                    val (isBouncerShowing, lastStartedTransitionStep) = pair
+                    if (
+                        isBouncerShowing &&
+                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
+                    ) {
+                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+                    }
+                }
+        }
+    }
+
+    private fun listenForHubToAlternateBouncer() {
+        scope.launch("$TAG#listenForHubToAlternateBouncer") {
+            keyguardInteractor.alternateBouncerShowing
+                .sample(startedKeyguardTransitionStep, ::Pair)
+                .collect { pair ->
+                    val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
+                    if (
+                        isAlternateBouncerShowing &&
+                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
+                    ) {
+                        startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+                    }
+                }
+        }
+    }
+
     private fun listenForHubToDozing() {
         scope.launch {
             powerInteractor.isAsleep.sample(startedKeyguardTransitionStep, ::Pair).collect {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index c62055f..33b6373 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.animation.ValueAnimator
 import com.android.keyguard.KeyguardSecurityModel
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -29,8 +30,8 @@
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.util.kotlin.Utils.Companion.sample
 import com.android.systemui.util.kotlin.Utils.Companion.toQuad
-import com.android.systemui.util.kotlin.Utils.Companion.toQuint
 import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import com.android.wm.shell.animation.Interpolators
@@ -54,6 +55,7 @@
     @Background bgDispatcher: CoroutineDispatcher,
     @Main mainDispatcher: CoroutineDispatcher,
     private val keyguardInteractor: KeyguardInteractor,
+    private val communalInteractor: CommunalInteractor,
     private val flags: FeatureFlags,
     private val keyguardSecurityModel: KeyguardSecurityModel,
     private val selectedUserInteractor: SelectedUserInteractor,
@@ -69,7 +71,7 @@
     override fun start() {
         listenForPrimaryBouncerToGone()
         listenForPrimaryBouncerToAodOrDozing()
-        listenForPrimaryBouncerToLockscreenOrOccluded()
+        listenForPrimaryBouncerToLockscreenHubOrOccluded()
         listenForPrimaryBouncerToDreamingLockscreenHosted()
         listenForTransitionToCamera(scope, keyguardInteractor)
     }
@@ -125,18 +127,15 @@
         scope.launch { startTransitionTo(KeyguardState.GONE) }
     }
 
-    private fun listenForPrimaryBouncerToLockscreenOrOccluded() {
+    private fun listenForPrimaryBouncerToLockscreenHubOrOccluded() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
                 .sample(
-                    combine(
-                        powerInteractor.isAwake,
-                        startedKeyguardTransitionStep,
-                        keyguardInteractor.isKeyguardOccluded,
-                        keyguardInteractor.isActiveDreamLockscreenHosted,
-                        ::toQuad
-                    ),
-                    ::toQuint
+                    powerInteractor.isAwake,
+                    startedKeyguardTransitionStep,
+                    keyguardInteractor.isKeyguardOccluded,
+                    keyguardInteractor.isActiveDreamLockscreenHosted,
+                    communalInteractor.isIdleOnCommunal
                 )
                 .collect {
                     (
@@ -144,16 +143,23 @@
                         isAwake,
                         lastStartedTransitionStep,
                         occluded,
-                        isActiveDreamLockscreenHosted) ->
+                        isActiveDreamLockscreenHosted,
+                        isIdleOnCommunal) ->
                     if (
                         !isBouncerShowing &&
                             lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
                             isAwake &&
                             !isActiveDreamLockscreenHosted
                     ) {
-                        startTransitionTo(
-                            if (occluded) KeyguardState.OCCLUDED else KeyguardState.LOCKSCREEN
-                        )
+                        val toState =
+                            if (occluded) {
+                                KeyguardState.OCCLUDED
+                            } else if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(toState)
                     }
                 }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
index cb50839..ca66153 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.communal.domain.interactor.CommunalTransitionProgress
 import com.android.systemui.communal.shared.model.CommunalSceneKey
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
@@ -30,12 +31,15 @@
 import com.android.systemui.util.kotlin.sample
 import java.util.UUID
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flowOn
 
 class GlanceableHubTransitions
 @Inject
 constructor(
     @Application private val scope: CoroutineScope,
+    @Background private val bgDispatcher: CoroutineDispatcher,
     private val transitionInteractor: KeyguardTransitionInteractor,
     private val transitionRepository: KeyguardTransitionRepository,
     private val communalInteractor: CommunalInteractor,
@@ -66,7 +70,10 @@
         scope.launch("$transitionOwnerName#$transitionName") {
             communalInteractor
                 .transitionProgressToScene(toScene)
-                .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
+                .sample(
+                    transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher),
+                    ::Pair
+                )
                 .collect { pair ->
                     val (transitionProgress, lastStartedStep) = pair
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 3362ebc..44cb0d6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -66,6 +66,13 @@
     private var topEdgeSwipeRegionWidth: Int = 0
 
     /**
+     * The height of the area in which a bottom edge swipe while the hub is open will not intercept
+     * touches, in pixels. This allows the bottom edge swipe to instead open the bouncer. Read from
+     * resources when [initView] is called.
+     */
+    private var bottomEdgeSwipeRegionWidth: Int = 0
+
+    /**
      * True if we are currently tracking a gesture for opening the hub that started in the edge
      * swipe region.
      */
@@ -132,6 +139,10 @@
             communalContainerView.resources.getDimensionPixelSize(
                 R.dimen.communal_top_edge_swipe_region_height
             )
+        bottomEdgeSwipeRegionWidth =
+            communalContainerView.resources.getDimensionPixelSize(
+                R.dimen.communal_bottom_edge_swipe_region_height
+            )
 
         collectFlow(
             communalContainerView,
@@ -179,11 +190,11 @@
         if (hubShowing && isDown) {
             val y = ev.rawY
             val topSwipe: Boolean = y <= topEdgeSwipeRegionWidth
+            val bottomSwipe = y >= communalContainerView.height - bottomEdgeSwipeRegionWidth
 
-            // TODO(b/315207481): allow bottom edge swipes to open the bouncer
-            if (topSwipe) {
-                // Don't intercept touches at the top edge so that swipes can open the notification
-                // shade.
+            if (topSwipe || bottomSwipe) {
+                // Don't intercept touches at the top/bottom edge so that swipes can open the
+                // notification shade and bouncer.
                 return false
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
index 2336a8e..6993c96 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
@@ -28,9 +28,13 @@
         fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) =
             Quad(a, bcd.first, bcd.second, bcd.third)
 
+        fun <A, B, C, D, E> toQuint(a: A, b: B, c: C, d: D, e: E) = Quint(a, b, c, d, e)
         fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) =
             Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth)
 
+        fun <A, B, C, D, E, F> toSextuple(a: A, bcdef: Quint<B, C, D, E, F>) =
+            Sextuple(a, bcdef.first, bcdef.second, bcdef.third, bcdef.fourth, bcdef.fifth)
+
         /**
          * Samples the provided flows, emitting a tuple of the original flow's value as well as each
          * of the combined flows' values.
@@ -69,6 +73,22 @@
         ): Flow<Quint<A, B, C, D, E>> {
             return this.sample(combine(b, c, d, e, ::Quad), ::toQuint)
         }
+
+        /**
+         * Samples the provided flows, emitting a tuple of the original flow's value as well as each
+         * of the combined flows' values.
+         *
+         * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>, Flow<E>, Flow<F>) -> (A, B, C, D, E, F)
+         */
+        fun <A, B, C, D, E, F> Flow<A>.sample(
+            b: Flow<B>,
+            c: Flow<C>,
+            d: Flow<D>,
+            e: Flow<E>,
+            f: Flow<F>,
+        ): Flow<Sextuple<A, B, C, D, E, F>> {
+            return this.sample(combine(b, c, d, e, f, ::Quint), ::toSextuple)
+        }
     }
 }
 
@@ -81,3 +101,12 @@
     val fourth: D,
     val fifth: E
 )
+
+data class Sextuple<A, B, C, D, E, F>(
+    val first: A,
+    val second: B,
+    val third: C,
+    val fourth: D,
+    val fifth: E,
+    val sixth: F,
+)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index d8eb05a..d06457b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1720,6 +1720,24 @@
     }
 
     @Test
+    public void assistantVisible_sendEventToFaceAuthInteractor() {
+        // WHEN the assistant is visible
+        mKeyguardUpdateMonitor.setAssistantVisible(true);
+
+        // THEN send event to face auth interactor
+        verify(mFaceAuthInteractor).onAssistantTriggeredOnLockScreen();
+    }
+
+    @Test
+    public void assistantNotVisible_doesNotSendEventToFaceAuthInteractor() {
+        // WHEN the assistant is visible
+        mKeyguardUpdateMonitor.setAssistantVisible(false);
+
+        // THEN never send event to face auth interactor
+        verify(mFaceAuthInteractor, never()).onAssistantTriggeredOnLockScreen();
+    }
+
+    @Test
     public void fingerprintFailure_requestActiveUnlock_dismissKeyguard() {
         // GIVEN shouldTriggerActiveUnlock
         bouncerFullyVisible();
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 754a7fd..8a3a434 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -309,6 +309,28 @@
 
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testRaceCondition_doNotRegisterCentralSurfacesImmediately() {
+        create(false);
+
+        // GIVEN central surfaces is not registered with KeyguardViewMediator, but a call to enable
+        // keyguard comes in
+        mViewMediator.onSystemReady();
+        mViewMediator.setKeyguardEnabled(true);
+        TestableLooper.get(this).processAllMessages();
+
+        // If this step has been reached, then system ui has not crashed. Now register
+        // CentralSurfaces
+        assertFalse(mViewMediator.isShowingAndNotOccluded());
+        register();
+        TestableLooper.get(this).moveTimeForward(100);
+        TestableLooper.get(this).processAllMessages();
+
+        // THEN keyguard is shown
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() {
         // GIVEN keyguard is not enabled and isn't showing
         mViewMediator.onSystemReady();
@@ -1139,6 +1161,11 @@
     }
 
     private void createAndStartViewMediator(boolean orderUnlockAndWake) {
+        create(orderUnlockAndWake);
+        register();
+    }
+
+    private void create(boolean orderUnlockAndWake) {
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.config_orderUnlockAndWake, orderUnlockAndWake);
 
@@ -1189,7 +1216,9 @@
                 mSelectedUserInteractor,
                 mKeyguardInteractor);
         mViewMediator.start();
+    }
 
+    private void register() {
         mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
index 809947d..6092b6b35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
@@ -66,6 +66,7 @@
                 bgDispatcher = super.testDispatcher,
                 mainDispatcher = super.testDispatcher,
                 keyguardInteractor = super.keyguardInteractor,
+                communalInteractor = super.communalInteractor,
                 flags = FakeFeatureFlags(),
                 keyguardSecurityModel = mock(),
                 powerInteractor = PowerInteractorFactory.create().powerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTestCase.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTestCase.kt
index 339fd22..a03aed0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTestCase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTestCase.kt
@@ -17,14 +17,18 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import dagger.Lazy
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 
 open class KeyguardTransitionInteractorTestCase : SysuiTestCase() {
+    private val kosmos = testKosmos()
     val testDispatcher = StandardTestDispatcher()
     var testScope = TestScope(testDispatcher)
 
@@ -32,6 +36,7 @@
     lateinit var transitionRepository: FakeKeyguardTransitionRepository
 
     lateinit var keyguardInteractor: KeyguardInteractor
+    lateinit var communalInteractor: CommunalInteractor
     lateinit var transitionInteractor: KeyguardTransitionInteractor
 
     /**
@@ -51,6 +56,8 @@
         keyguardInteractor =
             KeyguardInteractorFactory.create(repository = keyguardRepository).keyguardInteractor
 
+        communalInteractor = kosmos.communalInteractor
+
         transitionInteractor =
             KeyguardTransitionInteractorFactory.create(
                     repository = transitionRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index dafd9e6..892be35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -156,10 +156,11 @@
 
         val glanceableHubTransitions =
             GlanceableHubTransitions(
-                testScope,
-                transitionInteractor,
-                transitionRepository,
-                communalInteractor
+                scope = testScope,
+                bgDispatcher = kosmos.testDispatcher,
+                transitionInteractor = transitionInteractor,
+                transitionRepository = transitionRepository,
+                communalInteractor = communalInteractor
             )
         fromLockscreenTransitionInteractor =
             FromLockscreenTransitionInteractor(
@@ -196,6 +197,7 @@
                     flags = featureFlags,
                     keyguardSecurityModel = keyguardSecurityModel,
                     powerInteractor = powerInteractor,
+                    communalInteractor = communalInteractor,
                     selectedUserInteractor = mSelectedUserInteractor,
                 )
                 .apply { start() }
@@ -278,6 +280,7 @@
                     keyguardInteractor = keyguardInteractor,
                     transitionRepository = transitionRepository,
                     transitionInteractor = transitionInteractor,
+                    communalInteractor = communalInteractor,
                     powerInteractor = powerInteractor,
                 )
                 .apply { start() }
@@ -288,6 +291,7 @@
                     bgDispatcher = kosmos.testDispatcher,
                     mainDispatcher = kosmos.testDispatcher,
                     glanceableHubTransitions = glanceableHubTransitions,
+                    keyguardInteractor = keyguardInteractor,
                     transitionRepository = transitionRepository,
                     transitionInteractor = transitionInteractor,
                     powerInteractor = powerInteractor,
@@ -1023,6 +1027,45 @@
         }
 
     @Test
+    fun alternateBouncerToGlanceableHub() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+            bouncerRepository.setAlternateVisible(true)
+            runTransitionAndSetWakefulness(
+                KeyguardState.LOCKSCREEN,
+                KeyguardState.ALTERNATE_BOUNCER
+            )
+
+            // GIVEN the primary bouncer isn't showing and device not sleeping
+            bouncerRepository.setPrimaryShow(false)
+
+            // GIVEN the device is idle on the glanceable hub
+            val idleTransitionState =
+                MutableStateFlow<ObservableCommunalTransitionState>(
+                    ObservableCommunalTransitionState.Idle(CommunalSceneKey.Communal)
+                )
+            communalInteractor.setTransitionState(idleTransitionState)
+            runCurrent()
+
+            // WHEN the alternateBouncer stops showing
+            bouncerRepository.setAlternateVisible(false)
+            advanceUntilIdle()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture())
+                }
+            // THEN a transition to LOCKSCREEN should occur
+            assertThat(info.ownerName)
+                .isEqualTo(FromAlternateBouncerTransitionInteractor::class.simpleName)
+            assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+            assertThat(info.to).isEqualTo(KeyguardState.GLANCEABLE_HUB)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
     fun primaryBouncerToAod() =
         testScope.runTest {
             // GIVEN a prior transition has run to PRIMARY_BOUNCER
@@ -1085,7 +1128,7 @@
             bouncerRepository.setPrimaryShow(true)
             runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER)
 
-            // WHEN the alternateBouncer stops showing
+            // WHEN the primaryBouncer stops showing
             bouncerRepository.setPrimaryShow(false)
             runCurrent()
 
@@ -1103,6 +1146,39 @@
         }
 
     @Test
+    fun primaryBouncerToGlanceableHub() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to PRIMARY_BOUNCER
+            bouncerRepository.setPrimaryShow(true)
+            runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER)
+
+            // GIVEN the device is idle on the glanceable hub
+            val idleTransitionState =
+                MutableStateFlow<ObservableCommunalTransitionState>(
+                    ObservableCommunalTransitionState.Idle(CommunalSceneKey.Communal)
+                )
+            communalInteractor.setTransitionState(idleTransitionState)
+            runCurrent()
+
+            // WHEN the primaryBouncer stops showing
+            bouncerRepository.setPrimaryShow(false)
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture())
+                }
+            // THEN a transition to LOCKSCREEN should occur
+            assertThat(info.ownerName)
+                .isEqualTo(FromPrimaryBouncerTransitionInteractor::class.simpleName)
+            assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(info.to).isEqualTo(KeyguardState.GLANCEABLE_HUB)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
     fun primaryBouncerToDreamingLockscreenHosted() =
         testScope.runTest {
             // GIVEN device dreaming with the lockscreen hosted dream and not dozing
@@ -1640,6 +1716,54 @@
             coroutineContext.cancelChildren()
         }
 
+    @Test
+    fun glanceableHubToPrimaryBouncer() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+            runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.GLANCEABLE_HUB)
+
+            // WHEN the primary bouncer shows
+            bouncerRepository.setPrimaryShow(true)
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture())
+                }
+            // THEN a transition to PRIMARY_BOUNCER should occur
+            assertThat(info.ownerName)
+                .isEqualTo(FromGlanceableHubTransitionInteractor::class.simpleName)
+            assertThat(info.from).isEqualTo(KeyguardState.GLANCEABLE_HUB)
+            assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun glanceableHubToAlternateBouncer() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+            runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.GLANCEABLE_HUB)
+
+            // WHEN the primary bouncer shows
+            bouncerRepository.setAlternateVisible(true)
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture())
+                }
+            // THEN a transition to PRIMARY_BOUNCER should occur
+            assertThat(info.ownerName)
+                .isEqualTo(FromGlanceableHubTransitionInteractor::class.simpleName)
+            assertThat(info.from).isEqualTo(KeyguardState.GLANCEABLE_HUB)
+            assertThat(info.to).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
     private fun createKeyguardInteractor(): KeyguardInteractor {
         return KeyguardInteractorFactory.create(
                 featureFlags = featureFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index c1f5d85..45f6869 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -96,6 +96,10 @@
 
         overrideResource(R.dimen.communal_right_edge_swipe_region_width, RIGHT_SWIPE_REGION_WIDTH)
         overrideResource(R.dimen.communal_top_edge_swipe_region_height, TOP_SWIPE_REGION_WIDTH)
+        overrideResource(
+            R.dimen.communal_bottom_edge_swipe_region_height,
+            BOTTOM_SWIPE_REGION_WIDTH
+        )
     }
 
     @Test
@@ -180,6 +184,17 @@
     }
 
     @Test
+    fun onTouchEvent_bottomSwipeWhenHubOpen_returnsFalse() {
+        // Communal is open.
+        communalRepository.setDesiredScene(CommunalSceneKey.Communal)
+
+        initAndAttachContainerView()
+
+        // Touch event in the bottom swipe reqgion is not intercepted.
+        assertThat(underTest.onTouchEvent(DOWN_IN_BOTTOM_SWIPE_REGION_EVENT)).isFalse()
+    }
+
+    @Test
     fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() {
         // Communal is open.
         communalRepository.setDesiredScene(CommunalSceneKey.Communal)
@@ -227,6 +242,7 @@
         private const val CONTAINER_HEIGHT = 100
         private const val RIGHT_SWIPE_REGION_WIDTH = 20
         private const val TOP_SWIPE_REGION_WIDTH = 20
+        private const val BOTTOM_SWIPE_REGION_WIDTH = 20
 
         private val DOWN_EVENT =
             MotionEvent.obtain(
@@ -248,6 +264,8 @@
                 TOP_SWIPE_REGION_WIDTH.toFloat(),
                 0
             )
+        private val DOWN_IN_BOTTOM_SWIPE_REGION_EVENT =
+            MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, CONTAINER_HEIGHT.toFloat(), 0)
         private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
         private val UP_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
 
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 200e758..461db8e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -226,6 +226,7 @@
                 powerInteractor,
                 new GlanceableHubTransitions(
                         mTestScope,
+                        mKosmos.getTestDispatcher(),
                         keyguardTransitionInteractor,
                         keyguardTransitionRepository,
                         communalInteractor
@@ -247,6 +248,7 @@
                 mKosmos.getTestDispatcher(),
                 mKosmos.getTestDispatcher(),
                 keyguardInteractor,
+                communalInteractor,
                 featureFlags,
                 mKeyguardSecurityModel,
                 mSelectedUserInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
index 6fc88ce..3e0a647 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
@@ -257,6 +257,7 @@
                 powerInteractor,
                 new GlanceableHubTransitions(
                         mTestScope,
+                        mKosmos.getTestDispatcher(),
                         keyguardTransitionInteractor,
                         keyguardTransitionRepository,
                         communalInteractor
@@ -278,6 +279,7 @@
                 mKosmos.getTestDispatcher(),
                 mKosmos.getTestDispatcher(),
                 keyguardInteractor,
+                communalInteractor,
                 featureFlags,
                 mock(KeyguardSecurityModel.class),
                 mSelectedUserInteractor,
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 13934da..8cb064d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -158,6 +158,7 @@
                 powerInteractor,
                 GlanceableHubTransitions(
                     testScope,
+                    testDispatcher,
                     keyguardTransitionInteractor,
                     keyguardTransitionRepository,
                     communalInteractor
@@ -180,6 +181,7 @@
                 testDispatcher,
                 testDispatcher,
                 keyguardInteractor,
+                communalInteractor,
                 featureFlags,
                 mock(),
                 mock(),
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 93d8dcc..98f3ede 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -456,6 +456,7 @@
                 powerInteractor,
                 new GlanceableHubTransitions(
                         mTestScope,
+                        mKosmos.getTestDispatcher(),
                         keyguardTransitionInteractor,
                         keyguardTransitionRepository,
                         communalInteractor
@@ -477,6 +478,7 @@
                 mKosmos.getTestDispatcher(),
                 mKosmos.getTestDispatcher(),
                 keyguardInteractor,
+                communalInteractor,
                 featureFlags,
                 mock(KeyguardSecurityModel.class),
                 mSelectedUserInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
index 97536e2..719686e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import com.android.keyguard.keyguardSecurityModel
+import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
 import com.android.systemui.kosmos.Kosmos
@@ -34,6 +35,7 @@
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
             keyguardInteractor = keyguardInteractor,
+            communalInteractor = communalInteractor,
             flags = featureFlagsClassic,
             keyguardSecurityModel = keyguardSecurityModel,
             selectedUserInteractor = selectedUserInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
index ec17c48..55885bf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
@@ -20,11 +20,13 @@
 import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
 
 val Kosmos.glanceableHubTransitions by
     Kosmos.Fixture {
         GlanceableHubTransitions(
             scope = applicationCoroutineScope,
+            bgDispatcher = testDispatcher,
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
             communalInteractor = communalInteractor,
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index beb68d3..50340d2 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1167,7 +1167,7 @@
                 // sender userId can be a real user ID or USER_ALL.
                 final int senderUserId = pendingResult.getSendingUserId();
                 if (senderUserId != UserHandle.USER_ALL) {
-                    if (senderUserId != mSettings.getCurrentUserId()) {
+                    if (senderUserId != mSettings.getUserId()) {
                         // A background user is trying to hide the dialog. Ignore.
                         return;
                     }
@@ -1245,7 +1245,7 @@
         @GuardedBy("ImfLock.class")
         private boolean isChangingPackagesOfCurrentUserLocked() {
             final int userId = getChangingUserId();
-            final boolean retval = userId == mSettings.getCurrentUserId();
+            final boolean retval = userId == mSettings.getUserId();
             if (DEBUG) {
                 if (!retval) {
                     Slog.d(TAG, "--- ignore this call back from a background user: " + userId);
@@ -1344,8 +1344,7 @@
             }
             if (changed) {
                 AdditionalSubtypeUtils.save(
-                        mAdditionalSubtypeMap, mSettings.getMethodMap(),
-                        mSettings.getCurrentUserId());
+                        mAdditionalSubtypeMap, mSettings.getMethodMap(), mSettings.getUserId());
                 mChangedPackages.add(packageName);
             }
         }
@@ -1425,8 +1424,7 @@
                                             + imi.getComponent());
                             mAdditionalSubtypeMap.remove(imi.getId());
                             AdditionalSubtypeUtils.save(mAdditionalSubtypeMap,
-                                    mSettings.getMethodMap(),
-                                    mSettings.getCurrentUserId());
+                                    mSettings.getMethodMap(), mSettings.getUserId());
                         }
                     }
                 }
@@ -1440,7 +1438,7 @@
                     if (change == PACKAGE_TEMPORARY_CHANGE
                             || change == PACKAGE_PERMANENT_CHANGE) {
                         final PackageManager userAwarePackageManager =
-                                getPackageManagerForUser(mContext, mSettings.getCurrentUserId());
+                                getPackageManagerForUser(mContext, mSettings.getUserId());
                         ServiceInfo si = null;
                         try {
                             si = userAwarePackageManager.getServiceInfo(curIm.getComponent(),
@@ -1576,7 +1574,7 @@
 
     void onUnlockUser(@UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            final int currentUserId = mSettings.getCurrentUserId();
+            final int currentUserId = mSettings.getUserId();
             if (DEBUG) {
                 Slog.d(TAG, "onUnlockUser: userId=" + userId + " curUserId=" + currentUserId);
             }
@@ -1665,7 +1663,7 @@
                         mSettings.getMethodMap(), userId);
         mHardwareKeyboardShortcutController =
                 new HardwareKeyboardShortcutController(mSettings.getMethodMap(),
-                        mSettings.getCurrentUserId());
+                        mSettings.getUserId());
         mMenuController = new InputMethodMenuController(this);
         mBindingController =
                 bindingControllerForTesting != null
@@ -1696,7 +1694,7 @@
     @GuardedBy("ImfLock.class")
     @UserIdInt
     int getCurrentImeUserIdLocked() {
-        return mSettings.getCurrentUserId();
+        return mSettings.getUserId();
     }
 
     private final class InkWindowInitializer implements Runnable {
@@ -1784,7 +1782,7 @@
             IInputMethodClientInvoker clientToBeReset) {
         if (DEBUG) {
             Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
-                    + " currentUserId=" + mSettings.getCurrentUserId());
+                    + " currentUserId=" + mSettings.getUserId());
         }
 
         maybeInitImeNavbarConfigLocked(newUserId);
@@ -1854,7 +1852,7 @@
             }
             if (!mSystemReady) {
                 mSystemReady = true;
-                final int currentUserId = mSettings.getCurrentUserId();
+                final int currentUserId = mSettings.getUserId();
                 mStatusBarManagerInternal =
                         LocalServices.getService(StatusBarManagerInternal.class);
                 hideStatusBarIconLocked();
@@ -1875,7 +1873,7 @@
                     // the "mImeDrawsImeNavBarResLazyInitFuture" field.
                     synchronized (ImfLock.class) {
                         mImeDrawsImeNavBarResLazyInitFuture = null;
-                        if (currentUserId != mSettings.getCurrentUserId()) {
+                        if (currentUserId != mSettings.getUserId()) {
                             // This means that the current user is already switched to other user
                             // before the background task is executed. In this scenario the relevant
                             // field should already be initialized.
@@ -1947,7 +1945,7 @@
         }
         synchronized (ImfLock.class) {
             final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
-                    mSettings.getCurrentUserId(), null);
+                    mSettings.getUserId(), null);
             if (resolvedUserIds.length != 1) {
                 return Collections.emptyList();
             }
@@ -1970,7 +1968,7 @@
         }
         synchronized (ImfLock.class) {
             final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
-                    mSettings.getCurrentUserId(), null);
+                    mSettings.getUserId(), null);
             if (resolvedUserIds.length != 1) {
                 return Collections.emptyList();
             }
@@ -1997,7 +1995,7 @@
             }
 
             // Check if selected IME of current user supports handwriting.
-            if (userId == mSettings.getCurrentUserId()) {
+            if (userId == mSettings.getUserId()) {
                 return mBindingController.supportsStylusHandwriting();
             }
             //TODO(b/197848765): This can be optimized by caching multi-user methodMaps/methodList.
@@ -2025,7 +2023,7 @@
     private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId,
             @DirectBootAwareness int directBootAwareness, int callingUid) {
         final InputMethodSettings settings;
-        if (userId == mSettings.getCurrentUserId()
+        if (userId == mSettings.getUserId()
                 && directBootAwareness == DirectBootAwareness.AUTO) {
             settings = mSettings;
         } else {
@@ -2048,7 +2046,7 @@
             int callingUid) {
         final ArrayList<InputMethodInfo> methodList;
         final InputMethodSettings settings;
-        if (userId == mSettings.getCurrentUserId()) {
+        if (userId == mSettings.getUserId()) {
             methodList = mSettings.getEnabledInputMethodList();
             settings = mSettings;
         } else {
@@ -2112,7 +2110,7 @@
     @GuardedBy("ImfLock.class")
     private List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(String imiId,
             boolean allowsImplicitlyEnabledSubtypes, @UserIdInt int userId, int callingUid) {
-        if (userId == mSettings.getCurrentUserId()) {
+        if (userId == mSettings.getUserId()) {
             final InputMethodInfo imi;
             String selectedMethodId = getSelectedMethodIdLocked();
             if (imiId == null && selectedMethodId != null) {
@@ -2300,7 +2298,7 @@
 
         final boolean restarting = !initial;
         final Binder startInputToken = new Binder();
-        final StartInputInfo info = new StartInputInfo(mSettings.getCurrentUserId(),
+        final StartInputInfo info = new StartInputInfo(mSettings.getUserId(),
                 getCurTokenLocked(),
                 mCurTokenDisplayId, getCurIdLocked(), startInputReason, restarting,
                 UserHandle.getUserId(mCurClient.mUid),
@@ -2315,9 +2313,9 @@
         // same-user scenarios.
         // That said ignoring cross-user scenario will never affect IMEs that do not have
         // INTERACT_ACROSS_USERS(_FULL) permissions, which is actually almost always the case.
-        if (mSettings.getCurrentUserId() == UserHandle.getUserId(
+        if (mSettings.getUserId() == UserHandle.getUserId(
                 mCurClient.mUid)) {
-            mPackageManagerInternal.grantImplicitAccess(mSettings.getCurrentUserId(),
+            mPackageManagerInternal.grantImplicitAccess(mSettings.getUserId(),
                     null /* intent */, UserHandle.getAppId(getCurMethodUidLocked()),
                     mCurClient.mUid, true /* direct */);
         }
@@ -2939,7 +2937,7 @@
                 } else if (packageName != null) {
                     if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
                     final PackageManager userAwarePackageManager =
-                            getPackageManagerForUser(mContext, mSettings.getCurrentUserId());
+                            getPackageManagerForUser(mContext, mSettings.getUserId());
                     ApplicationInfo applicationInfo = null;
                     try {
                         applicationInfo = userAwarePackageManager.getApplicationInfo(packageName,
@@ -3001,7 +2999,7 @@
             return false;
         }
         if (mWindowManagerInternal.isKeyguardShowingAndNotOccluded()
-                && mWindowManagerInternal.isKeyguardSecure(mSettings.getCurrentUserId())) {
+                && mWindowManagerInternal.isKeyguardSecure(mSettings.getUserId())) {
             return false;
         }
         if ((visibility & InputMethodService.IME_ACTIVE) == 0
@@ -3180,7 +3178,7 @@
     void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
         if (enabledMayChange) {
             final PackageManager userAwarePackageManager = getPackageManagerForUser(mContext,
-                    mSettings.getCurrentUserId());
+                    mSettings.getUserId());
 
             List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodList();
             for (int i = 0; i < enabled.size(); i++) {
@@ -3228,18 +3226,18 @@
         }
 
         // TODO: Instantiate mSwitchingController for each user.
-        if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
+        if (mSettings.getUserId() == mSwitchingController.getUserId()) {
             mSwitchingController.resetCircularListLocked(mSettings.getMethodMap());
         } else {
             mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
-                    mContext, mSettings.getMethodMap(), mSettings.getCurrentUserId());
+                    mContext, mSettings.getMethodMap(), mSettings.getUserId());
         }
         // TODO: Instantiate mHardwareKeyboardShortcutController for each user.
-        if (mSettings.getCurrentUserId() == mHardwareKeyboardShortcutController.getUserId()) {
+        if (mSettings.getUserId() == mHardwareKeyboardShortcutController.getUserId()) {
             mHardwareKeyboardShortcutController.reset(mSettings.getMethodMap());
         } else {
             mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
-                    mSettings.getMethodMap(), mSettings.getCurrentUserId());
+                    mSettings.getMethodMap(), mSettings.getUserId());
         }
         sendOnNavButtonFlagsChangedLocked();
     }
@@ -3270,7 +3268,7 @@
 
         // See if we need to notify a subtype change within the same IME.
         if (id.equals(getSelectedMethodIdLocked())) {
-            final int userId = mSettings.getCurrentUserId();
+            final int userId = mSettings.getUserId();
             final int subtypeCount = info.getSubtypeCount();
             if (subtypeCount <= 0) {
                 notifyInputMethodSubtypeChangedLocked(userId, info, null);
@@ -3781,7 +3779,7 @@
                 return InputBindResult.USER_SWITCHING;
             }
             final int[] profileIdsWithDisabled = mUserManagerInternal.getProfileIds(
-                    mSettings.getCurrentUserId(), false /* enabledOnly */);
+                    mSettings.getUserId(), false /* enabledOnly */);
             for (int profileId : profileIdsWithDisabled) {
                 if (profileId == userId) {
                     scheduleSwitchUserTaskLocked(userId, cs.mClient);
@@ -3800,7 +3798,7 @@
             mVisibilityStateComputer.mShowForced = false;
         }
 
-        final int currentUserId = mSettings.getCurrentUserId();
+        final int currentUserId = mSettings.getUserId();
         if (userId != currentUserId) {
             if (ArrayUtils.contains(
                     mUserManagerInternal.getProfileIds(currentUserId, false), userId)) {
@@ -3944,7 +3942,7 @@
                 && mCurFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
             return true;
         }
-        if (mSettings.getCurrentUserId() != UserHandle.getUserId(uid)) {
+        if (mSettings.getUserId() != UserHandle.getUserId(uid)) {
             return false;
         }
         if (getCurIntentLocked() != null && InputMethodUtils.checkIfPackageBelongsToUid(
@@ -4085,8 +4083,7 @@
                             && !TextUtils.isEmpty(mCurrentSubtype.getLocale())) {
                         locale = mCurrentSubtype.getLocale();
                     } else {
-                        locale = SystemLocaleWrapper.get(mSettings.getCurrentUserId()).get(0)
-                                .toString();
+                        locale = SystemLocaleWrapper.get(mSettings.getUserId()).get(0).toString();
                     }
                     for (int i = 0; i < enabledCount; ++i) {
                         final InputMethodInfo imi = enabled.get(i);
@@ -4164,7 +4161,7 @@
                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         }
         synchronized (ImfLock.class) {
-            if (mSettings.getCurrentUserId() == userId) {
+            if (mSettings.getUserId() == userId) {
                 return mSettings.getLastInputMethodSubtype();
             }
 
@@ -4199,7 +4196,7 @@
                 return;
             }
 
-            if (mSettings.getCurrentUserId() == userId) {
+            if (mSettings.getUserId() == userId) {
                 if (!mSettings.setAdditionalInputMethodSubtypes(imiId, toBeAdded,
                         mAdditionalSubtypeMap, mPackageManagerInternal, callingUid)) {
                     return;
@@ -4243,7 +4240,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (ImfLock.class) {
-                final boolean currentUser = (mSettings.getCurrentUserId() == userId);
+                final boolean currentUser = (mSettings.getUserId() == userId);
                 final InputMethodSettings settings = currentUser
                         ? mSettings : queryMethodMapForUser(userId);
                 if (!settings.setEnabledInputMethodSubtypes(imeId, subtypeHashCodes)) {
@@ -4614,7 +4611,7 @@
                 }
                 return;
             }
-            if (mSettings.getCurrentUserId() != mSwitchingController.getUserId()) {
+            if (mSettings.getUserId() != mSwitchingController.getUserId()) {
                 return;
             }
             final InputMethodInfo imi =
@@ -4849,8 +4846,7 @@
                 }
                 synchronized (ImfLock.class) {
                     final boolean isScreenLocked = mWindowManagerInternal.isKeyguardLocked()
-                            && mWindowManagerInternal.isKeyguardSecure(
-                                    mSettings.getCurrentUserId());
+                            && mWindowManagerInternal.isKeyguardSecure(mSettings.getUserId());
                     final String lastInputMethodId = mSettings.getSelectedInputMethod();
                     int lastInputMethodSubtypeId =
                             mSettings.getSelectedInputMethodSubtypeId(lastInputMethodId);
@@ -4858,8 +4854,7 @@
                     final List<ImeSubtypeListItem> imList = InputMethodSubtypeSwitchingController
                             .getSortedInputMethodAndSubtypeList(
                                     showAuxSubtypes, isScreenLocked, true /* forImeMenu */,
-                                    mContext, mSettings.getMethodMap(),
-                                    mSettings.getCurrentUserId());
+                                    mContext, mSettings.getMethodMap(), mSettings.getUserId());
                     mMenuController.showInputMethodMenuLocked(showAuxSubtypes, displayId,
                             lastInputMethodId, lastInputMethodSubtypeId, imList);
                 }
@@ -5157,7 +5152,7 @@
         mMethodMapUpdateCount++;
         mMyPackageMonitor.clearKnownImePackageNamesLocked();
 
-        mSettings = queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(),
+        mSettings = queryInputMethodServicesInternal(mContext, mSettings.getUserId(),
                 mAdditionalSubtypeMap, DirectBootAwareness.AUTO);
 
         // Construct the set of possible IME packages for onPackageChanged() to avoid false
@@ -5170,7 +5165,7 @@
             final List<ResolveInfo> allInputMethodServices =
                     mContext.getPackageManager().queryIntentServicesAsUser(
                             new Intent(InputMethod.SERVICE_INTERFACE),
-                            PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId());
+                            PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getUserId());
             final int numImes = allInputMethodServices.size();
             for (int i = 0; i < numImes; ++i) {
                 final ServiceInfo si = allInputMethodServices.get(i).serviceInfo;
@@ -5241,18 +5236,18 @@
         updateDefaultVoiceImeIfNeededLocked();
 
         // TODO: Instantiate mSwitchingController for each user.
-        if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
+        if (mSettings.getUserId() == mSwitchingController.getUserId()) {
             mSwitchingController.resetCircularListLocked(mSettings.getMethodMap());
         } else {
             mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
-                    mContext, mSettings.getMethodMap(), mSettings.getCurrentUserId());
+                    mContext, mSettings.getMethodMap(), mSettings.getUserId());
         }
         // TODO: Instantiate mHardwareKeyboardShortcutController for each user.
-        if (mSettings.getCurrentUserId() == mHardwareKeyboardShortcutController.getUserId()) {
+        if (mSettings.getUserId() == mHardwareKeyboardShortcutController.getUserId()) {
             mHardwareKeyboardShortcutController.reset(mSettings.getMethodMap());
         } else {
             mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
-                    mSettings.getMethodMap(), mSettings.getCurrentUserId());
+                    mSettings.getMethodMap(), mSettings.getUserId());
         }
 
         sendOnNavButtonFlagsChangedLocked();
@@ -5260,7 +5255,7 @@
         // Notify InputMethodListListeners of the new installed InputMethods.
         final List<InputMethodInfo> inputMethodList = mSettings.getMethodList();
         mHandler.obtainMessage(MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED,
-                mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
+                mSettings.getUserId(), 0 /* unused */, inputMethodList).sendToTarget();
     }
 
     @GuardedBy("ImfLock.class")
@@ -5381,7 +5376,7 @@
                 mCurrentSubtype = getCurrentInputMethodSubtypeLocked();
             }
         }
-        notifyInputMethodSubtypeChangedLocked(mSettings.getCurrentUserId(), imi, mCurrentSubtype);
+        notifyInputMethodSubtypeChangedLocked(mSettings.getUserId(), imi, mCurrentSubtype);
 
         if (!setSubtypeOnly) {
             // Set InputMethod here
@@ -5422,7 +5417,7 @@
                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         }
         synchronized (ImfLock.class) {
-            if (mSettings.getCurrentUserId() == userId) {
+            if (mSettings.getUserId() == userId) {
                 return getCurrentInputMethodSubtypeLocked();
             }
 
@@ -5466,7 +5461,7 @@
                 if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
                     mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
                 } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
-                    final String locale = SystemLocaleWrapper.get(mSettings.getCurrentUserId())
+                    final String locale = SystemLocaleWrapper.get(mSettings.getUserId())
                             .get(0).toString();
                     mCurrentSubtype = SubtypeUtils.findLastResortApplicableSubtype(
                             explicitlyOrImplicitlyEnabledSubtypes,
@@ -5490,7 +5485,7 @@
     @GuardedBy("ImfLock.class")
     private InputMethodInfo queryDefaultInputMethodForUserIdLocked(@UserIdInt int userId) {
         final InputMethodSettings settings;
-        if (userId == mSettings.getCurrentUserId()) {
+        if (userId == mSettings.getUserId()) {
             settings = mSettings;
         } else {
             final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
@@ -5512,7 +5507,7 @@
 
     @GuardedBy("ImfLock.class")
     private boolean switchToInputMethodLocked(String imeId, @UserIdInt int userId) {
-        if (userId == mSettings.getCurrentUserId()) {
+        if (userId == mSettings.getUserId()) {
             if (!mSettings.getMethodMap().containsKey(imeId)
                     || !mSettings.getEnabledInputMethodList()
                     .contains(mSettings.getMethodMap().get(imeId))) {
@@ -5654,7 +5649,7 @@
         @Override
         public boolean setInputMethodEnabled(String imeId, boolean enabled, @UserIdInt int userId) {
             synchronized (ImfLock.class) {
-                if (userId == mSettings.getCurrentUserId()) {
+                if (userId == mSettings.getUserId()) {
                     if (!mSettings.getMethodMap().containsKey(imeId)) {
                         return false; // IME is not found.
                     }
@@ -6296,7 +6291,7 @@
         }
         synchronized (ImfLock.class) {
             final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                    mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                    mSettings.getUserId(), shellCommand.getErrPrintWriter());
             try (PrintWriter pr = shellCommand.getOutPrintWriter()) {
                 for (int userId : userIds) {
                     final List<InputMethodInfo> methods = all
@@ -6341,7 +6336,7 @@
              PrintWriter error = shellCommand.getErrPrintWriter()) {
             synchronized (ImfLock.class) {
                 final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                        mSettings.getUserId(), shellCommand.getErrPrintWriter());
                 for (int userId : userIds) {
                     if (!userHasDebugPriv(userId, shellCommand)) {
                         continue;
@@ -6400,7 +6395,7 @@
             PrintWriter error) {
         boolean failedToEnableUnknownIme = false;
         boolean previouslyEnabled = false;
-        if (userId == mSettings.getCurrentUserId()) {
+        if (userId == mSettings.getUserId()) {
             if (enabled && !mSettings.getMethodMap().containsKey(imeId)) {
                 failedToEnableUnknownIme = true;
             } else {
@@ -6462,7 +6457,7 @@
              PrintWriter error = shellCommand.getErrPrintWriter()) {
             synchronized (ImfLock.class) {
                 final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                        mSettings.getUserId(), shellCommand.getErrPrintWriter());
                 for (int userId : userIds) {
                     if (!userHasDebugPriv(userId, shellCommand)) {
                         continue;
@@ -6502,7 +6497,7 @@
         synchronized (ImfLock.class) {
             try (PrintWriter out = shellCommand.getOutPrintWriter()) {
                 final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                        mSettings.getUserId(), shellCommand.getErrPrintWriter());
                 for (int userId : userIds) {
                     if (!userHasDebugPriv(userId, shellCommand)) {
                         continue;
@@ -6514,7 +6509,7 @@
                     }
                     final String nextIme;
                     final List<InputMethodInfo> nextEnabledImes;
-                    if (userId == mSettings.getCurrentUserId()) {
+                    if (userId == mSettings.getUserId()) {
                         hideCurrentInputLocked(mCurFocusedWindow, null /* statsToken */,
                                 0 /* flags */, null /* resultReceiver */,
                                 SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
@@ -6537,7 +6532,7 @@
                         }
                         updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
                         InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
-                                getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
+                                getPackageManagerForUser(mContext, mSettings.getUserId()),
                                 mSettings.getEnabledInputMethodList());
                         nextIme = mSettings.getSelectedInputMethod();
                         nextEnabledImes = mSettings.getEnabledInputMethodList();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
index abd7688..a51002b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
@@ -63,7 +63,7 @@
     private final List<InputMethodInfo> mMethodList;
 
     @UserIdInt
-    private final int mCurrentUserId;
+    private final int mUserId;
 
     private static void buildEnabledInputMethodsSettingString(
             StringBuilder builder, Pair<String, ArrayList<String>> ime) {
@@ -87,7 +87,7 @@
     private InputMethodSettings(InputMethodMap methodMap, @UserIdInt int userId) {
         mMethodMap = methodMap;
         mMethodList = methodMap.values();
-        mCurrentUserId = userId;
+        mUserId = userId;
         String ime = getSelectedInputMethod();
         String defaultDeviceIme = getSelectedDefaultDeviceInputMethod();
         if (defaultDeviceIme != null && !Objects.equals(ime, defaultDeviceIme)) {
@@ -109,20 +109,20 @@
     }
 
     private void putString(@NonNull String key, @Nullable String str) {
-        SecureSettingsWrapper.putString(key, str, mCurrentUserId);
+        SecureSettingsWrapper.putString(key, str, mUserId);
     }
 
     @Nullable
     private String getString(@NonNull String key, @Nullable String defaultValue) {
-        return SecureSettingsWrapper.getString(key, defaultValue, mCurrentUserId);
+        return SecureSettingsWrapper.getString(key, defaultValue, mUserId);
     }
 
     private void putInt(String key, int value) {
-        SecureSettingsWrapper.putInt(key, value, mCurrentUserId);
+        SecureSettingsWrapper.putInt(key, value, mUserId);
     }
 
     private int getInt(String key, int defaultValue) {
-        return SecureSettingsWrapper.getInt(key, defaultValue, mCurrentUserId);
+        return SecureSettingsWrapper.getInt(key, defaultValue, mUserId);
     }
 
     ArrayList<InputMethodInfo> getEnabledInputMethodList() {
@@ -142,7 +142,7 @@
                 getEnabledInputMethodSubtypeList(imi);
         if (allowsImplicitlyEnabledSubtypes && enabledSubtypes.isEmpty()) {
             enabledSubtypes = SubtypeUtils.getImplicitlyApplicableSubtypes(
-                    SystemLocaleWrapper.get(mCurrentUserId), imi);
+                    SystemLocaleWrapper.get(mUserId), imi);
         }
         return InputMethodSubtype.sort(imi, enabledSubtypes);
     }
@@ -394,7 +394,7 @@
 
     private String getEnabledSubtypeHashCodeForInputMethodAndSubtype(List<Pair<String,
             ArrayList<String>>> enabledImes, String imeId, String subtypeHashCode) {
-        final LocaleList localeList = SystemLocaleWrapper.get(mCurrentUserId);
+        final LocaleList localeList = SystemLocaleWrapper.get(mUserId);
         for (int i = 0; i < enabledImes.size(); ++i) {
             final Pair<String, ArrayList<String>> enabledIme = enabledImes.get(i);
             if (enabledIme.first.equals(imeId)) {
@@ -483,16 +483,14 @@
 
     void putSelectedInputMethod(String imeId) {
         if (DEBUG) {
-            Slog.d(TAG, "putSelectedInputMethodStr: " + imeId + ", "
-                    + mCurrentUserId);
+            Slog.d(TAG, "putSelectedInputMethodStr: " + imeId + ", " + mUserId);
         }
         putString(Settings.Secure.DEFAULT_INPUT_METHOD, imeId);
     }
 
     void putSelectedSubtype(int subtypeId) {
         if (DEBUG) {
-            Slog.d(TAG, "putSelectedInputMethodSubtypeStr: " + subtypeId + ", "
-                    + mCurrentUserId);
+            Slog.d(TAG, "putSelectedInputMethodSubtypeStr: " + subtypeId + ", " + mUserId);
         }
         putInt(Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtypeId);
     }
@@ -510,24 +508,21 @@
     String getSelectedDefaultDeviceInputMethod() {
         final String imi = getString(Settings.Secure.DEFAULT_DEVICE_INPUT_METHOD, null);
         if (DEBUG) {
-            Slog.d(TAG, "getSelectedDefaultDeviceInputMethodStr: " + imi + ", "
-                    + mCurrentUserId);
+            Slog.d(TAG, "getSelectedDefaultDeviceInputMethodStr: " + imi + ", " + mUserId);
         }
         return imi;
     }
 
     void putSelectedDefaultDeviceInputMethod(String imeId) {
         if (DEBUG) {
-            Slog.d(TAG, "putSelectedDefaultDeviceInputMethodStr: " + imeId + ", "
-                    + mCurrentUserId);
+            Slog.d(TAG, "putSelectedDefaultDeviceInputMethodStr: " + imeId + ", " + mUserId);
         }
         putString(Settings.Secure.DEFAULT_DEVICE_INPUT_METHOD, imeId);
     }
 
     void putDefaultVoiceInputMethod(String imeId) {
         if (DEBUG) {
-            Slog.d(TAG,
-                    "putDefaultVoiceInputMethodStr: " + imeId + ", " + mCurrentUserId);
+            Slog.d(TAG, "putDefaultVoiceInputMethodStr: " + imeId + ", " + mUserId);
         }
         putString(Settings.Secure.DEFAULT_VOICE_INPUT_METHOD, imeId);
     }
@@ -551,8 +546,8 @@
     }
 
     @UserIdInt
-    public int getCurrentUserId() {
-        return mCurrentUserId;
+    public int getUserId() {
+        return mUserId;
     }
 
     int getSelectedInputMethodSubtypeId(String selectedImiId) {
@@ -615,7 +610,7 @@
         if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
             return explicitlyOrImplicitlyEnabledSubtypes.get(0);
         }
-        final String locale = SystemLocaleWrapper.get(mCurrentUserId).get(0).toString();
+        final String locale = SystemLocaleWrapper.get(mUserId).get(0).toString();
         final InputMethodSubtype subtype = SubtypeUtils.findLastResortApplicableSubtype(
                 explicitlyOrImplicitlyEnabledSubtypes, SubtypeUtils.SUBTYPE_MODE_KEYBOARD,
                 locale, true);
@@ -644,7 +639,7 @@
         } else {
             additionalSubtypeMap.put(imi.getId(), subtypes);
         }
-        AdditionalSubtypeUtils.save(additionalSubtypeMap, mMethodMap, getCurrentUserId());
+        AdditionalSubtypeUtils.save(additionalSubtypeMap, mMethodMap, getUserId());
         return true;
     }
 
@@ -715,6 +710,6 @@
     }
 
     void dump(final Printer pw, final String prefix) {
-        pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
+        pw.println(prefix + "mUserId=" + mUserId);
     }
 }