Loading packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +36 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId Loading @@ -120,6 +121,7 @@ import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset import com.android.systemui.communal.ui.compose.extensions.observeTapsWithoutConsuming import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.widgets.WidgetConfigurator import com.android.systemui.res.R import kotlinx.coroutines.launch Loading Loading @@ -222,6 +224,17 @@ fun CommunalHub( widgetConfigurator = widgetConfigurator, ) // TODO(b/326060686): Remove this once keyguard indication area can persist over hub if (viewModel is CommunalViewModel) { val isUnlocked by viewModel.deviceUnlocked.collectAsState(initial = false) LockStateIcon( modifier = Modifier.align(Alignment.BottomCenter) .padding(bottom = Dimensions.LockIconBottomPadding), isUnlocked = isUnlocked, ) } if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) { Toolbar( isDraggingToRemove = isDraggingToRemove, Loading Loading @@ -396,6 +409,26 @@ private fun BoxScope.CommunalHubLazyGrid( } } @Composable private fun LockStateIcon( isUnlocked: Boolean, modifier: Modifier = Modifier, ) { val colors = LocalAndroidColorScheme.current val resource = if (isUnlocked) { R.drawable.ic_unlocked } else { R.drawable.ic_lock } Icon( painter = painterResource(id = resource), contentDescription = null, tint = colors.onPrimaryContainer, modifier = modifier.size(Dimensions.LockIconSize), ) } /** * Toolbar that contains action buttons to * 1) open the widget picker Loading Loading @@ -955,6 +988,9 @@ object Dimensions { horizontal = ToolbarButtonPaddingHorizontal, ) val IconSize = 48.dp val LockIconSize = 52.dp val LockIconBottomPadding = 70.dp } private object Colors { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository Loading Loading @@ -113,6 +114,7 @@ class CommunalViewModelTest : SysuiTestCase() { kosmos.communalInteractor, kosmos.communalTutorialInteractor, kosmos.shadeInteractor, kosmos.deviceEntryInteractor, mediaHost, logcatLogBuffer("CommunalViewModelTest"), ) Loading packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.communal.domain.interactor.CommunalTutorialInteracto import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger import com.android.systemui.log.dagger.CommunalLog Loading @@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch /** The default view model used for showing the communal hub. */ @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class CommunalViewModel @Inject Loading @@ -54,6 +56,7 @@ constructor( private val communalInteractor: CommunalInteractor, tutorialInteractor: CommunalTutorialInteractor, shadeInteractor: ShadeInteractor, deviceEntryInteractor: DeviceEntryInteractor, @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, @CommunalLog logBuffer: LogBuffer, ) : BaseCommunalViewModel(communalInteractor, mediaHost) { Loading Loading @@ -87,6 +90,8 @@ constructor( /** Whether touches should be disabled in communal */ val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded) val deviceUnlocked: Flow<Boolean> = deviceEntryInteractor.isUnlocked init { // Initialize our media host for the UMO. This only needs to happen once and must be done // before the MediaHierarchyManager attempts to move the UMO to the hub. Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +36 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId Loading @@ -120,6 +121,7 @@ import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset import com.android.systemui.communal.ui.compose.extensions.observeTapsWithoutConsuming import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.widgets.WidgetConfigurator import com.android.systemui.res.R import kotlinx.coroutines.launch Loading Loading @@ -222,6 +224,17 @@ fun CommunalHub( widgetConfigurator = widgetConfigurator, ) // TODO(b/326060686): Remove this once keyguard indication area can persist over hub if (viewModel is CommunalViewModel) { val isUnlocked by viewModel.deviceUnlocked.collectAsState(initial = false) LockStateIcon( modifier = Modifier.align(Alignment.BottomCenter) .padding(bottom = Dimensions.LockIconBottomPadding), isUnlocked = isUnlocked, ) } if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) { Toolbar( isDraggingToRemove = isDraggingToRemove, Loading Loading @@ -396,6 +409,26 @@ private fun BoxScope.CommunalHubLazyGrid( } } @Composable private fun LockStateIcon( isUnlocked: Boolean, modifier: Modifier = Modifier, ) { val colors = LocalAndroidColorScheme.current val resource = if (isUnlocked) { R.drawable.ic_unlocked } else { R.drawable.ic_lock } Icon( painter = painterResource(id = resource), contentDescription = null, tint = colors.onPrimaryContainer, modifier = modifier.size(Dimensions.LockIconSize), ) } /** * Toolbar that contains action buttons to * 1) open the widget picker Loading Loading @@ -955,6 +988,9 @@ object Dimensions { horizontal = ToolbarButtonPaddingHorizontal, ) val IconSize = 48.dp val LockIconSize = 52.dp val LockIconBottomPadding = 70.dp } private object Colors { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository Loading Loading @@ -113,6 +114,7 @@ class CommunalViewModelTest : SysuiTestCase() { kosmos.communalInteractor, kosmos.communalTutorialInteractor, kosmos.shadeInteractor, kosmos.deviceEntryInteractor, mediaHost, logcatLogBuffer("CommunalViewModelTest"), ) Loading
packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.communal.domain.interactor.CommunalTutorialInteracto import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger import com.android.systemui.log.dagger.CommunalLog Loading @@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch /** The default view model used for showing the communal hub. */ @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class CommunalViewModel @Inject Loading @@ -54,6 +56,7 @@ constructor( private val communalInteractor: CommunalInteractor, tutorialInteractor: CommunalTutorialInteractor, shadeInteractor: ShadeInteractor, deviceEntryInteractor: DeviceEntryInteractor, @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, @CommunalLog logBuffer: LogBuffer, ) : BaseCommunalViewModel(communalInteractor, mediaHost) { Loading Loading @@ -87,6 +90,8 @@ constructor( /** Whether touches should be disabled in communal */ val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded) val deviceUnlocked: Flow<Boolean> = deviceEntryInteractor.isUnlocked init { // Initialize our media host for the UMO. This only needs to happen once and must be done // before the MediaHierarchyManager attempts to move the UMO to the hub. Loading