From c8b2a14bbfde2b3366fd0709fac5834a20065139 Mon Sep 17 00:00:00 2001 From: Alejandro Nijamkin Date: Tue, 3 Oct 2023 15:09:55 -0700 Subject: [flexiglass] Foldable UI support for bouncer. A small tweak to get the foldable UI just right. Because the user switcher UI shouldn't be available on non-tablet devices like foldables, the presentation logic in the composable is slightly changed. Note that for the unfolded + landscape case we do want to use the side-by-side layout, but we want an empty placeholder instead of the user switcher. Fix: 299343639 Test: manually tested folded, unfolded + landscape, unfolded + portrait on foldable device with pattern unlock Test: manually tested tablet device in landscape and portrait, also with pattern unlock Change-Id: Ibe9611209ea9b2b4f03ecf72db72e7dbab88a072 --- .../systemui/bouncer/ui/composable/BouncerScene.kt | 32 ++++++++++++++-------- .../bouncer/data/repository/BouncerRepository.kt | 11 +++++++- .../bouncer/domain/interactor/BouncerInteractor.kt | 3 ++ .../bouncer/ui/viewmodel/BouncerViewModel.kt | 2 ++ .../com/android/systemui/scene/SceneTestUtils.kt | 8 ++++-- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt index a9944f739975..f2b7b3290f96 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt @@ -144,15 +144,17 @@ private fun SceneScope.BouncerScene( } val childModifier = Modifier.element(Bouncer.Elements.Content).fillMaxSize() + val isFullScreenUserSwitcherEnabled = viewModel.isUserSwitcherVisible - when (windowSizeClass.widthSizeClass) { - WindowWidthSizeClass.Expanded -> + when { + windowSizeClass.widthSizeClass == WindowWidthSizeClass.Expanded -> SideBySide( viewModel = viewModel, dialogFactory = dialogFactory, modifier = childModifier, ) - WindowWidthSizeClass.Medium -> + isFullScreenUserSwitcherEnabled && + windowSizeClass.widthSizeClass == WindowWidthSizeClass.Medium -> Stacked( viewModel = viewModel, dialogFactory = dialogFactory, @@ -442,14 +444,22 @@ private fun SideBySide( label = "offset", ) - UserSwitcher( - viewModel = viewModel, - modifier = - Modifier.fillMaxHeight().weight(1f).graphicsLayer { - translationX = size.width * animatedOffset - alpha = animatedAlpha(animatedOffset) - }, - ) + val userSwitcherModifier = + Modifier.fillMaxHeight().weight(1f).graphicsLayer { + translationX = size.width * animatedOffset + alpha = animatedAlpha(animatedOffset) + } + if (viewModel.isUserSwitcherVisible) { + UserSwitcher( + viewModel = viewModel, + modifier = userSwitcherModifier, + ) + } else { + Box( + modifier = userSwitcherModifier, + ) + } + Box( modifier = Modifier.fillMaxHeight().weight(1f).graphicsLayer { diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt index 943216ebd0d6..b2a7607cb323 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt @@ -17,6 +17,8 @@ package com.android.systemui.bouncer.data.repository import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -24,11 +26,18 @@ import kotlinx.coroutines.flow.asStateFlow /** Provides access to bouncer-related application state. */ @SysUISingleton -class BouncerRepository @Inject constructor() { +class BouncerRepository +@Inject +constructor( + flags: FeatureFlagsClassic, +) { private val _message = MutableStateFlow(null) /** The user-facing message to show in the bouncer. */ val message: StateFlow = _message.asStateFlow() + /** Whether the user switcher should be displayed within the bouncer UI on large screens. */ + val isUserSwitcherVisible: Boolean = flags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER) + fun setMessage(message: String?) { _message.value = message } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt index 0c0236999e39..4ce1422b91e8 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt @@ -96,6 +96,9 @@ constructor( /** Whether the pattern should be visible for the currently-selected user. */ val isPatternVisible: StateFlow = authenticationInteractor.isPatternVisible + /** Whether the user switcher should be displayed within the bouncer UI on large screens. */ + val isUserSwitcherVisible: Boolean = repository.isUserSwitcherVisible + init { if (flags.isEnabled()) { // Clear the message if moved from throttling to no-longer throttling. diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt index 2cb98d879e69..ef0609a99e05 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt @@ -99,6 +99,8 @@ class BouncerViewModel( initialValue = emptyList(), ) + val isUserSwitcherVisible: Boolean = bouncerInteractor.isUserSwitcherVisible + private val isInputEnabled: StateFlow = bouncerInteractor.isThrottled .map { !it } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index f01f3c7aedb3..84587609e2ef 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -82,7 +82,11 @@ class SceneTestUtils( ) { val testDispatcher = StandardTestDispatcher() val testScope = TestScope(testDispatcher) - val featureFlags = FakeFeatureFlagsClassic().apply { set(Flags.FACE_AUTH_REFACTOR, false) } + val featureFlags = + FakeFeatureFlagsClassic().apply { + set(Flags.FACE_AUTH_REFACTOR, false) + set(Flags.FULL_SCREEN_USER_SWITCHER, false) + } val sceneContainerFlags = FakeSceneContainerFlags().apply { enabled = true } val deviceEntryRepository: FakeDeviceEntryRepository by lazy { FakeDeviceEntryRepository() } val authenticationRepository: FakeAuthenticationRepository by lazy { @@ -215,7 +219,7 @@ class SceneTestUtils( return BouncerInteractor( applicationScope = applicationScope(), applicationContext = context, - repository = BouncerRepository(), + repository = BouncerRepository(featureFlags), deviceEntryInteractor = deviceEntryInteractor, authenticationInteractor = authenticationInteractor, sceneInteractor = sceneInteractor, -- cgit v1.2.3-59-g8ed1b