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

Commit 123d5b3f authored by yyalan's avatar yyalan
Browse files

adb command launch notifications

With drive-by fix of the test so that the presubmit doesn't complain

Bug: 377652741
Flag: com.android.systemui.shared.new_touchpad_gestures_tutorial
Test: adb command
Change-Id: Iff04a913d38694c3e1f94979f2ff7cb6f2d984b4
parent f63aff71
Loading
Loading
Loading
Loading
+11 −12
Original line number Original line Diff line number Diff line
@@ -85,63 +85,62 @@ class TutorialSchedulerInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun connectKeyboard_delayElapse_launchForKeyboard() =
    fun connectKeyboard_delayElapse_launchForKeyboard() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.KEYBOARD)

            keyboardRepository.setIsAnyKeyboardConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(true)
            advanceTimeBy(LAUNCH_DELAY)
            advanceTimeBy(LAUNCH_DELAY)

            launchAndAssert(TutorialType.KEYBOARD)
        }
        }


    @Test
    @Test
    fun connectBothDevices_delayElapse_launchForBoth() =
    fun connectBothDevices_delayElapse_launchForBoth() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.BOTH)

            keyboardRepository.setIsAnyKeyboardConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            advanceTimeBy(LAUNCH_DELAY)
            advanceTimeBy(LAUNCH_DELAY)

            launchAndAssert(TutorialType.BOTH)
        }
        }


    @Test
    @Test
    fun connectBothDevice_delayNotElapse_launchNothing() =
    fun connectBothDevice_delayNotElapse_launchNothing() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.NONE)

            keyboardRepository.setIsAnyKeyboardConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)

            launchAndAssert(TutorialType.NONE)
        }
        }


    @Test
    @Test
    fun nothingConnect_delayElapse_launchNothing() =
    fun nothingConnect_delayElapse_launchNothing() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.NONE)

            keyboardRepository.setIsAnyKeyboardConnected(false)
            keyboardRepository.setIsAnyKeyboardConnected(false)
            touchpadRepository.setIsAnyTouchpadConnected(false)
            touchpadRepository.setIsAnyTouchpadConnected(false)
            advanceTimeBy(LAUNCH_DELAY)
            advanceTimeBy(LAUNCH_DELAY)

            launchAndAssert(TutorialType.NONE)
        }
        }


    @Test
    @Test
    fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() =
    fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.BOTH)

            keyboardRepository.setIsAnyKeyboardConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(true)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            advanceTimeBy(REMAINING_TIME)
            advanceTimeBy(REMAINING_TIME)

            launchAndAssert(TutorialType.BOTH)
        }
        }


    @Test
    @Test
    fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() =
    fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() =
        testScope.runTest {
        testScope.runTest {
            launchAndAssert(TutorialType.NONE)

            keyboardRepository.setIsAnyKeyboardConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(true)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
            advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            touchpadRepository.setIsAnyTouchpadConnected(true)
            keyboardRepository.setIsAnyKeyboardConnected(false)
            keyboardRepository.setIsAnyKeyboardConnected(false)
            advanceTimeBy(REMAINING_TIME)
            advanceTimeBy(REMAINING_TIME)
            launchAndAssert(TutorialType.NONE)
        }
        }


    private suspend fun launchAndAssert(expectedTutorial: TutorialType) =
    private suspend fun launchAndAssert(expectedTutorial: TutorialType) =
+16 −0
Original line number Original line Diff line number Diff line
@@ -17,12 +17,14 @@
package com.android.systemui.inputdevice.tutorial.domain.interactor
package com.android.systemui.inputdevice.tutorial.domain.interactor


