diff options
5 files changed, 129 insertions, 62 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt index dbfea7688e0d..701d3da1ee66 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt @@ -18,7 +18,7 @@ package com.android.systemui.inputdevice.oobe import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.inputdevice.oobe.domain.interactor.OobeTutorialSchedulerInteractor +import com.android.systemui.inputdevice.oobe.domain.interactor.OobeSchedulerInteractor import com.android.systemui.shared.Flags.newTouchpadGesturesTutorial import dagger.Lazy import javax.inject.Inject @@ -27,11 +27,10 @@ import javax.inject.Inject @SysUISingleton class KeyboardTouchpadOobeTutorialCoreStartable @Inject -constructor(private val oobeTutorialSchedulerInteractor: Lazy<OobeTutorialSchedulerInteractor>) : - CoreStartable { +constructor(private val oobeSchedulerInteractor: Lazy<OobeSchedulerInteractor>) : CoreStartable { override fun start() { if (newTouchpadGesturesTutorial()) { - oobeTutorialSchedulerInteractor.get().start() + oobeSchedulerInteractor.get().start() } } } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/data/model/OobeSchedulerInfo.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/data/model/OobeSchedulerInfo.kt new file mode 100644 index 000000000000..e5aedc031ebe --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/data/model/OobeSchedulerInfo.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.inputdevice.oobe.data.model + +data class OobeSchedulerInfo( + val keyboard: DeviceSchedulerInfo = DeviceSchedulerInfo(), + val touchpad: DeviceSchedulerInfo = DeviceSchedulerInfo() +) + +data class DeviceSchedulerInfo(var isLaunched: Boolean = false, var connectionTime: Long? = null) { + val wasEverConnected: Boolean + get() = connectionTime != null +} diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeSchedulerInteractor.kt new file mode 100644 index 000000000000..b014c08d4564 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeSchedulerInteractor.kt @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.inputdevice.oobe.domain.interactor + +import android.content.Context +import android.content.Intent +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.inputdevice.oobe.data.model.DeviceSchedulerInfo +import com.android.systemui.inputdevice.oobe.data.model.OobeSchedulerInfo +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 kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch + +/** + * When the first time a keyboard or touchpad id connected, wait for [LAUNCH_DELAY], then launch the + * tutorial as soon as there's a connected device + */ +@SysUISingleton +class OobeSchedulerInteractor +@Inject +constructor( + @Application private val context: Context, + @Application private val applicationScope: CoroutineScope, + private val keyboardRepository: KeyboardRepository, + private val touchpadRepository: TouchpadRepository +) { + private val info = OobeSchedulerInfo() + + fun start() { + if (!info.keyboard.isLaunched) { + applicationScope.launch { + schedule(keyboardRepository.isAnyKeyboardConnected, info.keyboard) + } + } + if (!info.touchpad.isLaunched) { + applicationScope.launch { + schedule(touchpadRepository.isAnyTouchpadConnected, info.touchpad) + } + } + } + + private suspend fun schedule(isAnyDeviceConnected: Flow<Boolean>, info: DeviceSchedulerInfo) { + if (!info.wasEverConnected) { + waitForDeviceConnection(isAnyDeviceConnected) + info.connectionTime = Instant.now().toEpochMilli() + } + delay(remainingTimeMillis(info.connectionTime!!)) + waitForDeviceConnection(isAnyDeviceConnected) + info.isLaunched = true + launchOobe() + } + + private suspend fun waitForDeviceConnection(isAnyDeviceConnected: Flow<Boolean>): Boolean { + return isAnyDeviceConnected.filter { it }.first() + } + + private fun launchOobe() { + val intent = Intent(TUTORIAL_ACTION) + intent.addCategory(Intent.CATEGORY_DEFAULT) + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) + } + + private fun remainingTimeMillis(start: Long): Long { + val elapsed = Instant.now().toEpochMilli() - start + return LAUNCH_DELAY - elapsed + } + + companion object { + const val TAG = "OobeSchedulerInteractor" + const val TUTORIAL_ACTION = "com.android.systemui.action.TOUCHPAD_TUTORIAL" + private val LAUNCH_DELAY = Duration.ofHours(72).toMillis() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeTutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeTutorialSchedulerInteractor.kt deleted file mode 100644 index 0d69081adfa4..000000000000 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeTutorialSchedulerInteractor.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.inputdevice.oobe.domain.interactor - -import android.content.Context -import android.content.Intent -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.keyboard.data.repository.KeyboardRepository -import com.android.systemui.touchpad.data.repository.TouchpadRepository -import javax.inject.Inject -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - -/** When keyboards or touchpads are connected, schedule a tutorial after given time has elapsed */ -@SysUISingleton -class OobeTutorialSchedulerInteractor -@Inject -constructor( - @Application private val context: Context, - @Application private val applicationScope: CoroutineScope, - keyboardRepository: KeyboardRepository, - touchpadRepository: TouchpadRepository -) { - private val isAnyKeyboardConnected = keyboardRepository.isAnyKeyboardConnected - private val isAnyTouchpadConnected = touchpadRepository.isAnyTouchpadConnected - - fun start() { - applicationScope.launch { isAnyKeyboardConnected.collect { startOobe() } } - applicationScope.launch { isAnyTouchpadConnected.collect { startOobe() } } - } - - private fun startOobe() { - val intent = Intent(TUTORIAL_ACTION) - intent.addCategory(Intent.CATEGORY_DEFAULT) - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) - } - - companion object { - const val TAG = "OobeSchedulerInteractor" - const val TUTORIAL_ACTION = "com.android.systemui.action.TOUCHPAD_TUTORIAL" - } -} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/TouchpadModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/TouchpadModule.kt index c86ac2f99a13..2f74d292f030 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/TouchpadModule.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/TouchpadModule.kt @@ -16,6 +16,7 @@ package com.android.systemui.touchpad +import com.android.systemui.dagger.SysUISingleton import com.android.systemui.touchpad.data.repository.TouchpadRepository import com.android.systemui.touchpad.data.repository.TouchpadRepositoryImpl import dagger.Binds @@ -25,5 +26,6 @@ import dagger.Module abstract class TouchpadModule { @Binds + @SysUISingleton abstract fun bindTouchpadRepository(repository: TouchpadRepositoryImpl): TouchpadRepository } |