Loading packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +134 −12 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer Loading @@ -44,6 +45,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Widgets import androidx.compose.material3.Button import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults Loading @@ -51,6 +53,7 @@ import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable Loading @@ -71,6 +74,7 @@ import androidx.compose.ui.layout.positionInWindow import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection Loading Loading @@ -111,7 +115,8 @@ fun CommunalHub( isDraggingToRemove = checkForDraggingToRemove(it, removeButtonCoordinates, gridCoordinates) isDraggingToRemove } }, onOpenWidgetPicker = onOpenWidgetPicker, ) if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) { Loading Loading @@ -148,13 +153,14 @@ private fun BoxScope.CommunalHubLazyGrid( contentPadding: PaddingValues, setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit, updateDragPositionForRemove: (offset: Offset) -> Boolean, onOpenWidgetPicker: (() -> Unit)? = null, ) { var gridModifier = Modifier.align(Alignment.CenterStart) val gridState = rememberLazyGridState() var list = communalContent var dragDropState: GridDragDropState? = null if (viewModel.isEditMode && viewModel is CommunalEditModeViewModel) { val contentListState = rememberContentListState(communalContent, viewModel) val contentListState = rememberContentListState(list, viewModel) list = contentListState.list // for drag & drop operations within the communal hub grid dragDropState = Loading Loading @@ -207,7 +213,7 @@ private fun BoxScope.CommunalHubLazyGrid( if (viewModel.isEditMode && dragDropState != null) { DraggableItem( dragDropState = dragDropState, enabled = true, enabled = list[index] is CommunalContentModel.Widget, index = index, size = size ) { _ -> Loading @@ -216,6 +222,7 @@ private fun BoxScope.CommunalHubLazyGrid( model = list[index], viewModel = viewModel, size = size, onOpenWidgetPicker = onOpenWidgetPicker, ) } } else { Loading Loading @@ -256,16 +263,11 @@ private fun Toolbar( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { val buttonContentPadding = PaddingValues( vertical = Dimensions.ToolbarButtonPaddingVertical, horizontal = Dimensions.ToolbarButtonPaddingHorizontal, ) val spacerModifier = Modifier.width(Dimensions.ToolbarButtonSpaceBetween) Button( onClick = onOpenWidgetPicker, colors = filledButtonColors(), contentPadding = buttonContentPadding contentPadding = Dimensions.ButtonPadding ) { Icon(Icons.Default.Add, stringResource(R.string.button_to_open_widget_editor)) Spacer(spacerModifier) Loading @@ -285,7 +287,7 @@ private fun Toolbar( disabledContainerColor = colors.primary, disabledContentColor = colors.onPrimary, ), contentPadding = buttonContentPadding, contentPadding = Dimensions.ButtonPadding, modifier = Modifier.onGloballyPositioned { setRemoveButtonCoordinates(it) } ) { RemoveButtonContent(spacerModifier) Loading @@ -297,7 +299,7 @@ private fun Toolbar( onClick = {}, colors = ButtonDefaults.outlinedButtonColors(disabledContentColor = colors.primary), border = BorderStroke(width = 1.0.dp, color = colors.primary), contentPadding = buttonContentPadding, contentPadding = Dimensions.ButtonPadding, modifier = Modifier.onGloballyPositioned { setRemoveButtonCoordinates(it) } ) { RemoveButtonContent(spacerModifier) Loading @@ -307,7 +309,7 @@ private fun Toolbar( Button( onClick = onEditDone, colors = filledButtonColors(), contentPadding = buttonContentPadding contentPadding = Dimensions.ButtonPadding ) { Text( text = stringResource(R.string.hub_mode_editing_exit_button_text), Loading Loading @@ -340,10 +342,15 @@ private fun CommunalContent( viewModel: BaseCommunalViewModel, size: SizeF, modifier: Modifier = Modifier, onOpenWidgetPicker: (() -> Unit)? = null, ) { when (model) { is CommunalContentModel.Widget -> WidgetContent(viewModel, model, size, modifier) is CommunalContentModel.WidgetPlaceholder -> WidgetPlaceholderContent(size) is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, size, modifier) is CommunalContentModel.CtaTileInEditMode -> CtaTileInEditModeContent(size, modifier, onOpenWidgetPicker) is CommunalContentModel.Smartspace -> SmartspaceContent(model, modifier) is CommunalContentModel.Tutorial -> TutorialContent(modifier) is CommunalContentModel.Umo -> Umo(viewModel, modifier) Loading @@ -361,6 +368,115 @@ fun WidgetPlaceholderContent(size: SizeF) { ) {} } /** Presents a CTA tile at the end of the grid, to customize the hub. */ @Composable private fun CtaTileInViewModeContent( viewModel: BaseCommunalViewModel, size: SizeF, modifier: Modifier = Modifier, ) { val colors = LocalAndroidColorScheme.current Card( modifier = modifier.height(size.height.dp), colors = CardDefaults.cardColors( containerColor = colors.primary, contentColor = colors.onPrimary, ), shape = RoundedCornerShape(80.dp, 40.dp, 80.dp, 40.dp) ) { Column( modifier = Modifier.fillMaxSize().padding(horizontal = 82.dp), verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = Icons.Outlined.Widgets, contentDescription = stringResource(R.string.cta_label_to_open_widget_picker), modifier = Modifier.size(Dimensions.IconSize), ) Text( text = stringResource(R.string.cta_label_to_edit_widget), style = MaterialTheme.typography.titleLarge, textAlign = TextAlign.Center, ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, ) { OutlinedButton( colors = ButtonDefaults.buttonColors( contentColor = colors.onPrimary, ), border = BorderStroke(width = 1.0.dp, color = colors.primaryContainer), contentPadding = Dimensions.ButtonPadding, onClick = viewModel::onDismissCtaTile, ) { Text( text = stringResource(R.string.cta_tile_button_to_dismiss), ) } Spacer(modifier = Modifier.size(Dimensions.Spacing)) Button( colors = ButtonDefaults.buttonColors( containerColor = colors.primaryContainer, contentColor = colors.onPrimaryContainer, ), contentPadding = Dimensions.ButtonPadding, onClick = viewModel::onOpenWidgetEditor ) { Text( text = stringResource(R.string.cta_tile_button_to_open_widget_editor), ) } } } } } /** Presents a CTA tile at the end of the hub in edit mode, to add more widgets. */ @Composable private fun CtaTileInEditModeContent( size: SizeF, modifier: Modifier = Modifier, onOpenWidgetPicker: (() -> Unit)? = null, ) { if (onOpenWidgetPicker == null) { throw IllegalArgumentException("onOpenWidgetPicker should not be null.") } val colors = LocalAndroidColorScheme.current Card( modifier = modifier.height(size.height.dp), colors = CardDefaults.cardColors(containerColor = Color.Transparent), border = BorderStroke(1.dp, colors.primary), shape = RoundedCornerShape(200.dp), onClick = onOpenWidgetPicker, ) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = Icons.Outlined.Widgets, contentDescription = stringResource(R.string.cta_label_to_open_widget_picker), tint = colors.primary, modifier = Modifier.size(Dimensions.IconSize), ) Text( text = stringResource(R.string.cta_label_to_open_widget_picker), style = MaterialTheme.typography.titleLarge, color = colors.primary, textAlign = TextAlign.Center, ) } } } @Composable private fun WidgetContent( viewModel: BaseCommunalViewModel, Loading Loading @@ -513,4 +629,10 @@ object Dimensions { val ToolbarButtonPaddingHorizontal = 24.dp val ToolbarButtonPaddingVertical = 16.dp val ToolbarButtonSpaceBetween = 8.dp val ButtonPadding = PaddingValues( vertical = ToolbarButtonPaddingVertical, horizontal = ToolbarButtonPaddingHorizontal, ) val IconSize = 48.dp } packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +26 −0 Original line number Diff line number Diff line Loading @@ -326,6 +326,32 @@ class CommunalInteractorTest : SysuiTestCase() { assertThat(ongoingContent?.get(3)?.size).isEqualTo(CommunalContentSize.THIRD) } @Test fun cta_visibilityTrue_shows() = testScope.runTest { tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) communalRepository.setCtaTileInViewModeVisibility(true) val ctaTileContent by collectLastValue(underTest.ctaTileContent) assertThat(ctaTileContent?.size).isEqualTo(1) assertThat(ctaTileContent?.get(0)) .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java) assertThat(ctaTileContent?.get(0)?.key) .isEqualTo(CommunalContentModel.KEY.CTA_TILE_IN_VIEW_MODE_KEY) } @Test fun ctaTile_visibilityFalse_doesNotShow() = testScope.runTest { tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) communalRepository.setCtaTileInViewModeVisibility(false) val ctaTileContent by collectLastValue(underTest.ctaTileContent) assertThat(ctaTileContent).isEmpty() } @Test fun listensToSceneChange() = testScope.runTest { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { } @Test fun communalContent_onlyWidgetsAreShownInEditMode() = fun communalContent_onlyWidgetsAndCtaTileAreShownInEditMode() = testScope.runTest { tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) Loading Loading @@ -123,12 +123,14 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { val communalContent by collectLastValue(underTest.communalContent) // Only Widgets are shown. assertThat(communalContent?.size).isEqualTo(2) // Only Widgets and CTA tile are shown. assertThat(communalContent?.size).isEqualTo(3) assertThat(communalContent?.get(0)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(1)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(2)) .isInstanceOf(CommunalContentModel.CtaTileInEditMode::class.java) } @Test Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt +8 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ class CommunalViewModelTest : SysuiTestCase() { } @Test fun ordering_smartspaceBeforeUmoBeforeWidgets() = fun ordering_smartspaceBeforeUmoBeforeWidgetsBeforeCtaTile() = testScope.runTest { tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) Loading Loading @@ -142,10 +142,13 @@ class CommunalViewModelTest : SysuiTestCase() { // Media playing. mediaRepository.mediaActive() // CTA Tile not dismissed. communalRepository.setCtaTileInViewModeVisibility(true) val communalContent by collectLastValue(underTest.communalContent) // Order is smart space, then UMO, then widget content. assertThat(communalContent?.size).isEqualTo(4) // Order is smart space, then UMO, widget content and cta tile. assertThat(communalContent?.size).isEqualTo(5) assertThat(communalContent?.get(0)) .isInstanceOf(CommunalContentModel.Smartspace::class.java) assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java) Loading @@ -153,5 +156,7 @@ class CommunalViewModelTest : SysuiTestCase() { .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(3)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(4)) .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java) } } packages/SystemUI/res/values/strings.xml +8 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,14 @@ <!-- Description for the button that opens the widget editor on click. [CHAR LIMIT=50] --> <string name="button_to_open_widget_editor">Open the widget editor</string> <!-- Text for CTA button that launches the hub mode widget editor on click. [CHAR LIMIT=50] --> <string name="cta_tile_button_to_open_widget_editor">Customize</string> <!-- Text for CTA button that dismisses the tile on click. [CHAR LIMIT=50] --> <string name="cta_tile_button_to_dismiss">Dismiss</string> <!-- Label for CTA tile to edit the glanceable hub [CHAR LIMIT=100] --> <string name="cta_label_to_edit_widget">Add, remove, and reorder your widgets in this space</string> <!-- Label for CTA tile that opens widget picker on click in edit mode [CHAR LIMIT=50] --> <string name="cta_label_to_open_widget_picker">Add more widgets</string> <!-- Description for the button that removes a widget on click. [CHAR LIMIT=50] --> <string name="button_to_remove_widget">Remove</string> <!-- Text for the button that launches the hub mode widget picker. [CHAR LIMIT=50] --> Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +134 −12 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer Loading @@ -44,6 +45,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Widgets import androidx.compose.material3.Button import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults Loading @@ -51,6 +53,7 @@ import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable Loading @@ -71,6 +74,7 @@ import androidx.compose.ui.layout.positionInWindow import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection Loading Loading @@ -111,7 +115,8 @@ fun CommunalHub( isDraggingToRemove = checkForDraggingToRemove(it, removeButtonCoordinates, gridCoordinates) isDraggingToRemove } }, onOpenWidgetPicker = onOpenWidgetPicker, ) if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) { Loading Loading @@ -148,13 +153,14 @@ private fun BoxScope.CommunalHubLazyGrid( contentPadding: PaddingValues, setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit, updateDragPositionForRemove: (offset: Offset) -> Boolean, onOpenWidgetPicker: (() -> Unit)? = null, ) { var gridModifier = Modifier.align(Alignment.CenterStart) val gridState = rememberLazyGridState() var list = communalContent var dragDropState: GridDragDropState? = null if (viewModel.isEditMode && viewModel is CommunalEditModeViewModel) { val contentListState = rememberContentListState(communalContent, viewModel) val contentListState = rememberContentListState(list, viewModel) list = contentListState.list // for drag & drop operations within the communal hub grid dragDropState = Loading Loading @@ -207,7 +213,7 @@ private fun BoxScope.CommunalHubLazyGrid( if (viewModel.isEditMode && dragDropState != null) { DraggableItem( dragDropState = dragDropState, enabled = true, enabled = list[index] is CommunalContentModel.Widget, index = index, size = size ) { _ -> Loading @@ -216,6 +222,7 @@ private fun BoxScope.CommunalHubLazyGrid( model = list[index], viewModel = viewModel, size = size, onOpenWidgetPicker = onOpenWidgetPicker, ) } } else { Loading Loading @@ -256,16 +263,11 @@ private fun Toolbar( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { val buttonContentPadding = PaddingValues( vertical = Dimensions.ToolbarButtonPaddingVertical, horizontal = Dimensions.ToolbarButtonPaddingHorizontal, ) val spacerModifier = Modifier.width(Dimensions.ToolbarButtonSpaceBetween) Button( onClick = onOpenWidgetPicker, colors = filledButtonColors(), contentPadding = buttonContentPadding contentPadding = Dimensions.ButtonPadding ) { Icon(Icons.Default.Add, stringResource(R.string.button_to_open_widget_editor)) Spacer(spacerModifier) Loading @@ -285,7 +287,7 @@ private fun Toolbar( disabledContainerColor = colors.primary, disabledContentColor = colors.onPrimary, ), contentPadding = buttonContentPadding, contentPadding = Dimensions.ButtonPadding, modifier = Modifier.onGloballyPositioned { setRemoveButtonCoordinates(it) } ) { RemoveButtonContent(spacerModifier) Loading @@ -297,7 +299,7 @@ private fun Toolbar( onClick = {}, colors = ButtonDefaults.outlinedButtonColors(disabledContentColor = colors.primary), border = BorderStroke(width = 1.0.dp, color = colors.primary), contentPadding = buttonContentPadding, contentPadding = Dimensions.ButtonPadding, modifier = Modifier.onGloballyPositioned { setRemoveButtonCoordinates(it) } ) { RemoveButtonContent(spacerModifier) Loading @@ -307,7 +309,7 @@ private fun Toolbar( Button( onClick = onEditDone, colors = filledButtonColors(), contentPadding = buttonContentPadding contentPadding = Dimensions.ButtonPadding ) { Text( text = stringResource(R.string.hub_mode_editing_exit_button_text), Loading Loading @@ -340,10 +342,15 @@ private fun CommunalContent( viewModel: BaseCommunalViewModel, size: SizeF, modifier: Modifier = Modifier, onOpenWidgetPicker: (() -> Unit)? = null, ) { when (model) { is CommunalContentModel.Widget -> WidgetContent(viewModel, model, size, modifier) is CommunalContentModel.WidgetPlaceholder -> WidgetPlaceholderContent(size) is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, size, modifier) is CommunalContentModel.CtaTileInEditMode -> CtaTileInEditModeContent(size, modifier, onOpenWidgetPicker) is CommunalContentModel.Smartspace -> SmartspaceContent(model, modifier) is CommunalContentModel.Tutorial -> TutorialContent(modifier) is CommunalContentModel.Umo -> Umo(viewModel, modifier) Loading @@ -361,6 +368,115 @@ fun WidgetPlaceholderContent(size: SizeF) { ) {} } /** Presents a CTA tile at the end of the grid, to customize the hub. */ @Composable private fun CtaTileInViewModeContent( viewModel: BaseCommunalViewModel, size: SizeF, modifier: Modifier = Modifier, ) { val colors = LocalAndroidColorScheme.current Card( modifier = modifier.height(size.height.dp), colors = CardDefaults.cardColors( containerColor = colors.primary, contentColor = colors.onPrimary, ), shape = RoundedCornerShape(80.dp, 40.dp, 80.dp, 40.dp) ) { Column( modifier = Modifier.fillMaxSize().padding(horizontal = 82.dp), verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = Icons.Outlined.Widgets, contentDescription = stringResource(R.string.cta_label_to_open_widget_picker), modifier = Modifier.size(Dimensions.IconSize), ) Text( text = stringResource(R.string.cta_label_to_edit_widget), style = MaterialTheme.typography.titleLarge, textAlign = TextAlign.Center, ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, ) { OutlinedButton( colors = ButtonDefaults.buttonColors( contentColor = colors.onPrimary, ), border = BorderStroke(width = 1.0.dp, color = colors.primaryContainer), contentPadding = Dimensions.ButtonPadding, onClick = viewModel::onDismissCtaTile, ) { Text( text = stringResource(R.string.cta_tile_button_to_dismiss), ) } Spacer(modifier = Modifier.size(Dimensions.Spacing)) Button( colors = ButtonDefaults.buttonColors( containerColor = colors.primaryContainer, contentColor = colors.onPrimaryContainer, ), contentPadding = Dimensions.ButtonPadding, onClick = viewModel::onOpenWidgetEditor ) { Text( text = stringResource(R.string.cta_tile_button_to_open_widget_editor), ) } } } } } /** Presents a CTA tile at the end of the hub in edit mode, to add more widgets. */ @Composable private fun CtaTileInEditModeContent( size: SizeF, modifier: Modifier = Modifier, onOpenWidgetPicker: (() -> Unit)? = null, ) { if (onOpenWidgetPicker == null) { throw IllegalArgumentException("onOpenWidgetPicker should not be null.") } val colors = LocalAndroidColorScheme.current Card( modifier = modifier.height(size.height.dp), colors = CardDefaults.cardColors(containerColor = Color.Transparent), border = BorderStroke(1.dp, colors.primary), shape = RoundedCornerShape(200.dp), onClick = onOpenWidgetPicker, ) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = Icons.Outlined.Widgets, contentDescription = stringResource(R.string.cta_label_to_open_widget_picker), tint = colors.primary, modifier = Modifier.size(Dimensions.IconSize), ) Text( text = stringResource(R.string.cta_label_to_open_widget_picker), style = MaterialTheme.typography.titleLarge, color = colors.primary, textAlign = TextAlign.Center, ) } } } @Composable private fun WidgetContent( viewModel: BaseCommunalViewModel, Loading Loading @@ -513,4 +629,10 @@ object Dimensions { val ToolbarButtonPaddingHorizontal = 24.dp val ToolbarButtonPaddingVertical = 16.dp val ToolbarButtonSpaceBetween = 8.dp val ButtonPadding = PaddingValues( vertical = ToolbarButtonPaddingVertical, horizontal = ToolbarButtonPaddingHorizontal, ) val IconSize = 48.dp }
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +26 −0 Original line number Diff line number Diff line Loading @@ -326,6 +326,32 @@ class CommunalInteractorTest : SysuiTestCase() { assertThat(ongoingContent?.get(3)?.size).isEqualTo(CommunalContentSize.THIRD) } @Test fun cta_visibilityTrue_shows() = testScope.runTest { tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) communalRepository.setCtaTileInViewModeVisibility(true) val ctaTileContent by collectLastValue(underTest.ctaTileContent) assertThat(ctaTileContent?.size).isEqualTo(1) assertThat(ctaTileContent?.get(0)) .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java) assertThat(ctaTileContent?.get(0)?.key) .isEqualTo(CommunalContentModel.KEY.CTA_TILE_IN_VIEW_MODE_KEY) } @Test fun ctaTile_visibilityFalse_doesNotShow() = testScope.runTest { tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) communalRepository.setCtaTileInViewModeVisibility(false) val ctaTileContent by collectLastValue(underTest.ctaTileContent) assertThat(ctaTileContent).isEmpty() } @Test fun listensToSceneChange() = testScope.runTest { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { } @Test fun communalContent_onlyWidgetsAreShownInEditMode() = fun communalContent_onlyWidgetsAndCtaTileAreShownInEditMode() = testScope.runTest { tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) Loading Loading @@ -123,12 +123,14 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { val communalContent by collectLastValue(underTest.communalContent) // Only Widgets are shown. assertThat(communalContent?.size).isEqualTo(2) // Only Widgets and CTA tile are shown. assertThat(communalContent?.size).isEqualTo(3) assertThat(communalContent?.get(0)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(1)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(2)) .isInstanceOf(CommunalContentModel.CtaTileInEditMode::class.java) } @Test Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt +8 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ class CommunalViewModelTest : SysuiTestCase() { } @Test fun ordering_smartspaceBeforeUmoBeforeWidgets() = fun ordering_smartspaceBeforeUmoBeforeWidgetsBeforeCtaTile() = testScope.runTest { tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) Loading Loading @@ -142,10 +142,13 @@ class CommunalViewModelTest : SysuiTestCase() { // Media playing. mediaRepository.mediaActive() // CTA Tile not dismissed. communalRepository.setCtaTileInViewModeVisibility(true) val communalContent by collectLastValue(underTest.communalContent) // Order is smart space, then UMO, then widget content. assertThat(communalContent?.size).isEqualTo(4) // Order is smart space, then UMO, widget content and cta tile. assertThat(communalContent?.size).isEqualTo(5) assertThat(communalContent?.get(0)) .isInstanceOf(CommunalContentModel.Smartspace::class.java) assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java) Loading @@ -153,5 +156,7 @@ class CommunalViewModelTest : SysuiTestCase() { .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(3)) .isInstanceOf(CommunalContentModel.Widget::class.java) assertThat(communalContent?.get(4)) .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java) } }
packages/SystemUI/res/values/strings.xml +8 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,14 @@ <!-- Description for the button that opens the widget editor on click. [CHAR LIMIT=50] --> <string name="button_to_open_widget_editor">Open the widget editor</string> <!-- Text for CTA button that launches the hub mode widget editor on click. [CHAR LIMIT=50] --> <string name="cta_tile_button_to_open_widget_editor">Customize</string> <!-- Text for CTA button that dismisses the tile on click. [CHAR LIMIT=50] --> <string name="cta_tile_button_to_dismiss">Dismiss</string> <!-- Label for CTA tile to edit the glanceable hub [CHAR LIMIT=100] --> <string name="cta_label_to_edit_widget">Add, remove, and reorder your widgets in this space</string> <!-- Label for CTA tile that opens widget picker on click in edit mode [CHAR LIMIT=50] --> <string name="cta_label_to_open_widget_picker">Add more widgets</string> <!-- Description for the button that removes a widget on click. [CHAR LIMIT=50] --> <string name="button_to_remove_widget">Remove</string> <!-- Text for the button that launches the hub mode widget picker. [CHAR LIMIT=50] --> Loading