diff options
4 files changed, 59 insertions, 32 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt index 9f46846f0d91..1dbe83aeb64f 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt @@ -16,7 +16,23 @@ package com.android.systemui.inputdevice.tutorial.data.model -data class DeviceSchedulerInfo(var isLaunched: Boolean = false, var connectTime: Long? = null) { +import java.time.Instant + +data class DeviceSchedulerInfo( + var launchTime: Instant? = null, + var firstConnectionTime: Instant? = null +) { + constructor( + launchTimeSec: Long?, + firstConnectionTimeSec: Long? + ) : this( + launchTimeSec?.let { Instant.ofEpochSecond(it) }, + firstConnectionTimeSec?.let { Instant.ofEpochSecond(it) } + ) + val wasEverConnected: Boolean - get() = connectTime != null + get() = firstConnectionTime != null + + val isLaunched: Boolean + get() = launchTime != null } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt index 36b9ac70d290..d8d4bd686f07 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt @@ -20,7 +20,6 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.preferencesDataStore @@ -28,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.inputdevice.tutorial.data.model.DeviceSchedulerInfo +import java.time.Instant import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.first @@ -43,28 +43,31 @@ class TutorialSchedulerRepository( constructor( @Application applicationContext: Context, @Background backgroundScope: CoroutineScope - ) : this(applicationContext, backgroundScope, dataStoreName = "TutorialScheduler") + ) : this(applicationContext, backgroundScope, dataStoreName = DATASTORE_NAME) private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = dataStoreName, scope = backgroundScope) suspend fun isLaunched(deviceType: DeviceType): Boolean = loadData()[deviceType]!!.isLaunched + suspend fun launchTime(deviceType: DeviceType): Instant? = loadData()[deviceType]!!.launchTime + suspend fun wasEverConnected(deviceType: DeviceType): Boolean = loadData()[deviceType]!!.wasEverConnected - suspend fun connectTime(deviceType: DeviceType): Long = loadData()[deviceType]!!.connectTime!! + suspend fun firstConnectionTime(deviceType: DeviceType): Instant? = + loadData()[deviceType]!!.firstConnectionTime private suspend fun loadData(): Map<DeviceType, DeviceSchedulerInfo> { return applicationContext.dataStore.data.map { pref -> getSchedulerInfo(pref) }.first() } - suspend fun updateConnectTime(device: DeviceType, time: Long) { - applicationContext.dataStore.edit { pref -> pref[getConnectKey(device)] = time } + suspend fun updateFirstConnectionTime(device: DeviceType, time: Instant) { + applicationContext.dataStore.edit { pref -> pref[getConnectKey(device)] = time.epochSecond } } - suspend fun updateLaunch(device: DeviceType) { - applicationContext.dataStore.edit { pref -> pref[getLaunchedKey(device)] = true } + suspend fun updateLaunchTime(device: DeviceType, time: Instant) { + applicationContext.dataStore.edit { pref -> pref[getLaunchKey(device)] = time.epochSecond } } private fun getSchedulerInfo(pref: Preferences): Map<DeviceType, DeviceSchedulerInfo> { @@ -75,13 +78,13 @@ class TutorialSchedulerRepository( } private fun getDeviceSchedulerInfo(pref: Preferences, device: DeviceType): DeviceSchedulerInfo { - val isLaunched = pref[getLaunchedKey(device)] ?: false - val connectionTime = pref[getConnectKey(device)] ?: null - return DeviceSchedulerInfo(isLaunched, connectionTime) + val launchTime = pref[getLaunchKey(device)] + val connectionTime = pref[getConnectKey(device)] + return DeviceSchedulerInfo(launchTime, connectionTime) } - private fun getLaunchedKey(device: DeviceType) = - booleanPreferencesKey(device.name + IS_LAUNCHED_SUFFIX) + private fun getLaunchKey(device: DeviceType) = + longPreferencesKey(device.name + LAUNCH_TIME_SUFFIX) private fun getConnectKey(device: DeviceType) = longPreferencesKey(device.name + CONNECT_TIME_SUFFIX) @@ -92,8 +95,9 @@ class TutorialSchedulerRepository( } companion object { - const val IS_LAUNCHED_SUFFIX = "_IS_LAUNCHED" - const val CONNECT_TIME_SUFFIX = "_CONNECTED_TIME" + const val DATASTORE_NAME = "TutorialScheduler" + const val LAUNCH_TIME_SUFFIX = "_LAUNCH_TIME" + const val CONNECT_TIME_SUFFIX = "_CONNECT_TIME" } } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt index b3b8f21a4a4b..a8d7dad42a93 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt @@ -26,9 +26,11 @@ import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUC import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository import com.android.systemui.keyboard.data.repository.KeyboardRepository import com.android.systemui.touchpad.data.repository.TouchpadRepository +import java.time.Duration import java.time.Instant import javax.inject.Inject import kotlin.time.Duration.Companion.hours +import kotlin.time.toKotlinDuration import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.filter @@ -84,9 +86,9 @@ constructor( private suspend fun schedule(deviceType: DeviceType) { if (!repo.wasEverConnected(deviceType)) { waitForDeviceConnection(deviceType) - repo.updateConnectTime(deviceType, Instant.now().toEpochMilli()) + repo.updateFirstConnectionTime(deviceType, Instant.now()) } - delay(remainingTimeMillis(start = repo.connectTime(deviceType))) + delay(remainingTime(start = repo.firstConnectionTime(deviceType)!!)) waitForDeviceConnection(deviceType) } @@ -95,9 +97,9 @@ constructor( private suspend fun launchTutorial(tutorialType: TutorialType) { if (tutorialType == TutorialType.KEYBOARD || tutorialType == TutorialType.BOTH) - repo.updateLaunch(KEYBOARD) + repo.updateLaunchTime(KEYBOARD, Instant.now()) if (tutorialType == TutorialType.TOUCHPAD || tutorialType == TutorialType.BOTH) - repo.updateLaunch(TOUCHPAD) + repo.updateLaunchTime(TOUCHPAD, Instant.now()) // TODO: launch tutorial Log.d(TAG, "Launch tutorial for $tutorialType") } @@ -113,19 +115,21 @@ constructor( return if (deviceType == KEYBOARD) TutorialType.KEYBOARD else TutorialType.TOUCHPAD } - private fun remainingTimeMillis(start: Long): Long { - val elapsed = Instant.now().toEpochMilli() - start - return LAUNCH_DELAY - elapsed + private fun remainingTime(start: Instant): kotlin.time.Duration { + val elapsed = Duration.between(start, Instant.now()) + return LAUNCH_DELAY.minus(elapsed).toKotlinDuration() } companion object { const val TAG = "TutorialSchedulerInteractor" - private val DEFAULT_LAUNCH_DELAY = 72.hours.inWholeMilliseconds - private val LAUNCH_DELAY: Long + private val DEFAULT_LAUNCH_DELAY_SEC = 72.hours.inWholeSeconds + private val LAUNCH_DELAY: Duration get() = - SystemProperties.getLong( - "persist.peripheral_tutorial_delay_ms", - DEFAULT_LAUNCH_DELAY + Duration.ofSeconds( + SystemProperties.getLong( + "persist.peripheral_tutorial_delay_sec", + DEFAULT_LAUNCH_DELAY_SEC + ) ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt index 7583399c784a..1d96c4d67c77 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt @@ -68,20 +68,23 @@ class TutorialSchedulerRepositoryTest : SysuiTestCase() { @Test fun connectKeyboard() = testScope.runTest { - val now = Instant.now().toEpochMilli() - underTest.updateConnectTime(KEYBOARD, now) + val now = Instant.now() + underTest.updateFirstConnectionTime(KEYBOARD, now) assertThat(underTest.wasEverConnected(KEYBOARD)).isTrue() - assertThat(underTest.connectTime(KEYBOARD)).isEqualTo(now) + assertThat(underTest.firstConnectionTime(KEYBOARD)!!.epochSecond) + .isEqualTo(now.epochSecond) assertThat(underTest.wasEverConnected(TOUCHPAD)).isFalse() } @Test fun launchKeyboard() = testScope.runTest { - underTest.updateLaunch(KEYBOARD) + val now = Instant.now() + underTest.updateLaunchTime(KEYBOARD, now) assertThat(underTest.isLaunched(KEYBOARD)).isTrue() + assertThat(underTest.launchTime(KEYBOARD)!!.epochSecond).isEqualTo(now.epochSecond) assertThat(underTest.isLaunched(TOUCHPAD)).isFalse() } } |