summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Darrell Shi <darrellshi@google.com> 2023-10-27 08:16:08 -0700
committer Darrell Shi <darrellshi@google.com> 2023-10-30 17:27:24 -0700
commitb8a2ee16f070f4a4642833adb4811287b731dca7 (patch)
tree94027f5c81aad0d4fc532cde9b981ace046e7946
parente619e972988d960bad876ded08ec1d222fb740da (diff)
Reimplement CommunalHub with LazyHorizontalGrid
This change strips out dependency on the CommunalLayoutLib, and reimplements the UI layer with LazyHorizontalGrid. Now the Compose UI layer simply renders cards at the given size in the given order. It's up to upstream layers to decide the sizes and ordering. Test: verified that CommunalHub renders all three sizes correctly, and there is no visual delta Test: veriified that as cards are added / removed, existing cards maintain state Bug: 307942173 Fix: 307942173 Flag: ACONFIG com.android.systemui.communal_hub DEVELOPMENT Change-Id: Ie807b1f1c2e776156ce2c402f372a5bf55064655
-rw-r--r--packages/SystemUI/Android.bp1
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt147
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt15
5 files changed, 105 insertions, 77 deletions
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 17cc9f8135f4..f78811f5bb14 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -60,7 +60,6 @@ systemui_compose_java_defaults {
// except for SystemUI-core.
// Copied from compose/features/Android.bp.
static_libs: [
- "CommunalLayoutLib",
"PlatformComposeCore",
"PlatformComposeSceneTransitionLayout",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index b8fb26406801..87a8c35388fa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -4,8 +4,14 @@ import android.appwidget.AppWidgetHostView
import android.os.Bundle
import android.util.SizeF
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.material3.Card
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -13,16 +19,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.res.integerResource
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
-import com.android.systemui.communal.layout.ui.compose.CommunalGridLayout
-import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutCard
-import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutConfig
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.ui.model.CommunalContentUiModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
-import com.android.systemui.res.R
@Composable
fun CommunalHub(
@@ -34,68 +36,91 @@ fun CommunalHub(
Box(
modifier = modifier.fillMaxSize().background(Color.White),
) {
- CommunalGridLayout(
- modifier = Modifier.align(Alignment.CenterStart),
- layoutConfig =
- CommunalGridLayoutConfig(
- gridColumnSize = dimensionResource(R.dimen.communal_grid_column_size),
- gridGutter = dimensionResource(R.dimen.communal_grid_gutter_size),
- gridHeight = dimensionResource(R.dimen.communal_grid_height),
- gridColumnsPerCard = integerResource(R.integer.communal_grid_columns_per_card),
- ),
- communalCards = if (showTutorial) tutorialContent else widgetContent.map(::contentCard),
- )
+ LazyHorizontalGrid(
+ modifier = modifier.height(Dimensions.GridHeight).align(Alignment.CenterStart),
+ rows = GridCells.Fixed(CommunalContentSize.FULL.span),
+ horizontalArrangement = Arrangement.spacedBy(Dimensions.Spacing),
+ verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing),
+ ) {
+ if (showTutorial) {
+ items(
+ count = tutorialContentSizes.size,
+ // TODO(b/308148193): a more scalable solution for unique ids.
+ key = { index -> "tutorial_$index" },
+ span = { index -> GridItemSpan(tutorialContentSizes[index].span) },
+ ) { index ->
+ TutorialCard(
+ modifier =
+ Modifier.size(Dimensions.CardWidth, tutorialContentSizes[index].dp()),
+ )
+ }
+ } else {
+ items(
+ count = widgetContent.size,
+ key = { index -> widgetContent[index].id },
+ span = { index -> GridItemSpan(widgetContent[index].size.span) },
+ ) { index ->
+ val widget = widgetContent[index]
+ ContentCard(
+ modifier = Modifier.size(Dimensions.CardWidth, widget.size.dp()),
+ model = widget,
+ )
+ }
+ }
+ }
}
}
-private val tutorialContent =
- listOf(
- tutorialCard(CommunalGridLayoutCard.Size.FULL),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- )
-
-private fun tutorialCard(size: CommunalGridLayoutCard.Size): CommunalGridLayoutCard {
- return object : CommunalGridLayoutCard() {
- override val supportedSizes = listOf(size)
-
- @Composable
- override fun Content(modifier: Modifier, size: SizeF) {
- Card(modifier = modifier, content = {})
- }
- }
+// A placeholder for tutorial content.
+@Composable
+private fun TutorialCard(modifier: Modifier = Modifier) {
+ Card(modifier = modifier, content = {})
}
-private fun contentCard(model: CommunalContentUiModel): CommunalGridLayoutCard {
- return object : CommunalGridLayoutCard() {
- override val supportedSizes = listOf(convertToCardSize(model.size))
- override val priority = model.priority
+@Composable
+private fun ContentCard(
+ model: CommunalContentUiModel,
+ modifier: Modifier = Modifier,
+) {
+ AndroidView(
+ modifier = modifier,
+ factory = {
+ model.view.apply {
+ if (this is AppWidgetHostView) {
+ val size = SizeF(Dimensions.CardWidth.value, model.size.dp().value)
+ updateAppWidgetSize(Bundle.EMPTY, listOf(size))
+ }
+ }
+ },
+ )
+}
- @Composable
- override fun Content(modifier: Modifier, size: SizeF) {
- AndroidView(
- modifier = modifier,
- factory = {
- model.view.apply {
- if (this is AppWidgetHostView) {
- updateAppWidgetSize(Bundle(), listOf(size))
- }
- }
- },
- )
- }
+private fun CommunalContentSize.dp(): Dp {
+ return when (this) {
+ CommunalContentSize.FULL -> Dimensions.CardHeightFull
+ CommunalContentSize.HALF -> Dimensions.CardHeightHalf
+ CommunalContentSize.THIRD -> Dimensions.CardHeightThird
}
}
-private fun convertToCardSize(size: CommunalContentSize): CommunalGridLayoutCard.Size {
- return when (size) {
- CommunalContentSize.FULL -> CommunalGridLayoutCard.Size.FULL
- CommunalContentSize.HALF -> CommunalGridLayoutCard.Size.HALF
- CommunalContentSize.THIRD -> CommunalGridLayoutCard.Size.THIRD
- }
+// Sizes for the tutorial placeholders.
+private val tutorialContentSizes =
+ listOf(
+ CommunalContentSize.FULL,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ )
+
+private object Dimensions {
+ val CardWidth = 464.dp
+ val CardHeightFull = 630.dp
+ val CardHeightHalf = 307.dp
+ val CardHeightThird = 199.dp
+ val GridHeight = CardHeightFull
+ val Spacing = 16.dp
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
index 39a6476929ed..c903709aa2ee 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
@@ -16,14 +16,19 @@
package com.android.systemui.communal.shared.model
-/** Supported sizes for communal content in the layout grid. */
-enum class CommunalContentSize {
+/**
+ * Supported sizes for communal content in the layout grid.
+ *
+ * @param span The span of the content in a column. For example, if FULL is 6, then 3 represents
+ * HALF, 2 represents THIRD, and 1 represents SIXTH.
+ */
+enum class CommunalContentSize(val span: Int) {
/** Content takes the full height of the column. */
- FULL,
+ FULL(6),
/** Content takes half of the height of the column. */
- HALF,
+ HALF(3),
/** Content takes a third of the height of the column. */
- THIRD,
+ THIRD(2),
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
index 98060dc1dceb..b60dc2a21699 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
@@ -9,7 +9,7 @@ import com.android.systemui.communal.shared.model.CommunalContentSize
* This model stays in the UI layer.
*/
data class CommunalContentUiModel(
+ val id: String,
val view: View,
- val size: CommunalContentSize,
- val priority: Int,
+ val size: CommunalContentSize = CommunalContentSize.HALF,
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 25c64eafe255..390b580bad28 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -20,7 +20,6 @@ import android.appwidget.AppWidgetHost
import android.content.Context
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
-import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.ui.model.CommunalContentUiModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -42,16 +41,16 @@ constructor(
/** List of widgets to be displayed in the communal hub. */
val widgetContent: Flow<List<CommunalContentUiModel>> =
- communalInteractor.widgetContent.map {
- it.map {
+ communalInteractor.widgetContent.map { widgets ->
+ widgets.map Widget@{ widget ->
// TODO(b/306406256): As adding and removing widgets functionalities are
// supported, cache the host views so they're not recreated each time.
- val hostView = appWidgetHost.createView(context, it.appWidgetId, it.providerInfo)
- return@map CommunalContentUiModel(
+ val hostView =
+ appWidgetHost.createView(context, widget.appWidgetId, widget.providerInfo)
+ return@Widget CommunalContentUiModel(
+ // TODO(b/308148193): a more scalable solution for unique ids.
+ id = "widget_${widget.appWidgetId}",
view = hostView,
- priority = it.priority,
- // All widgets have HALF size.
- size = CommunalContentSize.HALF,
)
}
}