summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryImplTest.kt96
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepository.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryModule.kt5
3 files changed, 119 insertions, 52 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryImplTest.kt
index 30a5497d0a14..c4a8582d51b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryImplTest.kt
@@ -20,15 +20,16 @@ import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.CommunalTutorialRepositoryImpl.Companion.CURRENT_TUTORIAL_VERSION
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.FakeLogBuffer
-import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.testKosmos
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.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -38,36 +39,37 @@ import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalTutorialRepositoryImplTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
private lateinit var secureSettings: FakeSettings
private lateinit var userRepository: FakeUserRepository
- private lateinit var userTracker: FakeUserTracker
- private lateinit var logBuffer: LogBuffer
- private val testDispatcher = StandardTestDispatcher()
- private val testScope = TestScope(testDispatcher)
+ private lateinit var underTest: CommunalTutorialRepositoryImpl
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- logBuffer = FakeLogBuffer.Factory.create()
secureSettings = FakeSettings()
userRepository = FakeUserRepository()
val listOfUserInfo = listOf(MAIN_USER_INFO)
userRepository.setUserInfos(listOfUserInfo)
- userTracker = FakeUserTracker()
- userTracker.set(
- userInfos = listOfUserInfo,
- selectedUserIndex = 0,
- )
+ underTest =
+ CommunalTutorialRepositoryImpl(
+ kosmos.applicationCoroutineScope,
+ kosmos.testDispatcher,
+ userRepository,
+ secureSettings,
+ logcatLogBuffer("CommunalTutorialRepositoryImplTest"),
+ )
}
@Test
fun tutorialSettingState_defaultToNotStarted() =
testScope.runTest {
- val repository = initCommunalTutorialRepository()
- val tutorialSettingState = collectLastValue(repository.tutorialSettingState)()
+ val tutorialSettingState by collectLastValue(underTest.tutorialSettingState)
assertThat(tutorialSettingState)
.isEqualTo(Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED)
}
@@ -75,31 +77,55 @@ class CommunalTutorialRepositoryImplTest : SysuiTestCase() {
@Test
fun tutorialSettingState_whenTutorialSettingsUpdatedToStarted() =
testScope.runTest {
- val repository = initCommunalTutorialRepository()
- setTutorialStateSetting(Settings.Secure.HUB_MODE_TUTORIAL_STARTED)
- val tutorialSettingState = collectLastValue(repository.tutorialSettingState)()
+ underTest.setTutorialState(Settings.Secure.HUB_MODE_TUTORIAL_STARTED)
+ val tutorialSettingState by collectLastValue(underTest.tutorialSettingState)
assertThat(tutorialSettingState).isEqualTo(Settings.Secure.HUB_MODE_TUTORIAL_STARTED)
}
@Test
fun tutorialSettingState_whenTutorialSettingsUpdatedToCompleted() =
testScope.runTest {
- val repository = initCommunalTutorialRepository()
- setTutorialStateSetting(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
- val tutorialSettingState = collectLastValue(repository.tutorialSettingState)()
+ underTest.setTutorialState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+ val tutorialSettingState by collectLastValue(underTest.tutorialSettingState)
assertThat(tutorialSettingState).isEqualTo(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
}
- private fun initCommunalTutorialRepository(): CommunalTutorialRepositoryImpl {
- return CommunalTutorialRepositoryImpl(
- testScope.backgroundScope,
- testDispatcher,
- userRepository,
- secureSettings,
- userTracker,
- logBuffer
- )
- }
+ @Test
+ fun tutorialVersion_userCompletedCurrentVersion_stateCompleted() =
+ testScope.runTest {
+ // User completed the current version.
+ setTutorialStateSetting(CURRENT_TUTORIAL_VERSION)
+
+ // Verify tutorial state is completed.
+ val tutorialSettingState by collectLastValue(underTest.tutorialSettingState)
+ assertThat(tutorialSettingState).isEqualTo(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+ }
+
+ @Test
+ fun tutorialVersion_userCompletedPreviousVersion_stateNotStarted() =
+ testScope.runTest {
+ // User completed the previous version.
+ setTutorialStateSetting(CURRENT_TUTORIAL_VERSION - 1)
+
+ // Verify tutorial state is not started.
+ val tutorialSettingState by collectLastValue(underTest.tutorialSettingState)
+ assertThat(tutorialSettingState)
+ .isEqualTo(Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED)
+ }
+
+ @Test
+ fun tutorialVersion_uponTutorialCompletion_writeCurrentVersion() =
+ testScope.runTest {
+ // Tutorial not started.
+ setTutorialStateSetting(Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED)
+
+ // Tutorial completed.
+ underTest.setTutorialState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+
+ // Verify tutorial setting state is updated to current version.
+ val settingState = getTutorialStateSetting()
+ assertThat(settingState).isEqualTo(CURRENT_TUTORIAL_VERSION)
+ }
private fun setTutorialStateSetting(
@Settings.Secure.HubModeTutorialState state: Int,
@@ -108,6 +134,10 @@ class CommunalTutorialRepositoryImplTest : SysuiTestCase() {
secureSettings.putIntForUser(Settings.Secure.HUB_MODE_TUTORIAL_STATE, state, user.id)
}
+ private fun getTutorialStateSetting(user: UserInfo = MAIN_USER_INFO): Int {
+ return secureSettings.getIntForUser(Settings.Secure.HUB_MODE_TUTORIAL_STATE, user.id)
+ }
+
companion object {
private val MAIN_USER_INFO =
UserInfo(/* id= */ 0, /* name= */ "primary", /* flags= */ UserInfo.FLAG_MAIN)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepository.kt
index 9a9b0e29cbc4..046aaaa33342 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepository.kt
@@ -16,6 +16,7 @@
package com.android.systemui.communal.data.repository
import android.provider.Settings
+import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED
import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED
import android.provider.Settings.Secure.HubModeTutorialState
import com.android.systemui.dagger.SysUISingleton
@@ -24,7 +25,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
-import com.android.systemui.settings.UserTracker
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
@@ -35,6 +35,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -62,14 +63,19 @@ class CommunalTutorialRepositoryImpl
constructor(
@Application private val applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
- userRepository: UserRepository,
+ private val userRepository: UserRepository,
private val secureSettings: SecureSettings,
- private val userTracker: UserTracker,
@CommunalLog logBuffer: LogBuffer,
) : CommunalTutorialRepository {
companion object {
private const val TAG = "CommunalTutorialRepository"
+
+ const val MIN_TUTORIAL_VERSION = HUB_MODE_TUTORIAL_COMPLETED
+
+ // A version number which ensures that users, regardless of their completion of previous
+ // versions, see the updated tutorial when this number is bumped.
+ const val CURRENT_TUTORIAL_VERSION = MIN_TUTORIAL_VERSION + 1
}
private data class SettingsState(
@@ -80,7 +86,7 @@ constructor(
private val settingsState: Flow<SettingsState> =
userRepository.selectedUserInfo
- .flatMapLatest { observeSettings() }
+ .flatMapLatest { userInfo -> observeSettings(userInfo.id) }
.shareIn(scope = applicationScope, started = SharingStarted.WhileSubscribed())
/** Emits the state of tutorial state in settings */
@@ -91,31 +97,37 @@ constructor(
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = HUB_MODE_TUTORIAL_NOT_STARTED
+ initialValue = HUB_MODE_TUTORIAL_NOT_STARTED,
)
- private fun observeSettings(): Flow<SettingsState> =
+ private fun observeSettings(userId: Int): Flow<SettingsState> =
secureSettings
.observerFlow(
- userId = userTracker.userId,
- names =
- arrayOf(
- Settings.Secure.HUB_MODE_TUTORIAL_STATE,
- )
+ userId = userId,
+ names = arrayOf(Settings.Secure.HUB_MODE_TUTORIAL_STATE),
)
// Force an update
.onStart { emit(Unit) }
- .map { readFromSettings() }
+ .map { readFromSettings(userId) }
- private suspend fun readFromSettings(): SettingsState =
+ private suspend fun readFromSettings(userId: Int): SettingsState =
withContext(backgroundDispatcher) {
- val userId = userTracker.userId
- val hubModeTutorialState =
+ var hubModeTutorialState =
secureSettings.getIntForUser(
Settings.Secure.HUB_MODE_TUTORIAL_STATE,
HUB_MODE_TUTORIAL_NOT_STARTED,
userId,
)
+
+ if (hubModeTutorialState >= CURRENT_TUTORIAL_VERSION) {
+ // Tutorial is considered "completed" if the user has completed the current or a
+ // newer version.
+ hubModeTutorialState = HUB_MODE_TUTORIAL_COMPLETED
+ } else if (hubModeTutorialState >= MIN_TUTORIAL_VERSION) {
+ // Tutorial is considered "not started" if the user completed a version older than
+ // the current.
+ hubModeTutorialState = HUB_MODE_TUTORIAL_NOT_STARTED
+ }
val settingsState = SettingsState(hubModeTutorialState)
logger.d({ "Communal tutorial state for user $int1 in settings: $str1" }) {
int1 = userId
@@ -127,18 +139,40 @@ constructor(
override suspend fun setTutorialState(state: Int): Unit =
withContext(backgroundDispatcher) {
- val userId = userTracker.userId
+ val userId = userRepository.getSelectedUserInfo().id
if (tutorialSettingState.value == state) {
return@withContext
}
+ val newState =
+ if (state == HUB_MODE_TUTORIAL_COMPLETED) CURRENT_TUTORIAL_VERSION else state
logger.d({ "Update communal tutorial state to $int1 for user $int2" }) {
- int1 = state
+ int1 = newState
int2 = userId
}
secureSettings.putIntForUser(
Settings.Secure.HUB_MODE_TUTORIAL_STATE,
- state,
+ newState,
userId,
)
}
}
+
+// TODO(b/320769333): delete me and use the real repo above when tutorial is ready.
+@SysUISingleton
+class CommunalTutorialDisabledRepositoryImpl
+@Inject
+constructor(
+ @Application private val applicationScope: CoroutineScope,
+) : CommunalTutorialRepository {
+ override val tutorialSettingState: StateFlow<Int> =
+ emptyFlow<Int>()
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = HUB_MODE_TUTORIAL_COMPLETED,
+ )
+
+ override suspend fun setTutorialState(state: Int) {
+ // Do nothing
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryModule.kt
index 69b0a27c55a8..b4f838ad5567 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalTutorialRepositoryModule.kt
@@ -22,6 +22,9 @@ import dagger.Module
@Module
interface CommunalTutorialRepositoryModule {
+ // TODO(b/320769333): use [CommunalTutorialRepositoryImpl] when tutorial is ready.
@Binds
- fun communalTutorialRepository(impl: CommunalTutorialRepositoryImpl): CommunalTutorialRepository
+ fun communalTutorialRepository(
+ impl: CommunalTutorialDisabledRepositoryImpl
+ ): CommunalTutorialRepository
}