diff options
4 files changed, 11 insertions, 253 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 8b5f59457e6e..cd0c58feebed 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 @@ -19,23 +19,16 @@ package com.android.systemui.education.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.contextualeducation.GestureType.ALL_APPS -import com.android.systemui.contextualeducation.GestureType.BACK import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.contextualeducation.GestureType.BACK import com.android.systemui.education.data.repository.contextualEducationRepository import com.android.systemui.education.data.repository.fakeEduClock -import com.android.systemui.inputdevice.data.model.UserDeviceConnectionStatus -import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat -import kotlin.time.Duration.Companion.seconds -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith -import org.mockito.kotlin.any -import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) @@ -43,190 +36,24 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val underTest = kosmos.keyboardTouchpadEduStatsInteractor - private val repository = kosmos.contextualEducationRepository - private val fakeClock = kosmos.fakeEduClock - private val initialDelayElapsedDuration = - KeyboardTouchpadEduStatsInteractorImpl.initialDelayDuration + 1.seconds - - @Test - fun dataUpdatedOnIncrementSignalCountWhenTouchpadConnected() = - testScope.runTest { - setUpForInitialDelayElapse() - whenever(mockUserInputDeviceRepository.isAnyTouchpadConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = true, userId = 0))) - - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(BACK) - - assertThat(model?.signalCount).isEqualTo(originalValue + 1) - } - - @Test - fun dataUnchangedOnIncrementSignalCountWhenTouchpadDisconnected() = - testScope.runTest { - setUpForInitialDelayElapse() - whenever(mockUserInputDeviceRepository.isAnyTouchpadConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = false, userId = 0))) - - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(BACK) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test - fun dataUpdatedOnIncrementSignalCountWhenKeyboardConnected() = - testScope.runTest { - setUpForInitialDelayElapse() - whenever(mockUserInputDeviceRepository.isAnyKeyboardConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = true, userId = 0))) - - val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(ALL_APPS) - - assertThat(model?.signalCount).isEqualTo(originalValue + 1) - } - - @Test - fun dataUnchangedOnIncrementSignalCountWhenKeyboardDisconnected() = - testScope.runTest { - setUpForInitialDelayElapse() - whenever(mockUserInputDeviceRepository.isAnyKeyboardConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = false, userId = 0))) - - val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(ALL_APPS) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test - fun dataUpdatedOnIncrementSignalCountAfterOobeLaunchInitialDelay() = - testScope.runTest { - setUpForDeviceConnection() - whenever(mockTutorialSchedulerRepository.launchTime(any<DeviceType>())) - .thenReturn(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 dataUnchangedOnIncrementSignalCountBeforeOobeLaunchInitialDelay() = + fun dataUpdatedOnIncrementSignalCount() = testScope.runTest { - setUpForDeviceConnection() - whenever(mockTutorialSchedulerRepository.launchTime(any<DeviceType>())) - .thenReturn(fakeClock.instant()) - - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) + val model by + collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK)) val originalValue = model!!.signalCount underTest.incrementSignalCount(BACK) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test - fun dataUpdatedOnIncrementSignalCountAfterTouchpadConnectionInitialDelay() = - testScope.runTest { - setUpForDeviceConnection() - repository.updateEduDeviceConnectionTime { model -> - model.copy(touchpadFirstConnectionTime = 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 dataUnchangedOnIncrementSignalCountBeforeTouchpadConnectionInitialDelay() = - testScope.runTest { - setUpForDeviceConnection() - repository.updateEduDeviceConnectionTime { model -> - model.copy(touchpadFirstConnectionTime = fakeClock.instant()) - } - - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(BACK) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test - fun dataUpdatedOnIncrementSignalCountAfterKeyboardConnectionInitialDelay() = - testScope.runTest { - setUpForDeviceConnection() - repository.updateEduDeviceConnectionTime { model -> - model.copy(keyboardFirstConnectionTime = fakeClock.instant()) - } - fakeClock.offset(initialDelayElapsedDuration) - - val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(ALL_APPS) - - assertThat(model?.signalCount).isEqualTo(originalValue + 1) - } - - @Test - fun dataUnchangedOnIncrementSignalCountBeforeKeyboardConnectionInitialDelay() = - testScope.runTest { - setUpForDeviceConnection() - repository.updateEduDeviceConnectionTime { model -> - model.copy(keyboardFirstConnectionTime = fakeClock.instant()) - } - - val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(ALL_APPS) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test - fun dataUnchangedOnIncrementSignalCountWhenNoSetupTime() = - testScope.runTest { - whenever(mockUserInputDeviceRepository.isAnyTouchpadConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = true, userId = 0))) - - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) - val originalValue = model!!.signalCount - underTest.incrementSignalCount(BACK) - - assertThat(model?.signalCount).isEqualTo(originalValue) - } - - @Test fun dataAddedOnUpdateShortcutTriggerTime() = testScope.runTest { - val model by collectLastValue(repository.readGestureEduModelFlow(BACK)) + val model by + collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK)) assertThat(model?.lastShortcutTriggeredTime).isNull() underTest.updateShortcutTriggerTime(BACK) assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant()) } - - private suspend fun setUpForInitialDelayElapse() { - whenever(mockTutorialSchedulerRepository.launchTime(any<DeviceType>())) - .thenReturn(fakeClock.instant()) - fakeClock.offset(initialDelayElapsedDuration) - } - - private fun setUpForDeviceConnection() { - whenever(mockUserInputDeviceRepository.isAnyTouchpadConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = true, userId = 0))) - whenever(mockUserInputDeviceRepository.isAnyKeyboardConnectedForUser) - .thenReturn(flowOf(UserDeviceConnectionStatus(isConnected = true, userId = 0))) - } } diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt index 3b2d77172393..3105527eb9b1 100644 --- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt @@ -83,7 +83,6 @@ constructor( } override fun start() { - // Listen to back gesture model changes and trigger education if needed backgroundScope.launch { contextualEducationInteractor.backGestureModelFlow.collect { if (isUsageSessionExpired(it)) { @@ -95,7 +94,6 @@ constructor( } } - // Listen to touchpad connection changes and update the first connection time backgroundScope.launch { userInputDeviceRepository.isAnyTouchpadConnectedForUser.collect { if ( @@ -109,7 +107,6 @@ constructor( } } - // Listen to keyboard connection changes and update the first connection time backgroundScope.launch { userInputDeviceRepository.isAnyKeyboardConnectedForUser.collect { if ( @@ -123,7 +120,6 @@ constructor( } } - // Listen to keyboard shortcut triggered and update the last trigger time backgroundScope.launch { keyboardShortcutTriggered.collect { contextualEducationInteractor.updateShortcutTriggerTime(it) 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 7821f6940da4..3223433568b9 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,25 +16,11 @@ 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 com.android.systemui.contextualeducation.GestureType 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 /** @@ -53,29 +39,12 @@ class KeyboardTouchpadEduStatsInteractorImpl @Inject constructor( @Background private val backgroundScope: CoroutineScope, - private val contextualEducationInteractor: ContextualEducationInteractor, - private val inputDeviceRepository: UserInputDeviceRepository, - private val tutorialRepository: TutorialSchedulerRepository, - @EduClock private val clock: Clock, + private val contextualEducationInteractor: ContextualEducationInteractor ) : 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) && hasInitialDelayElapsed(targetDevice)) { - contextualEducationInteractor.incrementSignalCount(gestureType) - } - } + // Todo: check if keyboard/touchpad is connected before update + backgroundScope.launch { contextualEducationInteractor.incrementSignalCount(gestureType) } } override fun updateShortcutTriggerTime(gestureType: GestureType) { @@ -83,31 +52,4 @@ constructor( contextualEducationInteractor.updateShortcutTriggerTime(gestureType) } } - - 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 false - } - - /** - * Keyboard shortcut education would be provided for All Apps. Touchpad gesture education would - * be provided for the rest of the gesture types (i.e. Home, Overview, Back). This method maps - * gesture to its target education device. - */ - private fun getTargetDevice(gestureType: GestureType) = - when (gestureType) { - 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 7ccacb66e124..811c6533c656 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,7 +19,6 @@ 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.data.repository.TutorialSchedulerRepository import com.android.systemui.keyboard.data.repository.keyboardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher @@ -51,12 +50,6 @@ var Kosmos.keyboardTouchpadEduStatsInteractor by Kosmos.Fixture { KeyboardTouchpadEduStatsInteractorImpl( backgroundScope = testScope.backgroundScope, - contextualEducationInteractor = contextualEducationInteractor, - inputDeviceRepository = mockUserInputDeviceRepository, - tutorialRepository = mockTutorialSchedulerRepository, - clock = fakeEduClock + contextualEducationInteractor = contextualEducationInteractor ) } - -var mockUserInputDeviceRepository = mock<UserInputDeviceRepository>() -var mockTutorialSchedulerRepository = mock<TutorialSchedulerRepository>() |