Merge "Disable communal hub if lockscreen widgets are disabled" into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index ff53ff2..378a1e4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -34,6 +34,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -43,23 +44,21 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val viewModel: LockscreenSceneViewModel,
+ viewModel: LockscreenSceneViewModel,
private val lockscreenContent: Lazy<LockscreenContent>,
) : ComposableScene {
override val key = SceneKey.Lockscreen
override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
- viewModel.upDestinationSceneKey
- .map { pageKey ->
- destinationScenes(up = pageKey, left = viewModel.leftDestinationSceneKey)
- }
+ combine(viewModel.upDestinationSceneKey, viewModel.leftDestinationSceneKey, ::Pair)
+ .map { (upKey, leftKey) -> destinationScenes(up = upKey, left = leftKey) }
.stateIn(
scope = applicationScope,
started = SharingStarted.Eagerly,
initialValue =
destinationScenes(
up = viewModel.upDestinationSceneKey.value,
- left = viewModel.leftDestinationSceneKey,
+ left = viewModel.leftDestinationSceneKey.value,
)
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
index bd9ca30..b4e2eab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
@@ -16,26 +16,18 @@
package com.android.systemui.communal.data.repository
-import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.Flags
-import com.android.systemui.flags.fakeFeatureFlagsClassic
-import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.FakeUserRepository
-import com.android.systemui.user.data.repository.fakeUserRepository
-import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
@@ -48,37 +40,20 @@
class CommunalRepositoryImplTest : SysuiTestCase() {
private lateinit var underTest: CommunalRepositoryImpl
- private lateinit var secureSettings: FakeSettings
- private lateinit var userRepository: FakeUserRepository
-
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val sceneContainerRepository = kosmos.sceneContainerRepository
@Before
fun setUp() {
- secureSettings = FakeSettings()
- userRepository = kosmos.fakeUserRepository
-
- val listOfUserInfo = listOf(MAIN_USER_INFO)
- userRepository.setUserInfos(listOfUserInfo)
-
- kosmos.fakeFeatureFlagsClassic.apply { set(Flags.COMMUNAL_SERVICE_ENABLED, true) }
- mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
-
underTest = createRepositoryImpl(false)
}
private fun createRepositoryImpl(sceneContainerEnabled: Boolean): CommunalRepositoryImpl {
return CommunalRepositoryImpl(
testScope.backgroundScope,
- testScope.backgroundScope,
- kosmos.testDispatcher,
- kosmos.fakeFeatureFlagsClassic,
kosmos.fakeSceneContainerFlags.apply { enabled = sceneContainerEnabled },
sceneContainerRepository,
- kosmos.fakeUserRepository,
- secureSettings,
)
}
@@ -159,29 +134,4 @@
assertThat(transitionState)
.isEqualTo(ObservableCommunalTransitionState.Idle(CommunalSceneKey.DEFAULT))
}
-
- @Test
- fun communalEnabledState_false_whenGlanceableHubSettingFalse() =
- testScope.runTest {
- userRepository.setSelectedUserInfo(MAIN_USER_INFO)
- secureSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 0, MAIN_USER_INFO.id)
-
- val communalEnabled by collectLastValue(underTest.communalEnabledState)
- assertThat(communalEnabled).isFalse()
- }
-
- @Test
- fun communalEnabledState_true_whenGlanceableHubSettingTrue() =
- testScope.runTest {
- userRepository.setSelectedUserInfo(MAIN_USER_INFO)
- secureSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 1, MAIN_USER_INFO.id)
-
- val communalEnabled by collectLastValue(underTest.communalEnabledState)
- assertThat(communalEnabled).isTrue()
- }
-
- companion object {
- private const val GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled"
- private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
new file mode 100644
index 0000000..0aca16d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2024 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.data.repository
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
+import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
+import android.app.admin.devicePolicyManager
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.communal.data.model.DisabledReason
+import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl.Companion.GLANCEABLE_HUB_ENABLED
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.nullable
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.settings.fakeSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private lateinit var underTest: CommunalSettingsRepository
+
+ @Before
+ fun setUp() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+ setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_FEATURES_NONE)
+ setKeyguardFeaturesDisabled(SECONDARY_USER, KEYGUARD_DISABLE_FEATURES_NONE)
+ underTest = kosmos.communalSettingsRepository
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun secondaryUserIsInvalid() =
+ testScope.runTest {
+ val enabledState by collectLastValue(underTest.getEnabledState(SECONDARY_USER))
+
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_INVALID_USER)
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun classicFlagIsDisabled() =
+ testScope.runTest {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
+ val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_FLAG)
+ }
+
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun communalHubFlagIsDisabled() =
+ testScope.runTest {
+ val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_FLAG)
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun hubIsDisabledByUser() =
+ testScope.runTest {
+ kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 0, PRIMARY_USER.id)
+ val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_USER_SETTING)
+
+ kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 1, SECONDARY_USER.id)
+ assertThat(enabledState?.enabled).isFalse()
+
+ kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 1, PRIMARY_USER.id)
+ assertThat(enabledState?.enabled).isTrue()
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun hubIsDisabledByDevicePolicy() =
+ testScope.runTest {
+ val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
+ assertThat(enabledState?.enabled).isTrue()
+
+ setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_WIDGETS_ALL)
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_DEVICE_POLICY)
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun hubIsDisabledByUserAndDevicePolicy() =
+ testScope.runTest {
+ val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
+ assertThat(enabledState?.enabled).isTrue()
+
+ kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 0, PRIMARY_USER.id)
+ setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_WIDGETS_ALL)
+
+ assertThat(enabledState?.enabled).isFalse()
+ assertThat(enabledState)
+ .containsExactly(
+ DisabledReason.DISABLED_REASON_DEVICE_POLICY,
+ DisabledReason.DISABLED_REASON_USER_SETTING,
+ )
+ }
+
+ private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) {
+ whenever(kosmos.devicePolicyManager.getKeyguardDisabledFeatures(nullable(), eq(user.id)))
+ .thenReturn(disabledFlags)
+ kosmos.broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ )
+ }
+
+ private companion object {
+ val PRIMARY_USER =
+ UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN)
+ val SECONDARY_USER = UserInfo(/* id= */ 1, /* name= */ "secondary user", /* flags= */ 0)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
index 6a3fc2a..824733b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
@@ -19,6 +19,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
@@ -59,7 +60,7 @@
widgetRepository = kosmos.fakeCommunalWidgetRepository
keyguardRepository = kosmos.fakeKeyguardRepository
- communalRepository.setIsCommunalEnabled(false)
+ mSetFlagsRule.disableFlags(FLAG_COMMUNAL_HUB)
underTest = kosmos.communalInteractor
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index c5485c5..3ac19e4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -23,6 +23,7 @@
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalPrefsRepository
@@ -41,6 +42,8 @@
import com.android.systemui.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.kosmos.testScope
@@ -109,12 +112,19 @@
whenever(secondaryUser.isMain).thenReturn(false)
userRepository.setUserInfos(listOf(mainUser, secondaryUser))
+ kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
+ mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
+
underTest = kosmos.communalInteractor
}
@Test
fun communalEnabled_true() =
- testScope.runTest { assertThat(underTest.isCommunalEnabled).isTrue() }
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(mainUser)
+ runCurrent()
+ assertThat(underTest.isCommunalEnabled).isTrue()
+ }
@Test
fun isCommunalAvailable_storageUnlockedAndMainUser_true() =
@@ -125,7 +135,6 @@
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(mainUser)
keyguardRepository.setKeyguardShowing(true)
- communalRepository.setCommunalEnabledState(true)
assertThat(isAvailable).isTrue()
}
@@ -139,7 +148,6 @@
keyguardRepository.setIsEncryptedOrLockdown(true)
userRepository.setSelectedUserInfo(mainUser)
keyguardRepository.setKeyguardShowing(true)
- communalRepository.setCommunalEnabledState(true)
assertThat(isAvailable).isFalse()
}
@@ -153,7 +161,6 @@
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(secondaryUser)
keyguardRepository.setKeyguardShowing(true)
- communalRepository.setCommunalEnabledState(true)
assertThat(isAvailable).isFalse()
}
@@ -167,7 +174,6 @@
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(mainUser)
keyguardRepository.setDreaming(true)
- communalRepository.setCommunalEnabledState(true)
assertThat(isAvailable).isTrue()
}
@@ -175,13 +181,14 @@
@Test
fun isCommunalAvailable_communalDisabled_false() =
testScope.runTest {
+ mSetFlagsRule.disableFlags(FLAG_COMMUNAL_HUB)
+
val isAvailable by collectLastValue(underTest.isCommunalAvailable)
assertThat(isAvailable).isFalse()
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(mainUser)
keyguardRepository.setKeyguardShowing(true)
- communalRepository.setCommunalEnabledState(false)
assertThat(isAvailable).isFalse()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
index 6c87e0f..ceb7fac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
@@ -22,12 +22,15 @@
import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_STARTED
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.kosmos.testScope
@@ -35,11 +38,13 @@
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.data.repository.fakeUserRepository
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalTutorialInteractorTest : SysuiTestCase() {
@@ -62,6 +67,8 @@
userRepository = kosmos.fakeUserRepository
userRepository.setUserInfos(listOf(MAIN_USER_INFO))
+ kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
+ mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
underTest = kosmos.communalTutorialInteractor
}
@@ -127,6 +134,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_NOT_STARTED)
communalRepository.setIsCommunalHubShowing(true)
@@ -139,6 +147,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_STARTED)
communalRepository.setIsCommunalHubShowing(true)
@@ -151,6 +160,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
communalRepository.setIsCommunalHubShowing(true)
@@ -163,6 +173,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_NOT_STARTED)
communalRepository.setIsCommunalHubShowing(false)
@@ -175,6 +186,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalRepository.setIsCommunalHubShowing(true)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_STARTED)
@@ -188,6 +200,7 @@
testScope.runTest {
val tutorialSettingState by
collectLastValue(communalTutorialRepository.tutorialSettingState)
+ userRepository.setSelectedUserInfo(MAIN_USER_INFO)
communalRepository.setIsCommunalHubShowing(true)
communalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
@@ -198,14 +211,11 @@
private suspend fun setCommunalAvailable(available: Boolean) {
if (available) {
- communalRepository.setIsCommunalEnabled(true)
- communalRepository.setCommunalEnabledState(true)
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(MAIN_USER_INFO)
keyguardRepository.setKeyguardShowing(true)
} else {
- communalRepository.setIsCommunalEnabled(false)
- communalRepository.setCommunalEnabledState(false)
+ keyguardRepository.setIsEncryptedOrLockdown(true)
}
}
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
index 73d3091..f70b6a5 100644
--- 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
@@ -22,12 +22,12 @@
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
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.communalInteractor
@@ -37,6 +37,8 @@
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.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.kosmos.testScope
@@ -92,7 +94,8 @@
mediaRepository = kosmos.fakeCommunalMediaRepository
userRepository = kosmos.fakeUserRepository
- kosmos.fakeCommunalRepository.setCommunalEnabledState(true)
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+ mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
underTest =
CommunalViewModel(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
index 032d76f..8488843 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
@@ -19,12 +19,15 @@
import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl.Companion.GLANCEABLE_HUB_ENABLED
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
@@ -33,6 +36,7 @@
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -62,6 +66,8 @@
fun setUp() {
MockitoAnnotations.initMocks(this)
kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO))
+ kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
+ mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
appWidgetIdToRemove = MutableSharedFlow()
whenever(appWidgetHost.appWidgetIdToRemove).thenReturn(appWidgetIdToRemove)
@@ -169,7 +175,8 @@
fakeKeyguardRepository.setIsEncryptedOrLockdown(false)
fakeUserRepository.setSelectedUserInfo(MAIN_USER_INFO)
fakeKeyguardRepository.setKeyguardShowing(true)
- fakeCommunalRepository.setCommunalEnabledState(available)
+ val settingsValue = if (available) 1 else 0
+ fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, settingsValue, MAIN_USER_INFO.id)
}
private companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 4595fbf..7261723 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -18,22 +18,28 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.content.pm.UserInfo
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
-import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
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.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -49,9 +55,7 @@
private val testScope = kosmos.testScope
private val sceneInteractor by lazy { kosmos.sceneInteractor }
- private val underTest by lazy {
- createLockscreenSceneViewModel()
- }
+ private val underTest by lazy { createLockscreenSceneViewModel() }
@Test
fun upTransitionSceneKey_canSwipeToUnlock_gone() =
@@ -80,29 +84,37 @@
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
}
+ @EnableFlags(FLAG_COMMUNAL_HUB)
@Test
fun leftTransitionSceneKey_communalIsEnabled_communal() =
testScope.runTest {
- kosmos.fakeCommunalRepository.setIsCommunalEnabled(true)
- val underTest = createLockscreenSceneViewModel()
-
- assertThat(underTest.leftDestinationSceneKey).isEqualTo(SceneKey.Communal)
+ with(kosmos.fakeUserRepository) {
+ setUserInfos(listOf(PRIMARY_USER))
+ setSelectedUserInfo(PRIMARY_USER)
+ }
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+ val leftDestinationSceneKey by collectLastValue(underTest.leftDestinationSceneKey)
+ assertThat(leftDestinationSceneKey).isEqualTo(SceneKey.Communal)
}
+ @DisableFlags(FLAG_COMMUNAL_HUB)
@Test
fun leftTransitionSceneKey_communalIsDisabled_null() =
testScope.runTest {
- kosmos.fakeCommunalRepository.setIsCommunalEnabled(false)
- val underTest = createLockscreenSceneViewModel()
-
- assertThat(underTest.leftDestinationSceneKey).isNull()
+ with(kosmos.fakeUserRepository) {
+ setUserInfos(listOf(PRIMARY_USER))
+ setSelectedUserInfo(PRIMARY_USER)
+ }
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
+ val leftDestinationSceneKey by collectLastValue(underTest.leftDestinationSceneKey)
+ assertThat(leftDestinationSceneKey).isNull()
}
private fun createLockscreenSceneViewModel(): LockscreenSceneViewModel {
return LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope,
deviceEntryInteractor = kosmos.deviceEntryInteractor,
- communalInteractor = kosmos.communalInteractor,
+ communalSettingsInteractor = kosmos.communalSettingsInteractor,
longPress =
KeyguardLongPressViewModel(
interactor = mock(),
@@ -110,4 +122,9 @@
notifications = kosmos.notificationsPlaceholderViewModel,
)
}
+
+ private companion object {
+ val PRIMARY_USER =
+ UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 9d3f0d6..006f429 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -40,7 +40,7 @@
import com.android.systemui.bouncer.ui.viewmodel.bouncerViewModel
import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.classifier.falsingCollector
-import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -130,7 +130,7 @@
private val sceneInteractor by lazy { kosmos.sceneInteractor }
private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
- private val communalInteractor by lazy { kosmos.communalInteractor }
+ private val communalSettingsInteractor by lazy { kosmos.communalSettingsInteractor }
private val transitionState by lazy {
MutableStateFlow<ObservableTransitionState>(
@@ -155,7 +155,7 @@
LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope,
deviceEntryInteractor = deviceEntryInteractor,
- communalInteractor = communalInteractor,
+ communalSettingsInteractor = communalSettingsInteractor,
longPress =
KeyguardLongPressViewModel(
interactor = mock(),
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
index dc07c1b..0bad33b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
@@ -20,6 +20,7 @@
import com.android.systemui.communal.data.repository.CommunalMediaRepositoryModule
import com.android.systemui.communal.data.repository.CommunalPrefsRepositoryModule
import com.android.systemui.communal.data.repository.CommunalRepositoryModule
+import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule
import com.android.systemui.communal.data.repository.CommunalTutorialRepositoryModule
import com.android.systemui.communal.data.repository.CommunalWidgetRepositoryModule
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
@@ -36,6 +37,7 @@
CommunalWidgetRepositoryModule::class,
CommunalDatabaseModule::class,
CommunalPrefsRepositoryModule::class,
+ CommunalSettingsRepositoryModule::class,
]
)
interface CommunalModule {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalEnabledState.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalEnabledState.kt
new file mode 100644
index 0000000..83a5bdb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalEnabledState.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 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.data.model
+
+import com.android.systemui.log.table.Diffable
+import com.android.systemui.log.table.TableRowLogger
+import java.util.EnumSet
+
+/** Reasons that communal is disabled, primarily for logging. */
+enum class DisabledReason(val loggingString: String) {
+ /** Communal should be disabled due to invalid current user */
+ DISABLED_REASON_INVALID_USER("invalidUser"),
+ /** Communal should be disabled due to the flag being off */
+ DISABLED_REASON_FLAG("flag"),
+ /** Communal should be disabled because the user has turned off the setting */
+ DISABLED_REASON_USER_SETTING("userSetting"),
+ /** Communal is disabled by the device policy app */
+ DISABLED_REASON_DEVICE_POLICY("devicePolicy"),
+}
+
+/**
+ * Model representing the reasons communal hub should be disabled. Allows logging reasons separately
+ * for debugging.
+ */
+@JvmInline
+value class CommunalEnabledState(
+ private val disabledReasons: EnumSet<DisabledReason> =
+ EnumSet.noneOf(DisabledReason::class.java)
+) : Diffable<CommunalEnabledState>, Set<DisabledReason> by disabledReasons {
+
+ /** Creates [CommunalEnabledState] with a single reason for being disabled */
+ constructor(reason: DisabledReason) : this(EnumSet.of(reason))
+
+ /** Checks if there are any reasons communal should be disabled. If none, returns true. */
+ val enabled: Boolean
+ get() = isEmpty()
+
+ override fun logDiffs(prevVal: CommunalEnabledState, row: TableRowLogger) {
+ for (reason in DisabledReason.entries) {
+ val newVal = contains(reason)
+ if (newVal != prevVal.contains(reason)) {
+ row.logChange(
+ columnName = reason.loggingString,
+ value = newVal,
+ )
+ }
+ }
+ }
+
+ override fun logFull(row: TableRowLogger) {
+ for (reason in DisabledReason.entries) {
+ row.logChange(columnName = reason.loggingString, value = contains(reason))
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
index addd880..4a06585f5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
@@ -16,22 +16,14 @@
package com.android.systemui.communal.data.repository
-import com.android.systemui.Flags.communalHub
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.flags.Flags
import com.android.systemui.scene.data.repository.SceneContainerRepository
import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.user.data.repository.UserRepository
-import com.android.systemui.util.settings.SecureSettings
-import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -39,26 +31,13 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.withContext
/** Encapsulates the state of communal mode. */
interface CommunalRepository {
- /** Whether communal features are enabled. */
- val isCommunalEnabled: Boolean
-
- /**
- * A {@link StateFlow} that tracks whether communal hub is enabled (it can be disabled in
- * settings).
- */
- val communalEnabledState: StateFlow<Boolean>
-
/** Whether the communal hub is showing. */
val isCommunalHubShowing: Flow<Boolean>
@@ -87,37 +66,11 @@
class CommunalRepositoryImpl
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
@Background backgroundScope: CoroutineScope,
- @Background private val backgroundDispatcher: CoroutineDispatcher,
- private val featureFlagsClassic: FeatureFlagsClassic,
sceneContainerFlags: SceneContainerFlags,
sceneContainerRepository: SceneContainerRepository,
- userRepository: UserRepository,
- private val secureSettings: SecureSettings
) : CommunalRepository {
- private val communalEnabledSettingState: Flow<Boolean> =
- userRepository.selectedUserInfo
- .flatMapLatest { userInfo -> observeSettings(userInfo.id) }
- .shareIn(scope = applicationScope, started = SharingStarted.WhileSubscribed())
-
- override val communalEnabledState: StateFlow<Boolean> =
- if (featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()) {
- communalEnabledSettingState
- .filterNotNull()
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.Eagerly,
- initialValue = true
- )
- } else {
- MutableStateFlow(false)
- }
-
- override val isCommunalEnabled: Boolean
- get() = communalEnabledState.value
-
private val _desiredScene: MutableStateFlow<CommunalSceneKey> =
MutableStateFlow(CommunalSceneKey.DEFAULT)
override val desiredScene: StateFlow<CommunalSceneKey> = _desiredScene.asStateFlow()
@@ -153,26 +106,4 @@
} else {
desiredScene.map { sceneKey -> sceneKey == CommunalSceneKey.Communal }
}
-
- private fun observeSettings(userId: Int): Flow<Boolean> =
- secureSettings
- .observerFlow(
- userId = userId,
- names =
- arrayOf(
- GLANCEABLE_HUB_ENABLED,
- )
- )
- // Force an update
- .onStart { emit(Unit) }
- .map { readFromSettings(userId) }
-
- private suspend fun readFromSettings(userId: Int): Boolean =
- withContext(backgroundDispatcher) {
- secureSettings.getIntForUser(GLANCEABLE_HUB_ENABLED, 1, userId) == 1
- }
-
- companion object {
- private const val GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled"
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
new file mode 100644
index 0000000..201b049
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2024 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.data.repository
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
+import android.content.IntentFilter
+import android.content.pm.UserInfo
+import com.android.systemui.Flags.communalHub
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.communal.data.model.CommunalEnabledState
+import com.android.systemui.communal.data.model.DisabledReason
+import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_DEVICE_POLICY
+import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_FLAG
+import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_INVALID_USER
+import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_USER_SETTING
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.kotlin.emitOnStart
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import java.util.EnumSet
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+
+interface CommunalSettingsRepository {
+ /** A [CommunalEnabledState] for the specified user. */
+ fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState>
+}
+
+@SysUISingleton
+class CommunalSettingsRepositoryImpl
+@Inject
+constructor(
+ @Background private val bgDispatcher: CoroutineDispatcher,
+ private val featureFlagsClassic: FeatureFlagsClassic,
+ private val secureSettings: SecureSettings,
+ private val broadcastDispatcher: BroadcastDispatcher,
+ private val devicePolicyManager: DevicePolicyManager,
+) : CommunalSettingsRepository {
+
+ private val flagEnabled: Boolean by lazy {
+ featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
+ }
+
+ override fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState> {
+ if (!user.isMain) {
+ return flowOf(CommunalEnabledState(DISABLED_REASON_INVALID_USER))
+ }
+ if (!flagEnabled) {
+ return flowOf(CommunalEnabledState(DISABLED_REASON_FLAG))
+ }
+ return combine(
+ getEnabledByUser(user).mapToReason(DISABLED_REASON_USER_SETTING),
+ getAllowedByDevicePolicy(user).mapToReason(DISABLED_REASON_DEVICE_POLICY),
+ ) { reasons ->
+ reasons.filterNotNull()
+ }
+ .map { reasons ->
+ if (reasons.isEmpty()) {
+ EnumSet.noneOf(DisabledReason::class.java)
+ } else {
+ EnumSet.copyOf(reasons)
+ }
+ }
+ .map { reasons -> CommunalEnabledState(reasons) }
+ .flowOn(bgDispatcher)
+ }
+
+ private fun getEnabledByUser(user: UserInfo): Flow<Boolean> =
+ secureSettings
+ .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_ENABLED))
+ // Force an update
+ .onStart { emit(Unit) }
+ .map {
+ secureSettings.getIntForUser(
+ GLANCEABLE_HUB_ENABLED,
+ ENABLED_SETTING_DEFAULT,
+ user.id,
+ ) == 1
+ }
+
+ private fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> =
+ broadcastDispatcher
+ .broadcastFlow(
+ filter =
+ IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ user = user.userHandle
+ )
+ .emitOnStart()
+ .map { devicePolicyManager.areKeyguardWidgetsAllowed(user.id) }
+
+ companion object {
+ const val GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled"
+ private const val ENABLED_SETTING_DEFAULT = 1
+ }
+}
+
+private fun DevicePolicyManager.areKeyguardWidgetsAllowed(userId: Int): Boolean =
+ (getKeyguardDisabledFeatures(null, userId) and KEYGUARD_DISABLE_WIDGETS_ALL) == 0
+
+private fun Flow<Boolean>.mapToReason(reason: DisabledReason) = map { enabled ->
+ if (enabled) null else reason
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryModule.kt
new file mode 100644
index 0000000..a931d3f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryModule.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 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.data.repository
+
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface CommunalSettingsRepositoryModule {
+ @Binds
+ fun communalSettingsRepository(impl: CommunalSettingsRepositoryImpl): CommunalSettingsRepository
+}
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 950ac3c..23f590e 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
@@ -42,7 +42,6 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.smartspace.data.repository.SmartspaceRepository
-import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.BooleanFlowOperators.and
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.BooleanFlowOperators.or
@@ -74,8 +73,8 @@
private val communalPrefsRepository: CommunalPrefsRepository,
mediaRepository: CommunalMediaRepository,
smartspaceRepository: SmartspaceRepository,
- userRepository: UserRepository,
keyguardInteractor: KeyguardInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val appWidgetHost: CommunalAppWidgetHost,
private val editWidgetsActivityStarter: EditWidgetsActivityStarter,
@CommunalLog logBuffer: LogBuffer,
@@ -90,13 +89,12 @@
/** Whether communal features are enabled. */
val isCommunalEnabled: Boolean
- get() = communalRepository.isCommunalEnabled
+ get() = communalSettingsInteractor.isCommunalEnabled.value
/** Whether communal features are enabled and available. */
val isCommunalAvailable: Flow<Boolean> =
and(
- communalRepository.communalEnabledState,
- userRepository.selectedUserInfo.map { it.isMain },
+ communalSettingsInteractor.isCommunalEnabled,
not(keyguardInteractor.isEncryptedOrLockdown),
or(keyguardInteractor.isKeyguardVisible, keyguardInteractor.isDreaming)
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
new file mode 100644
index 0000000..0b096ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 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.domain.interactor
+
+import com.android.systemui.communal.data.model.CommunalEnabledState
+import com.android.systemui.communal.data.repository.CommunalSettingsRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.dagger.CommunalTableLog
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class CommunalSettingsInteractor
+@Inject
+constructor(
+ @Background private val bgScope: CoroutineScope,
+ private val repository: CommunalSettingsRepository,
+ userInteractor: SelectedUserInteractor,
+ @CommunalTableLog tableLogBuffer: TableLogBuffer,
+) {
+ /** Whether or not communal is enabled for the currently selected user. */
+ val isCommunalEnabled: StateFlow<Boolean> =
+ userInteractor.selectedUserInfo
+ .flatMapLatest { user -> repository.getEnabledState(user) }
+ .logDiffsForTable(
+ tableLogBuffer = tableLogBuffer,
+ columnPrefix = "disabledReason",
+ initialValue = CommunalEnabledState()
+ )
+ .map { model -> model.enabled }
+ // Start this eagerly since the value is accessed synchronously in many places.
+ .stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractor.kt
index 1404ee2..25dfc02 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractor.kt
@@ -28,17 +28,18 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transformWhile
import kotlinx.coroutines.launch
/** Encapsulates business-logic related to communal tutorial state. */
@@ -51,6 +52,7 @@
private val communalTutorialRepository: CommunalTutorialRepository,
keyguardInteractor: KeyguardInteractor,
private val communalRepository: CommunalRepository,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
communalInteractor: CommunalInteractor,
@CommunalTableLog tableLogBuffer: TableLogBuffer,
) {
@@ -110,20 +112,24 @@
return null
}
- private var job: Job? = null
private fun listenForTransitionToUpdateTutorialState() {
- if (!communalRepository.isCommunalEnabled) {
- return
- }
- job =
- scope.launch {
- tutorialStateToUpdate.collect {
- communalTutorialRepository.setTutorialState(it)
- if (it == Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) {
- job?.cancel()
+ scope.launch {
+ communalSettingsInteractor.isCommunalEnabled
+ .flatMapLatest { enabled ->
+ if (!enabled) {
+ emptyFlow()
+ } else {
+ tutorialStateToUpdate
}
}
- }
+ .transformWhile { tutorialState ->
+ emit(tutorialState)
+ tutorialState != Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED
+ }
+ .collect { tutorialState ->
+ communalTutorialRepository.setTutorialState(tutorialState)
+ }
+ }
}
init {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 2b28a71..fa18557 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -16,7 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
-import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -36,7 +36,7 @@
constructor(
@Application applicationScope: CoroutineScope,
deviceEntryInteractor: DeviceEntryInteractor,
- communalInteractor: CommunalInteractor,
+ communalSettingsInteractor: CommunalSettingsInteractor,
val longPress: KeyguardLongPressViewModel,
val notifications: NotificationsPlaceholderViewModel,
) {
@@ -55,10 +55,12 @@
}
/** The key of the scene we should switch to when swiping left. */
- val leftDestinationSceneKey: SceneKey? =
- if (communalInteractor.isCommunalEnabled) {
- SceneKey.Communal
- } else {
- null
- }
+ val leftDestinationSceneKey: StateFlow<SceneKey?> =
+ communalSettingsInteractor.isCommunalEnabled
+ .map { available -> if (available) SceneKey.Communal else null }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null,
+ )
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index 523414c..35e0271 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -1155,7 +1155,7 @@
onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
// TODO(b/311234666): revisit logic once interactions between the hub and
// shade/keyguard state are finalized
- isCommunalShowing && communalInteractor.isCommunalEnabled -> LOCATION_COMMUNAL_HUB
+ isCommunalShowing -> LOCATION_COMMUNAL_HUB
onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN
else -> LOCATION_QQS
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 1c7cc00..df845f5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -35,6 +35,7 @@
import com.android.systemui.util.kotlin.collectFlow
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
/**
* Controller that's responsible for the glanceable hub container view and its touch handling.
@@ -105,13 +106,9 @@
*/
private var shadeShowing = false
- /** Returns true if the glanceable hub is enabled and the container view can be created. */
- fun isEnabled(): Boolean {
- return communalInteractor.isCommunalEnabled && isComposeAvailable()
- }
-
- /** Returns a {@link StateFlow} that tracks whether communal hub is available. */
- fun communalAvailable(): Flow<Boolean> = communalInteractor.isCommunalAvailable
+ /** Returns a flow that tracks whether communal hub is available. */
+ fun communalAvailable(): Flow<Boolean> =
+ if (isComposeAvailable()) communalInteractor.isCommunalAvailable else flowOf(false)
/**
* Creates the container view containing the glanceable hub UI.
@@ -127,9 +124,6 @@
/** Override for testing. */
@VisibleForTesting
internal fun initView(containerView: View): View {
- if (!isEnabled()) {
- throw RuntimeException("Glanceable hub is not enabled")
- }
if (communalContainerView != null) {
throw RuntimeException("Communal view has already been initialized")
}
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
index 0fb4b43..38b381a 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
@@ -1,6 +1,7 @@
package com.android.systemui.user.domain.interactor
import android.annotation.UserIdInt
+import android.content.pm.UserInfo
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.Flags.refactorGetCurrentUser
import com.android.systemui.dagger.SysUISingleton
@@ -16,6 +17,9 @@
/** Flow providing the ID of the currently selected user. */
val selectedUser = repository.selectedUserInfo.map { it.id }.distinctUntilChanged()
+ /** Flow providing the [UserInfo] of the currently selected user. */
+ val selectedUserInfo = repository.selectedUserInfo
+
/**
* Returns the ID of the currently-selected user.
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 9517f82..1dc5f7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -103,8 +103,6 @@
)
testableLooper = TestableLooper.get(this)
- communalRepository.setIsCommunalEnabled(true)
-
whenever(keyguardTransitionInteractor.isFinishedInStateWhere(any()))
.thenReturn(bouncerShowingFlow)
whenever(shadeInteractor.isAnyFullyExpanded).thenReturn(shadeShowingFlow)
@@ -125,36 +123,6 @@
}
@Test
- fun isEnabled_communalEnabled_returnsTrue() {
- communalRepository.setIsCommunalEnabled(true)
-
- assertThat(underTest.isEnabled()).isTrue()
- }
-
- @Test
- fun isEnabled_communalDisabled_returnsFalse() {
- communalRepository.setIsCommunalEnabled(false)
-
- assertThat(underTest.isEnabled()).isFalse()
- }
-
- @Test
- fun initView_notEnabled_throwsException() {
- communalRepository.setIsCommunalEnabled(false)
-
- underTest =
- GlanceableHubContainerController(
- communalInteractor,
- communalViewModel,
- keyguardTransitionInteractor,
- shadeInteractor,
- powerManager,
- )
-
- assertThrows(RuntimeException::class.java) { underTest.initView(context) }
- }
-
- @Test
fun initView_calledTwice_throwsException() {
underTest =
GlanceableHubContainerController(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 22b05be..248ed24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -488,7 +488,8 @@
return
}
- whenever(mGlanceableHubContainerController.isEnabled()).thenReturn(true)
+ whenever(mGlanceableHubContainerController.communalAvailable())
+ .thenReturn(MutableStateFlow(true))
val mockCommunalView = mock(View::class.java)
whenever(mGlanceableHubContainerController.initView(any<Context>()))
@@ -513,7 +514,6 @@
return
}
- whenever(mGlanceableHubContainerController.isEnabled()).thenReturn(false)
whenever(mGlanceableHubContainerController.communalAvailable())
.thenReturn(MutableStateFlow(false))
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt
new file mode 100644
index 0000000..5485f79
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.data.repository
+
+import android.app.admin.devicePolicyManager
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.util.settings.fakeSettings
+
+val Kosmos.communalSettingsRepository: CommunalSettingsRepository by
+ Kosmos.Fixture {
+ CommunalSettingsRepositoryImpl(
+ bgDispatcher = testDispatcher,
+ featureFlagsClassic = featureFlagsClassic,
+ secureSettings = fakeSettings,
+ broadcastDispatcher = broadcastDispatcher,
+ devicePolicyManager = devicePolicyManager,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt
index cccd908..ae7d877 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt
@@ -16,7 +16,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
class FakeCommunalRepository(
applicationScope: CoroutineScope,
- override var isCommunalEnabled: Boolean = true,
override val desiredScene: MutableStateFlow<CommunalSceneKey> =
MutableStateFlow(CommunalSceneKey.DEFAULT),
) : CommunalRepository {
@@ -40,21 +39,10 @@
_transitionState.value = transitionState
}
- fun setIsCommunalEnabled(value: Boolean) {
- isCommunalEnabled = value
- }
-
private val _isCommunalHubShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
override val isCommunalHubShowing: Flow<Boolean> = _isCommunalHubShowing
fun setIsCommunalHubShowing(isCommunalHubShowing: Boolean) {
_isCommunalHubShowing.value = isCommunalHubShowing
}
-
- private val _communalEnabledState: MutableStateFlow<Boolean> = MutableStateFlow(false)
- override val communalEnabledState: StateFlow<Boolean> = _communalEnabledState
-
- fun setCommunalEnabledState(enabled: Boolean) {
- _communalEnabledState.value = enabled
- }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index c47f020..f7e9a11 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -27,7 +27,6 @@
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.smartspace.data.repository.smartspaceRepository
-import com.android.systemui.user.data.repository.userRepository
import com.android.systemui.util.mockito.mock
val Kosmos.communalInteractor by Fixture {
@@ -38,12 +37,12 @@
mediaRepository = communalMediaRepository,
communalPrefsRepository = communalPrefsRepository,
smartspaceRepository = smartspaceRepository,
- userRepository = userRepository,
appWidgetHost = mock(),
keyguardInteractor = keyguardInteractor,
editWidgetsActivityStarter = editWidgetsActivityStarter,
logBuffer = logcatLogBuffer("CommunalInteractor"),
tableLogBuffer = mock(),
+ communalSettingsInteractor = communalSettingsInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorKosmos.kt
new file mode 100644
index 0000000..b4773f6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.domain.interactor
+
+import com.android.systemui.communal.data.repository.communalSettingsRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.communalSettingsInteractor by Fixture {
+ CommunalSettingsInteractor(
+ bgScope = applicationCoroutineScope,
+ repository = communalSettingsRepository,
+ userInteractor = selectedUserInteractor,
+ tableLogBuffer = mock(),
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorKosmos.kt
index 9776b43..00fdced 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorKosmos.kt
@@ -31,6 +31,7 @@
keyguardInteractor = keyguardInteractor,
communalRepository = communalRepository,
communalInteractor = communalInteractor,
+ communalSettingsInteractor = communalSettingsInteractor,
tableLogBuffer = mock(),
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettingsKosmos.kt
new file mode 100644
index 0000000..bcb5848
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettingsKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 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.util.settings
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.fakeSettings: FakeSettings by Fixture { FakeSettings() }