summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Helen Cheuk <helencheuk@google.com> 2024-09-11 08:23:10 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-09-11 08:23:10 +0000
commit6501ca315efe4bddaac97ed2bfa0334b7858875a (patch)
treeebb9eb242c034a2b9352a5e73e57af0c20957400
parentf8481647d19d25043cb1fc3a60265243ef85e170 (diff)
parent931f02d95d53fa18bcf1f602a6e53aa2cc3c7c31 (diff)
Merge "[Contextual Edu] Check if initial delay is elapsed before updating signal count" into main
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt37
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt5
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialKosmos.kt12
4 files changed, 117 insertions, 7 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
index c4fc13227eef..98e09474d5f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
@@ -24,12 +24,17 @@ import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.education.data.repository.contextualEducationRepository
import com.android.systemui.education.data.repository.fakeEduClock
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
+import com.android.systemui.inputdevice.tutorial.tutorialSchedulerRepository
import com.android.systemui.keyboard.data.repository.keyboardRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.touchpad.data.repository.touchpadRepository
import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
+import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
@@ -42,10 +47,15 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
private val keyboardRepository = kosmos.keyboardRepository
private val touchpadRepository = kosmos.touchpadRepository
private val repository = kosmos.contextualEducationRepository
+ private val fakeClock = kosmos.fakeEduClock
+ private val tutorialSchedulerRepository = kosmos.tutorialSchedulerRepository
+ private val initialDelayElapsedDuration =
+ KeyboardTouchpadEduStatsInteractorImpl.initialDelayDuration + 1.seconds
@Test
fun dataUpdatedOnIncrementSignalCountWhenTouchpadConnected() =
testScope.runTest {
+ setUpForInitialDelayElapse()
touchpadRepository.setIsAnyTouchpadConnected(true)
val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
@@ -58,6 +68,7 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
@Test
fun dataUnchangedOnIncrementSignalCountWhenTouchpadDisconnected() =
testScope.runTest {
+ setUpForInitialDelayElapse()
touchpadRepository.setIsAnyTouchpadConnected(false)
val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
@@ -70,6 +81,7 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
@Test
fun dataUpdatedOnIncrementSignalCountWhenKeyboardConnected() =
testScope.runTest {
+ setUpForInitialDelayElapse()
keyboardRepository.setIsAnyKeyboardConnected(true)
val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS))
@@ -82,6 +94,7 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
@Test
fun dataUnchangedOnIncrementSignalCountWhenKeyboardDisconnected() =
testScope.runTest {
+ setUpForInitialDelayElapse()
keyboardRepository.setIsAnyKeyboardConnected(false)
val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS))
@@ -99,4 +112,61 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
underTest.updateShortcutTriggerTime(BACK)
assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant())
}
+
+ @Test
+ fun dataUpdatedOnIncrementSignalCountAfterInitialDelay() =
+ testScope.runTest {
+ setUpForDeviceConnection()
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, fakeClock.instant())
+
+ fakeClock.offset(initialDelayElapsedDuration)
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(BACK)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountBeforeInitialDelay() =
+ testScope.runTest {
+ setUpForDeviceConnection()
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, fakeClock.instant())
+
+ // No offset to the clock to simulate update before initial delay
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(BACK)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountWithoutOobeLaunchTime() =
+ testScope.runTest {
+ // No update to OOBE launch time to simulate no OOBE is launched yet
+ setUpForDeviceConnection()
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(BACK)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ private suspend fun setUpForInitialDelayElapse() {
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, fakeClock.instant())
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.KEYBOARD, fakeClock.instant())
+ fakeClock.offset(initialDelayElapsedDuration)
+ }
+
+ private fun setUpForDeviceConnection() {
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ }
+
+ @After
+ fun clear() {
+ testScope.launch { tutorialSchedulerRepository.clearDataStore() }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
index eb4eee204834..0e2d9b6a3ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
@@ -16,15 +16,23 @@
package com.android.systemui.education.domain.interactor
+import android.os.SystemProperties
import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.contextualeducation.GestureType.ALL_APPS
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.education.dagger.ContextualEducationModule.EduClock
import com.android.systemui.inputdevice.data.repository.UserInputDeviceRepository
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.KEYBOARD
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
+import java.time.Clock
import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.DurationUnit
+import kotlin.time.toDuration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
@@ -47,12 +55,24 @@ constructor(
@Background private val backgroundScope: CoroutineScope,
private val contextualEducationInteractor: ContextualEducationInteractor,
private val inputDeviceRepository: UserInputDeviceRepository,
+ private val tutorialRepository: TutorialSchedulerRepository,
+ @EduClock private val clock: Clock,
) : KeyboardTouchpadEduStatsInteractor {
+ companion object {
+ val initialDelayDuration: Duration
+ get() =
+ SystemProperties.getLong(
+ "persist.contextual_edu.initial_delay_sec",
+ /* defaultValue= */ 72.hours.inWholeSeconds
+ )
+ .toDuration(DurationUnit.SECONDS)
+ }
+
override fun incrementSignalCount(gestureType: GestureType) {
backgroundScope.launch {
val targetDevice = getTargetDevice(gestureType)
- if (isTargetDeviceConnected(targetDevice)) {
+ if (isTargetDeviceConnected(targetDevice) && hasInitialDelayElapsed(targetDevice)) {
contextualEducationInteractor.incrementSignalCount(gestureType)
}
}
@@ -65,12 +85,10 @@ constructor(
}
private suspend fun isTargetDeviceConnected(deviceType: DeviceType): Boolean {
- if (deviceType == KEYBOARD) {
- return inputDeviceRepository.isAnyKeyboardConnectedForUser.first().isConnected
- } else if (deviceType == TOUCHPAD) {
- return inputDeviceRepository.isAnyTouchpadConnectedForUser.first().isConnected
+ return when (deviceType) {
+ KEYBOARD -> inputDeviceRepository.isAnyKeyboardConnectedForUser.first().isConnected
+ TOUCHPAD -> inputDeviceRepository.isAnyTouchpadConnectedForUser.first().isConnected
}
- return false
}
/**
@@ -83,4 +101,11 @@ constructor(
ALL_APPS -> KEYBOARD
else -> TOUCHPAD
}
+
+ private suspend fun hasInitialDelayElapsed(deviceType: DeviceType): Boolean {
+ val oobeLaunchTime = tutorialRepository.launchTime(deviceType) ?: return false
+ return clock
+ .instant()
+ .isAfter(oobeLaunchTime.plusSeconds(initialDelayDuration.inWholeSeconds))
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
index 251a6b10a0da..80f6fc24ef2c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.education.domain.interactor
import android.hardware.input.InputManager
import com.android.systemui.education.data.repository.fakeEduClock
import com.android.systemui.inputdevice.data.repository.UserInputDeviceRepository
+import com.android.systemui.inputdevice.tutorial.tutorialSchedulerRepository
import com.android.systemui.keyboard.data.repository.keyboardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
@@ -57,6 +58,8 @@ var Kosmos.keyboardTouchpadEduStatsInteractor by
keyboardRepository,
touchpadRepository,
userRepository
- )
+ ),
+ tutorialSchedulerRepository,
+ fakeEduClock
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialKosmos.kt
index 827f0d277d11..a83baffd78b2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialKosmos.kt
@@ -16,8 +16,20 @@
package com.android.systemui.inputdevice.tutorial
+import android.content.applicationContext
+import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
import org.mockito.kotlin.mock
var Kosmos.inputDeviceTutorialLogger: InputDeviceTutorialLogger by
Kosmos.Fixture { mock<InputDeviceTutorialLogger>() }
+
+var Kosmos.tutorialSchedulerRepository by
+ Kosmos.Fixture {
+ TutorialSchedulerRepository(
+ applicationContext = applicationContext,
+ testScope.backgroundScope,
+ "KosmosTutorialSchedulerRepository"
+ )
+ }