import android.os.SystemProperties
import android.os.SystemProperties
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
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.KEYBOARD
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.Companion.LAUNCH_DELAY
import com.android.systemui.keyboard.data.repository.KeyboardRepository
import com.android.systemui.keyboard.data.repository.KeyboardRepository
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.commandline.CommandRegistry
@@ -35,6 +37,7 @@ import kotlin.time.Duration.Companion.hours
import kotlin.time.toKotlinDuration
import kotlin.time.toKotlinDuration
import kotlinx.coroutines.delay
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flow
@@ -96,6 +99,9 @@ constructor(
    private suspend fun waitForDeviceConnection(deviceType: DeviceType) =
    private suspend fun waitForDeviceConnection(deviceType: DeviceType) =
        isAnyDeviceConnected[deviceType]!!.filter { it }.first()
        isAnyDeviceConnected[deviceType]!!.filter { it }.first()


    // Only for testing notifications. This should behave independently from scheduling
    @VisibleForTesting val commandTutorials = MutableStateFlow(TutorialType.NONE)

    // Merging two flows ensures that tutorial is launched consecutively to avoid race condition
    // Merging two flows ensures that tutorial is launched consecutively to avoid race condition
    val tutorials: Flow<TutorialType> =
    val tutorials: Flow<TutorialType> =
        merge(touchpadScheduleFlow, keyboardScheduleFlow).map {
        merge(touchpadScheduleFlow, keyboardScheduleFlow).map {
@@ -146,6 +152,15 @@ constructor(
                        pw.println("Touchpad connect time = ${repo.firstConnectionTime(TOUCHPAD)}")
                        pw.println("Touchpad connect time = ${repo.firstConnectionTime(TOUCHPAD)}")
                        pw.println("         launch time = ${repo.launchTime(TOUCHPAD)}")
                        pw.println("         launch time = ${repo.launchTime(TOUCHPAD)}")
                    }
                    }
                "notify" -> {
                    if (args.size != 2) help(pw)
                    when (args[1]) {
                        "keyboard" -> commandTutorials.value = TutorialType.KEYBOARD
                        "touchpad" -> commandTutorials.value = TutorialType.TOUCHPAD
                        "both" -> commandTutorials.value = TutorialType.BOTH
                        else -> help(pw)
                    }
                }
                else -> help(pw)
                else -> help(pw)
            }
            }
        }
        }
@@ -155,6 +170,7 @@ constructor(
            pw.println("Available commands:")
            pw.println("Available commands:")
            pw.println("  clear")
            pw.println("  clear")
            pw.println("  info")
            pw.println("  info")
            pw.println("  notify [keyboard|touchpad|both]")
        }
        }
    }
    }


+7 −2
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Context
import android.content.Intent
import android.content.Intent
import android.os.Bundle
import android.os.Bundle
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Background
@@ -41,7 +42,7 @@ import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.flow.merge


/** When the scheduler is due, show a notification to launch tutorial */
/** When the scheduler is due, show a notification to launch tutorial */
@SysUISingleton
@SysUISingleton
@@ -56,7 +57,11 @@ constructor(
) {
) {
    fun start() {
    fun start() {
        backgroundScope.launch {
        backgroundScope.launch {
            tutorialSchedulerInteractor.tutorials.collect { showNotification(it) }
            merge(
                    tutorialSchedulerInteractor.tutorials,
                    tutorialSchedulerInteractor.commandTutorials,
                )
                .collect { showNotification(it) }
        }
        }
    }
    }


+2 −1
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import androidx.compose.runtime.getValue
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.lifecycleScope
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.theme.PlatformTheme
import com.android.compose.theme.PlatformTheme
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger.TutorialContext
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger.TutorialContext
@@ -40,7 +41,6 @@ import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTUR
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
import java.util.Optional
import java.util.Optional
import javax.inject.Inject
import javax.inject.Inject
import com.android.app.tracing.coroutines.launchTraced as launch


/**
/**
 * Activity for out of the box experience for keyboard and touchpad. Note that it's possible that
 * Activity for out of the box experience for keyboard and touchpad. Note that it's possible that
@@ -90,6 +90,7 @@ constructor(
        setContent {
        setContent {
            PlatformTheme { KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) }
            PlatformTheme { KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) }
        }
        }
        // TODO(b/376692701): Update launchTime when the activity is launched by Companion App
        if (savedInstanceState == null) {
        if (savedInstanceState == null) {
            metricsLogger.logPeripheralTutorialLaunched(
            metricsLogger.logPeripheralTutorialLaunched(
                intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY),
                intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY),