summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bryce Lee <brycelee@google.com> 2024-10-29 13:00:13 -0700
committer Bryce Lee <brycelee@google.com> 2024-11-04 08:26:29 -0800
commita38706d54935bf18c91caf6f24af5ec7b4fe8d1a (patch)
tree0a0aebb004c63c0ea597cb2f30f03423649b53eb
parent282bd23257748634f7c75f196590ac97bf0fb0d8 (diff)
Fade keyguard status bar during transition to and from Glanceable Hub.
This change ties the keyguard status bar alpha to the transition progress to and from Glanceable Hub. Fixes: 374017195 Test: atest KeyguardStatusBarViewControllerTest#animateToGlanceableHub_affectsAlpha Test: atest KeyguardStatusBarViewControllerTest#animateToGlanceableHub_alphaResetOnCommunalNotShowing Flag: EXEMPT bugfix Change-Id: Ib24526c8d57bfc5e689a3450402cb7d28f64f109
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt99
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt110
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModel.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/StatusBarUserChipViewModelKosmos.kt24
8 files changed, 194 insertions, 123 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
index 627c0d0df657..b815c6ce0c51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone
import android.app.StatusBarManager
+import android.graphics.Insets
import android.os.UserHandle
import android.os.UserManager
import android.platform.test.annotations.DisableFlags
@@ -23,6 +24,7 @@ import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
+import android.testing.ViewUtils
import android.view.LayoutInflater
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -34,17 +36,21 @@ import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
-import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.res.R
import com.android.systemui.shade.ShadeViewStateProvider
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.StatusBarState
-import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
@@ -54,13 +60,16 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.UserInfoController
import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
+import com.android.systemui.statusbar.ui.viewmodel.statusBarUserChipViewModel
import com.android.systemui.testKosmos
-import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel
+import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.Assert
import org.junit.Before
import org.junit.Test
@@ -70,12 +79,11 @@ import org.mockito.ArgumentMatchers
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidJUnit4::class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
private lateinit var kosmos: Kosmos
private lateinit var testScope: TestScope
@@ -106,17 +114,11 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
@Mock private lateinit var biometricUnlockController: BiometricUnlockController
- @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
-
- @Mock private lateinit var statusBarContentInsetsProvider: StatusBarContentInsetsProvider
-
@Mock
private lateinit var statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore
@Mock private lateinit var userManager: UserManager
- @Mock private lateinit var statusBarUserChipViewModel: StatusBarUserChipViewModel
-
@Captor
private lateinit var configurationListenerCaptor:
ArgumentCaptor<ConfigurationController.ConfigurationListener>
@@ -139,21 +141,29 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
private val fakeExecutor = FakeExecutor(FakeSystemClock())
private val backgroundExecutor = FakeExecutor(FakeSystemClock())
+ private lateinit var looper: TestableLooper
+
@Before
@Throws(Exception::class)
fun setup() {
+ looper = TestableLooper.get(this)
kosmos = testKosmos()
testScope = kosmos.testScope
shadeViewStateProvider = TestShadeViewStateProvider()
+ Mockito.`when`(
+ kosmos.statusBarContentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()
+ )
+ .thenReturn(Insets.of(0, 0, 0, 0))
+
MockitoAnnotations.initMocks(this)
Mockito.`when`(iconManagerFactory.create(ArgumentMatchers.any(), ArgumentMatchers.any()))
.thenReturn(iconManager)
Mockito.`when`(statusBarContentInsetsProviderStore.defaultDisplay)
- .thenReturn(statusBarContentInsetsProvider)
+ .thenReturn(kosmos.statusBarContentInsetsProvider)
allowTestableLooperAsMainThread()
- TestableLooper.get(this).runWithLooper {
+ looper.runWithLooper {
keyguardStatusBarView =
Mockito.spy(
LayoutInflater.from(mContext).inflate(R.layout.keyguard_status_bar, null)
@@ -167,6 +177,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
private fun createController(): KeyguardStatusBarViewController {
return KeyguardStatusBarViewController(
+ kosmos.testDispatcher,
keyguardStatusBarView,
carrierTextController,
configurationController,
@@ -182,10 +193,10 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
keyguardUpdateMonitor,
kosmos.keyguardStatusBarViewModel,
biometricUnlockController,
- statusBarStateController,
+ kosmos.statusBarStateController,
statusBarContentInsetsProviderStore,
userManager,
- statusBarUserChipViewModel,
+ kosmos.statusBarUserChipViewModel,
secureSettings,
commandQueue,
fakeExecutor,
@@ -193,6 +204,8 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
logger,
statusOverlayHoverListenerFactory,
kosmos.communalSceneInteractor,
+ kosmos.glanceableHubToLockscreenTransitionViewModel,
+ kosmos.lockscreenToGlanceableHubTransitionViewModel,
)
}
@@ -682,21 +695,22 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
}
@Test
- fun testNewUserSwitcherDisablesAvatar_newUiOn() {
- // GIVEN the status bar user switcher chip is enabled
- Mockito.`when`(statusBarUserChipViewModel.chipEnabled).thenReturn(true)
+ fun testNewUserSwitcherDisablesAvatar_newUiOn() =
+ testScope.runTest {
+ // GIVEN the status bar user switcher chip is enabled
+ kosmos.fakeUserRepository.isStatusBarUserChipEnabled = true
- // WHEN the controller is created
- controller = createController()
+ // WHEN the controller is created
+ controller = createController()
- // THEN keyguard status bar view avatar is disabled
- Truth.assertThat(keyguardStatusBarView.isKeyguardUserAvatarEnabled).isFalse()
- }
+ // THEN keyguard status bar view avatar is disabled
+ Truth.assertThat(keyguardStatusBarView.isKeyguardUserAvatarEnabled).isFalse()
+ }
@Test
fun testNewUserSwitcherDisablesAvatar_newUiOff() {
// GIVEN the status bar user switcher chip is disabled
- Mockito.`when`(statusBarUserChipViewModel.chipEnabled).thenReturn(false)
+ kosmos.fakeUserRepository.isStatusBarUserChipEnabled = false
// WHEN the controller is created
controller = createController()
@@ -752,12 +766,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
}
private fun updateStatusBarState(state: Int) {
- val statusBarStateListenerCaptor =
- ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java)
- Mockito.verify(statusBarStateController).addCallback(statusBarStateListenerCaptor.capture())
- val callback = statusBarStateListenerCaptor.value
-
- callback.onStateChanged(state)
+ kosmos.statusBarStateController.setState(state)
}
@Test
@@ -774,6 +783,36 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() {
Truth.assertThat(keyguardStatusBarView.visibility).isEqualTo(View.INVISIBLE)
}
+ @Test
+ fun animateToGlanceableHub_affectsAlpha() =
+ testScope.runTest {
+ controller.init()
+ val transitionAlphaAmount = .5f
+ ViewUtils.attachView(keyguardStatusBarView)
+ looper.processAllMessages()
+ updateStateToKeyguard()
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
+ runCurrent()
+ controller.updateCommunalAlphaTransition(transitionAlphaAmount)
+ Truth.assertThat(keyguardStatusBarView.getAlpha()).isEqualTo(transitionAlphaAmount)
+ }
+
+ @Test
+ fun animateToGlanceableHub_alphaResetOnCommunalNotShowing() =
+ testScope.runTest {
+ controller.init()
+ val transitionAlphaAmount = .5f
+ ViewUtils.attachView(keyguardStatusBarView)
+ looper.processAllMessages()
+ updateStateToKeyguard()
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
+ runCurrent()
+ controller.updateCommunalAlphaTransition(transitionAlphaAmount)
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Blank)
+ runCurrent()
+ Truth.assertThat(keyguardStatusBarView.getAlpha()).isNotEqualTo(transitionAlphaAmount)
+ }
+
/**
* Calls [com.android.keyguard.KeyguardUpdateMonitorCallback.onFinishedGoingToSleep] to ensure
* values are updated properly.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
index 67b009e50ce0..7f3ef61d02c0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
@@ -54,9 +54,7 @@ constructor(
duration = TO_LOCKSCREEN_DURATION,
edge = Edge.create(from = Scenes.Communal, to = LOCKSCREEN),
)
- .setupWithoutSceneContainer(
- edge = Edge.create(from = GLANCEABLE_HUB, to = LOCKSCREEN),
- )
+ .setupWithoutSceneContainer(edge = Edge.create(from = GLANCEABLE_HUB, to = LOCKSCREEN))
val keyguardAlpha: Flow<Float> =
transitionAnimation.sharedFlow(
@@ -75,7 +73,7 @@ constructor(
configurationInteractor
.directionalDimensionPixelSize(
LayoutDirection.LTR,
- R.dimen.hub_to_lockscreen_transition_lockscreen_translation_x
+ R.dimen.hub_to_lockscreen_transition_lockscreen_translation_x,
)
.flatMapLatest { translatePx: Int ->
transitionAnimation.sharedFlowWithState(
@@ -87,7 +85,7 @@ constructor(
// is cancelled.
onFinish = { 0f },
onCancel = { 0f },
- name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardTranslationX"
+ name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardTranslationX",
)
}
@@ -95,6 +93,8 @@ constructor(
val shortcutsAlpha: Flow<Float> = keyguardAlpha
+ val statusBarAlpha: Flow<Float> = keyguardAlpha
+
val notificationTranslationX: Flow<Float> =
keyguardTranslationX.map { it.value }.filterNotNull()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
index 378374e72c8b..dd8ff8c4a052 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
@@ -54,9 +54,7 @@ constructor(
duration = FromLockscreenTransitionInteractor.TO_GLANCEABLE_HUB_DURATION,
edge = Edge.create(from = LOCKSCREEN, to = Scenes.Communal),
)
- .setupWithoutSceneContainer(
- edge = Edge.create(from = LOCKSCREEN, to = GLANCEABLE_HUB),
- )
+ .setupWithoutSceneContainer(edge = Edge.create(from = LOCKSCREEN, to = GLANCEABLE_HUB))
val keyguardAlpha: Flow<Float> =
transitionAnimation.sharedFlow(
@@ -74,7 +72,7 @@ constructor(
configurationInteractor
.directionalDimensionPixelSize(
LayoutDirection.LTR,
- R.dimen.lockscreen_to_hub_transition_lockscreen_translation_x
+ R.dimen.lockscreen_to_hub_transition_lockscreen_translation_x,
)
.flatMapLatest { translatePx: Int ->
transitionAnimation.sharedFlowWithState(
@@ -86,7 +84,7 @@ constructor(
onFinish = { 0f },
onCancel = { 0f },
interpolator = EMPHASIZED,
- name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardTranslationX"
+ name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardTranslationX",
)
}
@@ -94,6 +92,8 @@ constructor(
val shortcutsAlpha: Flow<Float> = keyguardAlpha
+ val statusBarAlpha: Flow<Float> = keyguardAlpha
+
val notificationTranslationX: Flow<Float> =
keyguardTranslationX.map { it.value }.filterNotNull()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index be2fb68ab88d..2433b78fc183 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -50,6 +50,8 @@ import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToLockscreenTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToGlanceableHubTransitionViewModel;
import com.android.systemui.log.core.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
@@ -82,6 +84,8 @@ import com.android.systemui.util.settings.SecureSettings;
import kotlin.Unit;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -108,6 +112,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
R.id.keyguard_hun_animator_end_tag,
R.id.keyguard_hun_animator_start_tag);
+ private final CoroutineDispatcher mCoroutineDispatcher;
private final CarrierTextController mCarrierTextController;
private final ConfigurationController mConfigurationController;
private final SystemStatusAnimationScheduler mAnimationScheduler;
@@ -133,6 +138,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private final Object mLock = new Object();
private final KeyguardLogger mLogger;
private final CommunalSceneInteractor mCommunalSceneInteractor;
+ private final GlanceableHubToLockscreenTransitionViewModel mHubToLockscreenTransitionViewModel;
+ private final LockscreenToGlanceableHubTransitionViewModel mLockscreenToHubTransitionViewModel;
private View mSystemIconsContainer;
private final StatusOverlayHoverListenerFactory mStatusOverlayHoverListenerFactory;
@@ -249,9 +256,20 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private boolean mCommunalShowing;
private final Consumer<Boolean> mCommunalConsumer = (communalShowing) -> {
+ updateCommunalShowing(communalShowing);
+ };
+
+ @VisibleForTesting
+ void updateCommunalShowing(boolean communalShowing) {
mCommunalShowing = communalShowing;
+
+ // When communal is hidden (either by transition or state change), set alpha to fully
+ // visible.
+ if (!mCommunalShowing) {
+ setAlpha(-1f);
+ }
updateViewState();
- };
+ }
private final DisableStateTracker mDisableStateTracker;
@@ -277,6 +295,15 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private boolean mShowingKeyguardHeadsUp;
private StatusBarSystemEventDefaultAnimator mSystemEventAnimator;
private float mSystemEventAnimatorAlpha = 1;
+ private final Consumer<Float> mToGlanceableHubStatusBarAlphaConsumer = (alpha) ->
+ updateCommunalAlphaTransition(alpha);
+
+ private final Consumer<Float> mFromGlanceableHubStatusBarAlphaConsumer = (alpha) ->
+ updateCommunalAlphaTransition(alpha);
+
+ @VisibleForTesting void updateCommunalAlphaTransition(float alpha) {
+ setAlpha(!mCommunalShowing || alpha == 0 ? -1 : alpha);
+ }
/**
* The alpha value to be set on the View. If -1, this value is to be ignored.
@@ -285,6 +312,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
@Inject
public KeyguardStatusBarViewController(
+ @Main CoroutineDispatcher dispatcher,
KeyguardStatusBarView view,
CarrierTextController carrierTextController,
ConfigurationController configurationController,
@@ -310,9 +338,14 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
@Background Executor backgroundExecutor,
KeyguardLogger logger,
StatusOverlayHoverListenerFactory statusOverlayHoverListenerFactory,
- CommunalSceneInteractor communalSceneInteractor
+ CommunalSceneInteractor communalSceneInteractor,
+ GlanceableHubToLockscreenTransitionViewModel
+ glanceableHubToLockscreenTransitionViewModel,
+ LockscreenToGlanceableHubTransitionViewModel
+ lockscreenToGlanceableHubTransitionViewModel
) {
super(view);
+ mCoroutineDispatcher = dispatcher;
mCarrierTextController = carrierTextController;
mConfigurationController = configurationController;
mAnimationScheduler = animationScheduler;
@@ -337,6 +370,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
mBackgroundExecutor = backgroundExecutor;
mLogger = logger;
mCommunalSceneInteractor = communalSceneInteractor;
+ mHubToLockscreenTransitionViewModel = glanceableHubToLockscreenTransitionViewModel;
+ mLockscreenToHubTransitionViewModel = lockscreenToGlanceableHubTransitionViewModel;
mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled();
mKeyguardStateController.addCallback(
@@ -418,7 +453,12 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
UserHandle.USER_ALL);
updateUserSwitcher();
onThemeChanged();
- collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer);
+ collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer,
+ mCoroutineDispatcher);
+ collectFlow(mView, mLockscreenToHubTransitionViewModel.getStatusBarAlpha(),
+ mToGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
+ collectFlow(mView, mHubToLockscreenTransitionViewModel.getStatusBarAlpha(),
+ mFromGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
}
@Override
@@ -573,7 +613,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
&& !mDozing
&& !hideForBypass
&& !mDisableStateTracker.isDisabled()
- && !mCommunalShowing
+ && (!mCommunalShowing || mExplicitAlpha != -1)
? View.VISIBLE : View.INVISIBLE;
updateViewState(newAlpha, newVisibility);
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
index 3662c78efb16..163288b25b28 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
@@ -32,6 +32,7 @@ import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings
import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.logging.UiEventLogger
import com.android.internal.util.UserIcons
import com.android.keyguard.KeyguardUpdateMonitor
@@ -81,7 +82,6 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
@@ -109,7 +109,7 @@ constructor(
private val guestUserInteractor: GuestUserInteractor,
private val uiEventLogger: UiEventLogger,
private val userRestrictionChecker: UserRestrictionChecker,
- private val processWrapper: ProcessWrapper
+ private val processWrapper: ProcessWrapper,
) {
/**
* Defines interface for classes that can be notified when the state of users on the device is
@@ -137,11 +137,10 @@ constructor(
/** List of current on-device users to select from. */
val users: Flow<List<UserModel>>
get() =
- combine(
+ combine(userInfos, repository.selectedUserInfo, repository.userSwitcherSettings) {
userInfos,
- repository.selectedUserInfo,
- repository.userSwitcherSettings,
- ) { userInfos, selectedUserInfo, settings ->
+ selectedUserInfo,
+ settings ->
toUserModels(
userInfos = userInfos,
selectedUserId = selectedUserInfo.id,
@@ -157,7 +156,7 @@ constructor(
toUserModel(
userInfo = selectedUserInfo,
selectedUserId = selectedUserId,
- canSwitchUsers = canSwitchUsers(selectedUserId)
+ canSwitchUsers = canSwitchUsers(selectedUserId),
)
}
@@ -211,7 +210,7 @@ constructor(
manager,
repository,
settings.isUserSwitcherEnabled,
- canAccessUserSwitcher
+ canAccessUserSwitcher,
)
if (canCreateUsers) {
@@ -238,7 +237,7 @@ constructor(
if (
UserActionsUtil.canManageUsers(
repository,
- settings.isUserSwitcherEnabled
+ settings.isUserSwitcherEnabled,
)
) {
add(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
@@ -248,18 +247,14 @@ constructor(
.flowOn(backgroundDispatcher)
val userRecords: StateFlow<ArrayList<UserRecord>> =
- combine(
+ combine(userInfos, repository.selectedUserInfo, actions, repository.userSwitcherSettings) {
userInfos,
- repository.selectedUserInfo,
- actions,
- repository.userSwitcherSettings,
- ) { userInfos, selectedUserInfo, actionModels, settings ->
+ selectedUserInfo,
+ actionModels,
+ settings ->
ArrayList(
userInfos.map {
- toRecord(
- userInfo = it,
- selectedUserId = selectedUserInfo.id,
- )
+ toRecord(userInfo = it, selectedUserId = selectedUserInfo.id)
} +
actionModels.map {
toRecord(
@@ -298,7 +293,8 @@ constructor(
val isGuestUserResetting: Boolean = guestUserInteractor.isGuestUserResetting
/** Whether to enable the user chip in the status bar */
- val isStatusBarUserChipEnabled: Boolean = repository.isStatusBarUserChipEnabled
+ val isStatusBarUserChipEnabled: Boolean
+ get() = repository.isStatusBarUserChipEnabled
private val _dialogShowRequests = MutableStateFlow<ShowDialogRequestModel?>(null)
val dialogShowRequests: Flow<ShowDialogRequestModel?> = _dialogShowRequests.asStateFlow()
@@ -467,10 +463,8 @@ constructor(
when (action) {
UserActionModel.ENTER_GUEST_MODE -> {
uiEventLogger.log(MultiUserActionsEvent.CREATE_GUEST_FROM_USER_SWITCHER)
- guestUserInteractor.createAndSwitchTo(
- this::showDialog,
- this::dismissDialog,
- ) { userId ->
+ guestUserInteractor.createAndSwitchTo(this::showDialog, this::dismissDialog) {
+ userId ->
selectUser(userId, dialogShower)
}
}
@@ -481,7 +475,7 @@ constructor(
activityStarter.startActivity(
CreateUserActivity.createIntentForStart(
applicationContext,
- keyguardInteractor.isKeyguardShowing()
+ keyguardInteractor.isKeyguardShowing(),
),
/* dismissShade= */ true,
/* animationController */ null,
@@ -523,17 +517,14 @@ constructor(
)
}
- fun removeGuestUser(
- @UserIdInt guestUserId: Int,
- @UserIdInt targetUserId: Int,
- ) {
+ fun removeGuestUser(@UserIdInt guestUserId: Int, @UserIdInt targetUserId: Int) {
applicationScope.launch {
guestUserInteractor.remove(
guestUserId = guestUserId,
targetUserId = targetUserId,
::showDialog,
::dismissDialog,
- ::switchUser
+ ::switchUser,
)
}
}
@@ -570,10 +561,7 @@ constructor(
}
}
- private suspend fun toRecord(
- userInfo: UserInfo,
- selectedUserId: Int,
- ): UserRecord {
+ private suspend fun toRecord(userInfo: UserInfo, selectedUserId: Int): UserRecord {
return LegacyUserDataHelper.createRecord(
context = applicationContext,
manager = manager,
@@ -595,10 +583,7 @@ constructor(
actionType = action,
isRestricted = isRestricted,
isSwitchToEnabled =
- canSwitchUsers(
- selectedUserId = selectedUserId,
- isAction = true,
- ) &&
+ canSwitchUsers(selectedUserId = selectedUserId, isAction = true) &&
// If the user is auto-created is must not be currently resetting.
!(isGuestUserAutoCreated && isGuestUserResetting),
userRestrictionChecker = userRestrictionChecker,
@@ -623,10 +608,7 @@ constructor(
}
}
- private suspend fun onBroadcastReceived(
- intent: Intent,
- previousUserInfo: UserInfo?,
- ) {
+ private suspend fun onBroadcastReceived(intent: Intent, previousUserInfo: UserInfo?) {
val shouldRefreshAllUsers =
when (intent.action) {
Intent.ACTION_LOCALE_CHANGED -> true
@@ -645,10 +627,8 @@ constructor(
Intent.ACTION_USER_INFO_CHANGED -> true
Intent.ACTION_USER_UNLOCKED -> {
// If we unlocked the system user, we should refresh all users.
- intent.getIntExtra(
- Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL,
- ) == UserHandle.USER_SYSTEM
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) ==
+ UserHandle.USER_SYSTEM
}
else -> true
}
@@ -668,20 +648,14 @@ constructor(
// Disconnect from the old secondary user's service
val secondaryUserId = repository.secondaryUserId
if (secondaryUserId != UserHandle.USER_NULL) {
- applicationContext.stopServiceAsUser(
- intent,
- UserHandle.of(secondaryUserId),
- )
+ applicationContext.stopServiceAsUser(intent, UserHandle.of(secondaryUserId))
repository.secondaryUserId = UserHandle.USER_NULL
}
// Connect to the new secondary user's service (purely to ensure that a persistent
// SystemUI application is created for that user)
if (userId != processWrapper.myUserHandle().identifier && !processWrapper.isSystemUser) {
- applicationContext.startServiceAsUser(
- intent,
- UserHandle.of(userId),
- )
+ applicationContext.startServiceAsUser(intent, UserHandle.of(userId))
repository.secondaryUserId = userId
}
}
@@ -732,7 +706,7 @@ constructor(
private suspend fun toUserModel(
userInfo: UserInfo,
selectedUserId: Int,
- canSwitchUsers: Boolean
+ canSwitchUsers: Boolean,
): UserModel {
val userId = userInfo.id
val isSelected = userId == selectedUserId
@@ -740,11 +714,7 @@ constructor(
UserModel(
id = userId,
name = Text.Loaded(userInfo.name),
- image =
- getUserImage(
- isGuest = true,
- userId = userId,
- ),
+ image = getUserImage(isGuest = true, userId = userId),
isSelected = isSelected,
isSelectable = canSwitchUsers,
isGuest = true,
@@ -753,11 +723,7 @@ constructor(
UserModel(
id = userId,
name = Text.Loaded(userInfo.name),
- image =
- getUserImage(
- isGuest = false,
- userId = userId,
- ),
+ image = getUserImage(isGuest = false, userId = userId),
isSelected = isSelected,
isSelectable = canSwitchUsers || isSelected,
isGuest = false,
@@ -765,10 +731,7 @@ constructor(
}
}
- private suspend fun canSwitchUsers(
- selectedUserId: Int,
- isAction: Boolean = false,
- ): Boolean {
+ private suspend fun canSwitchUsers(selectedUserId: Int, isAction: Boolean = false): Boolean {
val isHeadlessSystemUserMode =
withContext(backgroundDispatcher) { headlessSystemUserMode.isHeadlessSystemUserMode() }
// Whether menu item should be active. True if item is a user or if any user has
@@ -785,7 +748,7 @@ constructor(
.getUsers(
/* excludePartial= */ true,
/* excludeDying= */ true,
- /* excludePreCreated= */ true
+ /* excludePreCreated= */ true,
)
.any { user ->
user.id != UserHandle.USER_SYSTEM &&
@@ -794,10 +757,7 @@ constructor(
}
@SuppressLint("UseCompatLoadingForDrawables")
- private suspend fun getUserImage(
- isGuest: Boolean,
- userId: Int,
- ): Drawable {
+ private suspend fun getUserImage(isGuest: Boolean, userId: Int): Drawable {
if (isGuest) {
return checkNotNull(
applicationContext.getDrawable(com.android.settingslib.R.drawable.ic_account_circle)
@@ -823,13 +783,13 @@ constructor(
return UserIcons.getDefaultUserIcon(
applicationContext.resources,
userId,
- /* light= */ false
+ /* light= */ false,
)
}
private fun canCreateGuestUser(
settings: UserSwitcherSettingsModel,
- canAccessUserSwitcher: Boolean
+ canAccessUserSwitcher: Boolean,
): Boolean {
return guestUserInteractor.isGuestUserAutoCreated ||
UserActionsUtil.canCreateGuest(
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModel.kt
index 2c425b199b4e..53c2d888922b 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModel.kt
@@ -30,11 +30,10 @@ import kotlinx.coroutines.flow.mapLatest
@OptIn(ExperimentalCoroutinesApi::class)
class StatusBarUserChipViewModel
@Inject
-constructor(
- interactor: UserSwitcherInteractor,
-) {
+constructor(private val interactor: UserSwitcherInteractor) {
/** Whether the status bar chip ui should be available */
- val chipEnabled: Boolean = interactor.isStatusBarUserChipEnabled
+ val chipEnabled: Boolean
+ get() = interactor.isStatusBarUserChipEnabled
/** Whether or not the chip should be showing, based on the number of users */
val isChipVisible: Flow<Boolean> =
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 5eaa198fb2a6..a3cdcd20e93b 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
@@ -51,6 +51,8 @@ import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.pulseExpansionInteractor
+import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.model.sceneContainerPlugin
import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.power.data.repository.fakePowerRepository
@@ -164,4 +166,11 @@ class KosmosJavaAdapter() {
val msdlPlayer by lazy { kosmos.fakeMSDLPlayer }
val shadeModeInteractor by lazy { kosmos.shadeModeInteractor }
val bouncerHapticHelper by lazy { kosmos.bouncerHapticPlayer }
+
+ val glanceableHubToLockscreenTransitionViewModel by lazy {
+ kosmos.glanceableHubToLockscreenTransitionViewModel
+ }
+ val lockscreenToGlanceableHubTransitionViewModel by lazy {
+ kosmos.lockscreenToGlanceableHubTransitionViewModel
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/StatusBarUserChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/StatusBarUserChipViewModelKosmos.kt
new file mode 100644
index 000000000000..01175a568b3a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/StatusBarUserChipViewModelKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.user.domain.interactor.userSwitcherInteractor
+import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel
+
+val Kosmos.statusBarUserChipViewModel: StatusBarUserChipViewModel by
+ Kosmos.Fixture { StatusBarUserChipViewModel(userSwitcherInteractor) }