Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03ca983d authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12243840 from 4b33340b to 24Q4-release

Change-Id: I84e0691fbba2d47cd17bef7e495cb5986aa33b65
parents bb6d6e51 4b33340b
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -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
}
+18 −14
Original line number Diff line number Diff line
@@ -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"
    }
}

+16 −12
Original line number Diff line number Diff line
@@ -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() =
                Duration.ofSeconds(
                    SystemProperties.getLong(
                    "persist.peripheral_tutorial_delay_ms",
                    DEFAULT_LAUNCH_DELAY
                        "persist.peripheral_tutorial_delay_sec",
                        DEFAULT_LAUNCH_DELAY_SEC
                    )
                )
    }

+7 −4
Original line number Diff line number Diff line
@@ -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()
        }
}