summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Coco Duan <cocod@google.com> 2023-11-17 13:11:38 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-11-17 13:11:38 +0000
commit2b221f88b01d04a4d314a3a79e2d81c4a9d36b1d (patch)
treef5d50af244bc899c4c040336393bb41a275ee61d
parentfcbb655570ee96ba09f76a859566f908e8b939f6 (diff)
parent3b0af20d0c9a98a9df40ecd89af847cf644e97aa (diff)
Merge changes I210d4ae0,I7076b98f into main
* changes: Edit activity for hub mode Introduce BaseCommunalViewModel
-rw-r--r--packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt14
-rw-r--r--packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt21
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt6
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt39
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt126
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt148
-rw-r--r--packages/SystemUI/res/layout/edit_widgets.xml32
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt125
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt4
17 files changed, 493 insertions, 221 deletions
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
index ddd1c67bd5fa..914e5f2c17bf 100644
--- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
+++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
@@ -22,7 +22,7 @@ import android.view.View
import android.view.WindowInsets
import androidx.activity.ComponentActivity
import androidx.lifecycle.LifecycleOwner
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.scene.shared.model.Scene
@@ -47,6 +47,14 @@ object ComposeFacade : BaseComposeFacade {
throwComposeUnavailableError()
}
+ override fun setCommunalEditWidgetActivityContent(
+ activity: ComponentActivity,
+ viewModel: BaseCommunalViewModel,
+ onOpenWidgetPicker: () -> Unit,
+ ) {
+ throwComposeUnavailableError()
+ }
+
override fun createFooterActionsView(
context: Context,
viewModel: FooterActionsViewModel,
@@ -67,12 +75,12 @@ object ComposeFacade : BaseComposeFacade {
override fun createCommunalView(
context: Context,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
): View {
throwComposeUnavailableError()
}
- override fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View {
+ override fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View {
throwComposeUnavailableError()
}
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
index eeda6c63b68f..59bd95bd9027 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
@@ -32,7 +32,7 @@ import com.android.systemui.common.ui.compose.windowinsets.DisplayCutout
import com.android.systemui.common.ui.compose.windowinsets.DisplayCutoutProvider
import com.android.systemui.communal.ui.compose.CommunalContainer
import com.android.systemui.communal.ui.compose.CommunalHub
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.people.ui.compose.PeopleScreen
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.compose.FooterActions
@@ -62,6 +62,21 @@ object ComposeFacade : BaseComposeFacade {
activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } }
}
+ override fun setCommunalEditWidgetActivityContent(
+ activity: ComponentActivity,
+ viewModel: BaseCommunalViewModel,
+ onOpenWidgetPicker: () -> Unit,
+ ) {
+ activity.setContent {
+ PlatformTheme {
+ CommunalHub(
+ viewModel = viewModel,
+ onOpenWidgetPicker = onOpenWidgetPicker,
+ )
+ }
+ }
+ }
+
override fun createFooterActionsView(
context: Context,
viewModel: FooterActionsViewModel,
@@ -98,14 +113,14 @@ object ComposeFacade : BaseComposeFacade {
override fun createCommunalView(
context: Context,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
): View {
return ComposeView(context).apply {
setContent { PlatformTheme { CommunalHub(viewModel = viewModel) } }
}
}
- override fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View {
+ override fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View {
return ComposeView(context).apply {
setContent { PlatformTheme { CommunalContainer(viewModel = viewModel) } }
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 09706bed1921..ce84c19a53ee 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -32,7 +32,7 @@ import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.transitions
import com.android.systemui.communal.shared.model.CommunalSceneKey
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import kotlinx.coroutines.flow.transform
object Communal {
@@ -59,7 +59,7 @@ val sceneTransitions = transitions {
@Composable
fun CommunalContainer(
modifier: Modifier = Modifier,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
) {
val currentScene: SceneKey by
viewModel.currentScene
@@ -129,7 +129,7 @@ private fun BlankScene(
/** Scene containing the glanceable hub UI. */
@Composable
private fun SceneScope.CommunalScene(
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
modifier: Modifier = Modifier,
) {
Box(modifier.element(Communal.Elements.Content)) { CommunalHub(viewModel = viewModel) }
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 d822d1996eff..2ba1b77fb76e 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
@@ -34,6 +34,7 @@ import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Close
+import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -51,7 +52,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalContentSize
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.media.controls.ui.MediaHierarchyManager
import com.android.systemui.media.controls.ui.MediaHostState
import com.android.systemui.res.R
@@ -59,7 +60,8 @@ import com.android.systemui.res.R
@Composable
fun CommunalHub(
modifier: Modifier = Modifier,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
+ onOpenWidgetPicker: (() -> Unit)? = null,
) {
val communalContent by viewModel.communalContent.collectAsState(initial = emptyList())
Box(
@@ -81,7 +83,7 @@ fun CommunalHub(
modifier = Modifier.fillMaxHeight().width(Dimensions.CardWidth),
model = communalContent[index],
viewModel = viewModel,
- deleteOnClick = viewModel::onDeleteWidget,
+ deleteOnClick = if (viewModel.isEditMode) viewModel::onDeleteWidget else null,
size =
SizeF(
Dimensions.CardWidth.value,
@@ -90,8 +92,14 @@ fun CommunalHub(
)
}
}
- IconButton(onClick = viewModel::onOpenWidgetEditor) {
- Icon(Icons.Default.Add, stringResource(R.string.button_to_open_widget_editor))
+ if (viewModel.isEditMode && onOpenWidgetPicker != null) {
+ IconButton(onClick = onOpenWidgetPicker) {
+ Icon(Icons.Default.Add, stringResource(R.string.hub_mode_add_widget_button_text))
+ }
+ } else {
+ IconButton(onClick = viewModel::onOpenWidgetEditor) {
+ Icon(Icons.Default.Edit, stringResource(R.string.button_to_open_widget_editor))
+ }
}
// This spacer covers the edge of the LazyHorizontalGrid and prevents it from receiving
@@ -109,9 +117,9 @@ fun CommunalHub(
@Composable
private fun CommunalContent(
model: CommunalContentModel,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
size: SizeF,
- deleteOnClick: (id: Int) -> Unit,
+ deleteOnClick: ((id: Int) -> Unit)?,
modifier: Modifier = Modifier,
) {
when (model) {
@@ -126,19 +134,22 @@ private fun CommunalContent(
private fun WidgetContent(
model: CommunalContentModel.Widget,
size: SizeF,
- deleteOnClick: (id: Int) -> Unit,
+ deleteOnClick: ((id: Int) -> Unit)?,
modifier: Modifier = Modifier,
) {
// TODO(b/309009246): update background color
Box(
modifier = modifier.fillMaxSize().background(Color.White),
) {
- IconButton(onClick = { deleteOnClick(model.appWidgetId) }) {
- Icon(
- Icons.Default.Close,
- LocalContext.current.getString(R.string.button_to_remove_widget)
- )
+ if (deleteOnClick != null) {
+ IconButton(onClick = { deleteOnClick(model.appWidgetId) }) {
+ Icon(
+ Icons.Default.Close,
+ LocalContext.current.getString(R.string.button_to_remove_widget)
+ )
+ }
}
+
AndroidView(
modifier = modifier,
factory = { context ->
@@ -171,7 +182,7 @@ private fun TutorialContent(modifier: Modifier = Modifier) {
}
@Composable
-private fun Umo(viewModel: CommunalViewModel, modifier: Modifier = Modifier) {
+private fun Umo(viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier) {
AndroidView(
modifier = modifier,
factory = {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
new file mode 100644
index 000000000000..ce7db80db7da
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 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.communal.view.viewmodel
+
+import android.app.smartspace.SmartspaceTarget
+import android.provider.Settings
+import android.widget.RemoteViews
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
+import com.android.systemui.communal.data.repository.FakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
+import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractorFactory
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
+import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalEditModeViewModelTest : SysuiTestCase() {
+ @Mock private lateinit var mediaHost: MediaHost
+
+ private lateinit var testScope: TestScope
+
+ private lateinit var keyguardRepository: FakeKeyguardRepository
+ private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var tutorialRepository: FakeCommunalTutorialRepository
+ private lateinit var widgetRepository: FakeCommunalWidgetRepository
+ private lateinit var smartspaceRepository: FakeSmartspaceRepository
+ private lateinit var mediaRepository: FakeCommunalMediaRepository
+
+ private lateinit var underTest: CommunalEditModeViewModel
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ testScope = TestScope()
+
+ val withDeps = CommunalInteractorFactory.create()
+ keyguardRepository = withDeps.keyguardRepository
+ communalRepository = withDeps.communalRepository
+ tutorialRepository = withDeps.tutorialRepository
+ widgetRepository = withDeps.widgetRepository
+ smartspaceRepository = withDeps.smartspaceRepository
+ mediaRepository = withDeps.mediaRepository
+
+ underTest =
+ CommunalEditModeViewModel(
+ withDeps.communalInteractor,
+ mediaHost,
+ )
+ }
+
+ @Test
+ fun communalContent_onlyWidgetsAreShownInEditMode() =
+ testScope.runTest {
+ tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+
+ // Widgets available.
+ val widgets =
+ listOf(
+ CommunalWidgetContentModel(
+ appWidgetId = 0,
+ priority = 30,
+ providerInfo = mock(),
+ ),
+ CommunalWidgetContentModel(
+ appWidgetId = 1,
+ priority = 20,
+ providerInfo = mock(),
+ ),
+ )
+ widgetRepository.setCommunalWidgets(widgets)
+
+ // Smartspace available.
+ val target = Mockito.mock(SmartspaceTarget::class.java)
+ whenever(target.smartspaceTargetId).thenReturn("target")
+ whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
+ whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
+ smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target))
+
+ // Media playing.
+ mediaRepository.mediaPlaying.value = true
+
+ val communalContent by collectLastValue(underTest.communalContent)
+
+ // Only Widgets are shown.
+ assertThat(communalContent?.size).isEqualTo(2)
+ assertThat(communalContent?.get(0))
+ .isInstanceOf(CommunalContentModel.Widget::class.java)
+ assertThat(communalContent?.get(1))
+ .isInstanceOf(CommunalContentModel.Widget::class.java)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
new file mode 100644
index 000000000000..32f4d075a873
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 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.communal.view.viewmodel
+
+import android.app.smartspace.SmartspaceTarget
+import android.provider.Settings
+import android.widget.RemoteViews
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
+import com.android.systemui.communal.data.repository.FakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
+import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractorFactory
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
+import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalViewModelTest : SysuiTestCase() {
+ @Mock private lateinit var mediaHost: MediaHost
+
+ private lateinit var testScope: TestScope
+
+ private lateinit var keyguardRepository: FakeKeyguardRepository
+ private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var tutorialRepository: FakeCommunalTutorialRepository
+ private lateinit var widgetRepository: FakeCommunalWidgetRepository
+ private lateinit var smartspaceRepository: FakeSmartspaceRepository
+ private lateinit var mediaRepository: FakeCommunalMediaRepository
+
+ private lateinit var underTest: CommunalViewModel
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ testScope = TestScope()
+
+ val withDeps = CommunalInteractorFactory.create()
+ keyguardRepository = withDeps.keyguardRepository
+ communalRepository = withDeps.communalRepository
+ tutorialRepository = withDeps.tutorialRepository
+ widgetRepository = withDeps.widgetRepository
+ smartspaceRepository = withDeps.smartspaceRepository
+ mediaRepository = withDeps.mediaRepository
+
+ underTest =
+ CommunalViewModel(
+ withDeps.communalInteractor,
+ withDeps.tutorialInteractor,
+ mediaHost,
+ )
+ }
+
+ @Test
+ fun tutorial_tutorialNotCompletedAndKeyguardVisible_showTutorialContent() =
+ testScope.runTest {
+ // Keyguard showing, and tutorial not started.
+ keyguardRepository.setKeyguardShowing(true)
+ keyguardRepository.setKeyguardOccluded(false)
+ tutorialRepository.setTutorialSettingState(
+ Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED
+ )
+
+ val communalContent by collectLastValue(underTest.communalContent)
+
+ assertThat(communalContent!!).isNotEmpty()
+ communalContent!!.forEach { model ->
+ assertThat(model is CommunalContentModel.Tutorial).isTrue()
+ }
+ }
+
+ @Test
+ fun ordering_smartspaceBeforeUmoBeforeWidgets() =
+ testScope.runTest {
+ tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+
+ // Widgets available.
+ val widgets =
+ listOf(
+ CommunalWidgetContentModel(
+ appWidgetId = 0,
+ priority = 30,
+ providerInfo = mock(),
+ ),
+ CommunalWidgetContentModel(
+ appWidgetId = 1,
+ priority = 20,
+ providerInfo = mock(),
+ ),
+ )
+ widgetRepository.setCommunalWidgets(widgets)
+
+ // Smartspace available.
+ val target = Mockito.mock(SmartspaceTarget::class.java)
+ whenever(target.smartspaceTargetId).thenReturn("target")
+ whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
+ whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
+ smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target))
+
+ // Media playing.
+ mediaRepository.mediaPlaying.value = true
+
+ val communalContent by collectLastValue(underTest.communalContent)
+
+ // Order is smart space, then UMO, then widget content.
+ assertThat(communalContent?.size).isEqualTo(4)
+ assertThat(communalContent?.get(0))
+ .isInstanceOf(CommunalContentModel.Smartspace::class.java)
+ assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java)
+ assertThat(communalContent?.get(2))
+ .isInstanceOf(CommunalContentModel.Widget::class.java)
+ assertThat(communalContent?.get(3))
+ .isInstanceOf(CommunalContentModel.Widget::class.java)
+ }
+}
diff --git a/packages/SystemUI/res/layout/edit_widgets.xml b/packages/SystemUI/res/layout/edit_widgets.xml
deleted file mode 100644
index 182e651aa66d..000000000000
--- a/packages/SystemUI/res/layout/edit_widgets.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
- ~ Copyright (C) 2023 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.
- -->
-
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/edit_widgets"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <Button
- style="@android:Widget.DeviceDefault.Button.Colored"
- android:id="@+id/add_widget"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textSize="28sp"
- android:text="@string/hub_mode_add_widget_button_text"/>
-
-</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 7391a5e8e5fc..927bf024215d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -32,7 +32,6 @@ import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -47,7 +46,6 @@ constructor(
private val widgetRepository: CommunalWidgetRepository,
mediaRepository: CommunalMediaRepository,
smartspaceRepository: SmartspaceRepository,
- tutorialInteractor: CommunalTutorialInteractor,
private val appWidgetHost: AppWidgetHost,
private val editWidgetsActivityStarter: EditWidgetsActivityStarter
) {
@@ -86,20 +84,8 @@ constructor(
/** Delete a widget by id. */
fun deleteWidget(id: Int) = widgetRepository.deleteWidget(id)
- /** A list of all the communal content to be displayed in the communal hub. */
- @OptIn(ExperimentalCoroutinesApi::class)
- val communalContent: Flow<List<CommunalContentModel>> =
- tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode ->
- if (isTutorialMode) {
- return@flatMapLatest flowOf(tutorialContent)
- }
- combine(smartspaceContent, umoContent, widgetContent) { smartspace, umo, widgets ->
- smartspace + umo + widgets
- }
- }
-
/** A list of widget content to be displayed in the communal hub. */
- private val widgetContent: Flow<List<CommunalContentModel.Widget>> =
+ val widgetContent: Flow<List<CommunalContentModel.Widget>> =
widgetRepository.communalWidgets.map { widgets ->
widgets.map Widget@{ widget ->
return@Widget CommunalContentModel.Widget(
@@ -111,7 +97,7 @@ constructor(
}
/** A flow of available smartspace content. Currently only showing timer targets. */
- private val smartspaceContent: Flow<List<CommunalContentModel.Smartspace>> =
+ val smartspaceContent: Flow<List<CommunalContentModel.Smartspace>> =
if (!smartspaceRepository.isSmartspaceRemoteViewsEnabled) {
flowOf(emptyList())
} else {
@@ -133,7 +119,7 @@ constructor(
}
/** A list of tutorial content to be displayed in the communal hub in tutorial mode. */
- private val tutorialContent: List<CommunalContentModel.Tutorial> =
+ val tutorialContent: List<CommunalContentModel.Tutorial> =
listOf(
CommunalContentModel.Tutorial(id = 0, CommunalContentSize.FULL),
CommunalContentModel.Tutorial(id = 1, CommunalContentSize.THIRD),
@@ -145,7 +131,7 @@ constructor(
CommunalContentModel.Tutorial(id = 7, CommunalContentSize.HALF),
)
- private val umoContent: Flow<List<CommunalContentModel.Umo>> =
+ val umoContent: Flow<List<CommunalContentModel.Umo>> =
mediaRepository.mediaPlaying.flatMapLatest { mediaPlaying ->
if (mediaPlaying) {
// TODO(b/310254801): support HALF and FULL layouts
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
new file mode 100644
index 000000000000..98f3594801f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 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.communal.ui.viewmodel
+
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalSceneKey
+import com.android.systemui.media.controls.ui.MediaHost
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/** The base view model for the communal hub. */
+abstract class BaseCommunalViewModel(
+ private val communalInteractor: CommunalInteractor,
+ val mediaHost: MediaHost,
+) {
+ val currentScene: StateFlow<CommunalSceneKey> = communalInteractor.desiredScene
+
+ fun onSceneChanged(scene: CommunalSceneKey) {
+ communalInteractor.onSceneChanged(scene)
+ }
+
+ /** A list of all the communal content to be displayed in the communal hub. */
+ abstract val communalContent: Flow<List<CommunalContentModel>>
+
+ /** Whether in edit mode for the communal hub. */
+ open val isEditMode = false
+
+ /** Called as the UI requests deleting a widget. */
+ open fun onDeleteWidget(id: Int) {}
+
+ /** Called as the UI requests opening the widget editor. */
+ open fun onOpenWidgetEditor() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
new file mode 100644
index 000000000000..14d9b2ca80f0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.communal.ui.viewmodel
+
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.media.dagger.MediaModule
+import javax.inject.Inject
+import javax.inject.Named
+import kotlinx.coroutines.flow.Flow
+
+/** The view model for communal hub in edit mode. */
+@SysUISingleton
+class CommunalEditModeViewModel
+@Inject
+constructor(
+ private val communalInteractor: CommunalInteractor,
+ @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
+) : BaseCommunalViewModel(communalInteractor, mediaHost) {
+
+ override val isEditMode = true
+
+ // Only widgets are editable.
+ override val communalContent: Flow<List<CommunalContentModel>> =
+ communalInteractor.widgetContent
+
+ override fun onDeleteWidget(id: Int) = communalInteractor.deleteWidget(id)
+}
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 14edc8e0a88c..eaf2d5741e23 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
@@ -17,34 +17,43 @@
package com.android.systemui.communal.ui.viewmodel
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
-import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.media.dagger.MediaModule
import javax.inject.Inject
import javax.inject.Named
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+/** The default view model used for showing the communal hub. */
@SysUISingleton
class CommunalViewModel
@Inject
constructor(
private val communalInteractor: CommunalInteractor,
- @Named(MediaModule.COMMUNAL_HUB) val mediaHost: MediaHost,
-) {
- val currentScene: StateFlow<CommunalSceneKey> = communalInteractor.desiredScene
- fun onSceneChanged(scene: CommunalSceneKey) {
- communalInteractor.onSceneChanged(scene)
- }
+ tutorialInteractor: CommunalTutorialInteractor,
+ @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
+) : BaseCommunalViewModel(communalInteractor, mediaHost) {
- /** A list of all the communal content to be displayed in the communal hub. */
- val communalContent: Flow<List<CommunalContentModel>> = communalInteractor.communalContent
+ @OptIn(ExperimentalCoroutinesApi::class)
+ override val communalContent: Flow<List<CommunalContentModel>> =
+ tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode ->
+ if (isTutorialMode) {
+ return@flatMapLatest flowOf(communalInteractor.tutorialContent)
+ }
+ combine(
+ communalInteractor.smartspaceContent,
+ communalInteractor.umoContent,
+ communalInteractor.widgetContent,
+ ) { smartspace, umo, widgets ->
+ smartspace + umo + widgets
+ }
+ }
- /** Delete a widget by id. */
- fun onDeleteWidget(id: Int) = communalInteractor.deleteWidget(id)
-
- /** Open the widget editor */
- fun onOpenWidgetEditor() = communalInteractor.showWidgetEditor()
+ override fun onOpenWidgetEditor() = communalInteractor.showWidgetEditor()
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index 78e85db9ea05..7b94fc182fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -20,17 +20,21 @@ import android.appwidget.AppWidgetProviderInfo
import android.content.Intent
import android.os.Bundle
import android.util.Log
-import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import com.android.systemui.communal.domain.interactor.CommunalInteractor
-import com.android.systemui.res.R
+import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
+import com.android.systemui.compose.ComposeFacade.setCommunalEditWidgetActivityContent
import javax.inject.Inject
/** An Activity for editing the widgets that appear in hub mode. */
-class EditWidgetsActivity @Inject constructor(private val communalInteractor: CommunalInteractor) :
- ComponentActivity() {
+class EditWidgetsActivity
+@Inject
+constructor(
+ private val communalViewModel: CommunalEditModeViewModel,
+ private val communalInteractor: CommunalInteractor,
+) : ComponentActivity() {
companion object {
/**
* Intent extra name for the {@link AppWidgetProviderInfo} of a widget to add to hub mode.
@@ -59,20 +63,19 @@ class EditWidgetsActivity @Inject constructor(private val communalInteractor: Co
"Failed to receive result from widget picker, code=${result.resultCode}"
)
}
- this@EditWidgetsActivity.finish()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setShowWhenLocked(true)
- setContentView(R.layout.edit_widgets)
-
- val addWidgetsButton = findViewById<View>(R.id.add_widget)
- addWidgetsButton?.setOnClickListener({
- addWidgetActivityLauncher.launch(
- Intent(applicationContext, WidgetPickerActivity::class.java)
- )
- })
+ setCommunalEditWidgetActivityContent(
+ activity = this,
+ viewModel = communalViewModel,
+ onOpenWidgetPicker = {
+ addWidgetActivityLauncher.launch(
+ Intent(applicationContext, WidgetPickerActivity::class.java)
+ )
+ },
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt
index 3e6dbd5a7115..a2765486bf2d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt
@@ -43,7 +43,6 @@ constructor(
super.onCreate(savedInstanceState)
setContentView(R.layout.widget_picker)
- setShowWhenLocked(true)
loadWidgets()
}
diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
index 4bdea75d9d71..65d44957222a 100644
--- a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
+++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
@@ -22,7 +22,7 @@ import android.view.View
import android.view.WindowInsets
import androidx.activity.ComponentActivity
import androidx.lifecycle.LifecycleOwner
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.scene.shared.model.Scene
@@ -58,6 +58,13 @@ interface BaseComposeFacade {
onResult: (PeopleViewModel.Result) -> Unit,
)
+ /** Bind the content of [activity] to [viewModel]. */
+ fun setCommunalEditWidgetActivityContent(
+ activity: ComponentActivity,
+ viewModel: BaseCommunalViewModel,
+ onOpenWidgetPicker: () -> Unit,
+ )
+
/** Create a [View] to represent [viewModel] on screen. */
fun createFooterActionsView(
context: Context,
@@ -77,9 +84,9 @@ interface BaseComposeFacade {
/** Create a [View] to represent [viewModel] on screen. */
fun createCommunalView(
context: Context,
- viewModel: CommunalViewModel,
+ viewModel: BaseCommunalViewModel,
): View
/** Creates a container that hosts the communal UI and handles gesture transitions. */
- fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View
+ fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index e0567a4c6de5..16cfa2398fd5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -18,7 +18,6 @@
package com.android.systemui.communal.domain.interactor
import android.app.smartspace.SmartspaceTarget
-import android.provider.Settings
import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -99,24 +98,6 @@ class CommunalInteractorTest : SysuiTestCase() {
}
@Test
- fun tutorial_tutorialNotCompletedAndKeyguardVisible_showTutorialContent() =
- testScope.runTest {
- // Keyguard showing, and tutorial not started.
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- tutorialRepository.setTutorialSettingState(
- Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED
- )
-
- val communalContent by collectLastValue(underTest.communalContent)
-
- assertThat(communalContent!!).isNotEmpty()
- communalContent!!.forEach { model ->
- assertThat(model is CommunalContentModel.Tutorial).isTrue()
- }
- }
-
- @Test
fun widget_tutorialCompletedAndWidgetsAvailable_showWidgetContent() =
testScope.runTest {
// Keyguard showing, and tutorial completed.
@@ -145,12 +126,11 @@ class CommunalInteractorTest : SysuiTestCase() {
)
widgetRepository.setCommunalWidgets(widgets)
- val communalContent by collectLastValue(underTest.communalContent)
+ val widgetContent by collectLastValue(underTest.widgetContent)
- assertThat(communalContent!!).isNotEmpty()
- communalContent!!.forEachIndexed { index, model ->
- assertThat((model as CommunalContentModel.Widget).appWidgetId)
- .isEqualTo(widgets[index].appWidgetId)
+ assertThat(widgetContent!!).isNotEmpty()
+ widgetContent!!.forEachIndexed { index, model ->
+ assertThat(model.appWidgetId).isEqualTo(widgets[index].appWidgetId)
}
}
@@ -183,48 +163,9 @@ class CommunalInteractorTest : SysuiTestCase() {
val targets = listOf(target1, target2, target3)
smartspaceRepository.setLockscreenSmartspaceTargets(targets)
- val communalContent by collectLastValue(underTest.communalContent)
- assertThat(communalContent?.size).isEqualTo(1)
- assertThat(communalContent?.get(0)?.key).isEqualTo("smartspace_target3")
- }
-
- @Test
- fun smartspace_smartspaceAndWidgetsAvailable_showSmartspaceAndWidgetContent() =
- testScope.runTest {
- // Keyguard showing, and tutorial completed.
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
- // Widgets available.
- val widgets =
- listOf(
- CommunalWidgetContentModel(
- appWidgetId = 0,
- priority = 30,
- providerInfo = mock(),
- ),
- CommunalWidgetContentModel(
- appWidgetId = 1,
- priority = 20,
- providerInfo = mock(),
- ),
- )
- widgetRepository.setCommunalWidgets(widgets)
-
- // Smartspace available.
- val target = mock(SmartspaceTarget::class.java)
- whenever(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(mock(RemoteViews::class.java))
- smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target))
-
- val communalContent by collectLastValue(underTest.communalContent)
-
- assertThat(communalContent?.size).isEqualTo(3)
- assertThat(communalContent?.get(0)?.key).isEqualTo("smartspace_target")
- assertThat(communalContent?.get(1)?.key).isEqualTo("widget_0")
- assertThat(communalContent?.get(2)?.key).isEqualTo("widget_1")
+ val smartspaceContent by collectLastValue(underTest.smartspaceContent)
+ assertThat(smartspaceContent?.size).isEqualTo(1)
+ assertThat(smartspaceContent?.get(0)?.key).isEqualTo("smartspace_target3")
}
@Test
@@ -236,55 +177,11 @@ class CommunalInteractorTest : SysuiTestCase() {
// Media is playing.
mediaRepository.mediaPlaying.value = true
- val communalContent by collectLastValue(underTest.communalContent)
-
- assertThat(communalContent?.size).isEqualTo(1)
- assertThat(communalContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
- assertThat(communalContent?.get(0)?.key).isEqualTo(CommunalContentModel.UMO_KEY)
- }
-
- @Test
- fun ordering_smartspaceBeforeUmoBeforeWidgets() =
- testScope.runTest {
- tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
- // Widgets available.
- val widgets =
- listOf(
- CommunalWidgetContentModel(
- appWidgetId = 0,
- priority = 30,
- providerInfo = mock(),
- ),
- CommunalWidgetContentModel(
- appWidgetId = 1,
- priority = 20,
- providerInfo = mock(),
- ),
- )
- widgetRepository.setCommunalWidgets(widgets)
-
- // Smartspace available.
- val target = mock(SmartspaceTarget::class.java)
- whenever(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(mock(RemoteViews::class.java))
- smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target))
-
- // Media playing.
- mediaRepository.mediaPlaying.value = true
+ val umoContent by collectLastValue(underTest.umoContent)
- val communalContent by collectLastValue(underTest.communalContent)
-
- // Order is smart space, then UMO, then widget content.
- assertThat(communalContent?.size).isEqualTo(4)
- assertThat(communalContent?.get(0))
- .isInstanceOf(CommunalContentModel.Smartspace::class.java)
- assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java)
- assertThat(communalContent?.get(2))
- .isInstanceOf(CommunalContentModel.Widget::class.java)
- assertThat(communalContent?.get(3))
- .isInstanceOf(CommunalContentModel.Widget::class.java)
+ assertThat(umoContent?.size).isEqualTo(1)
+ assertThat(umoContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
+ assertThat(umoContent?.get(0)?.key).isEqualTo(CommunalContentModel.UMO_KEY)
}
@Test
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt
index 3aee889d55f4..b27926c8ba50 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt
@@ -65,7 +65,6 @@ object CommunalInteractorFactory {
widgetRepository,
mediaRepository,
smartspaceRepository,
- withDeps.communalTutorialInteractor,
appWidgetHost,
editWidgetsActivityStarter,
),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index d3744d55c55d..4068e408f0bd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -167,6 +167,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository {
_isKeyguardOccluded.value = isOccluded
}
+ fun setKeyguardUnlocked(isUnlocked: Boolean) {
+ _isKeyguardUnlocked.value = isUnlocked
+ }
+
override fun setIsDozing(isDozing: Boolean) {
_isDozing.value = isDozing
}