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

Commit 25ebb742 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Schedule OOBE and handle disconnection" into main

parents 714362ce 6d6d6f5d
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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()
        }
    }
}
+27 −0
Original line number Diff line number Diff line
/*
 * 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
}
+97 −0
Original line number Diff line number Diff line
@@ -20,39 +20,78 @@ 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 keyboards or touchpads are connected, schedule a tutorial after given time has elapsed */
/**
 * 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 OobeTutorialSchedulerInteractor
class OobeSchedulerInteractor
@Inject
constructor(
    @Application private val context: Context,
    @Application private val applicationScope: CoroutineScope,
    keyboardRepository: KeyboardRepository,
    touchpadRepository: TouchpadRepository
    private val keyboardRepository: KeyboardRepository,
    private val touchpadRepository: TouchpadRepository
) {
    private val isAnyKeyboardConnected = keyboardRepository.isAnyKeyboardConnected
    private val isAnyTouchpadConnected = touchpadRepository.isAnyTouchpadConnected
    private val info = OobeSchedulerInfo()

    fun start() {
        applicationScope.launch { isAnyKeyboardConnected.collect { startOobe() } }
        applicationScope.launch { isAnyTouchpadConnected.collect { startOobe() } }
        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 startOobe() {
    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()
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -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
}