Merge "Register KEY_GESTURE_TYPE_RECENT_APPS[_SWITCHER] in the quickstep" into main

This commit is contained in:
Treehugger Robot
2025-04-29 04:53:12 -07:00
committed by Android (Google) Code Review
4 changed files with 385 additions and 11 deletions

View File

@@ -60,7 +60,8 @@ class AllAppsActionManagerTest {
private val settingsCacheSandbox =
SettingsCacheSandbox().also { it[USER_SETUP_COMPLETE_URI] = 1 }
private val quickstepKeyGestureEventsManager = spy(QuickstepKeyGestureEventsManager(context))
private val quickstepKeyGestureEventsManager by
lazy(LazyThreadSafetyMode.NONE) { spy(QuickstepKeyGestureEventsManager(context)) }
private val allAppsActionManager by
lazy(LazyThreadSafetyMode.NONE) {

View File

@@ -19,13 +19,22 @@ package com.android.quickstep.input
import android.app.PendingIntent
import android.hardware.input.InputManager
import android.hardware.input.KeyGestureEvent
import android.hardware.input.KeyGestureEvent.ACTION_GESTURE_COMPLETE
import android.hardware.input.KeyGestureEvent.ACTION_GESTURE_START
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.util.SandboxApplication
import com.android.quickstep.input.QuickstepKeyGestureEventsHandlerTest.FakeOverviewHandler.OverviewEvent
import com.android.quickstep.input.QuickstepKeyGestureEventsManager.OverviewGestureHandler
import com.android.quickstep.input.QuickstepKeyGestureEventsManager.OverviewGestureHandler.OverviewType
import com.android.quickstep.input.QuickstepKeyGestureEventsManager.OverviewGestureHandler.OverviewType.ALT_TAB
import com.android.quickstep.input.QuickstepKeyGestureEventsManager.OverviewGestureHandler.OverviewType.UNDEFINED
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -50,19 +59,22 @@ class QuickstepKeyGestureEventsHandlerTest {
@get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT)
private val inputManager = context.spyService(InputManager::class.java)
private val keyGestureEventsManager = QuickstepKeyGestureEventsManager(context)
private val allAppsPendingIntent: PendingIntent = mock()
private val keyGestureEventsCaptor: KArgumentCaptor<List<Int>> = argumentCaptor()
private val fakeOverviewHandler = FakeOverviewHandler()
private lateinit var keyGestureEventsManager: QuickstepKeyGestureEventsManager
@Before
fun setup() {
doNothing().whenever(inputManager).registerKeyGestureEventHandler(any(), any())
doNothing().whenever(inputManager).unregisterKeyGestureEventHandler(any())
keyGestureEventsManager = QuickstepKeyGestureEventsManager(context)
keyGestureEventsManager.onUserSetupCompleteListener.onSettingsChanged(/* isEnabled= */ true)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun registerKeyGestureEventsHandler_flagEnabled_registerWithExpectedKeyGestureEvents() {
fun registerAllAppsHandler_flagEnabled_registerWithExpectedKeyGestureEvents() {
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
verify(inputManager)
@@ -75,7 +87,7 @@ class QuickstepKeyGestureEventsHandlerTest {
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun registerKeyGestureEventsHandler_flagDisabled_noRegister() {
fun registerAllAppsHandler_flagDisabled_noRegister() {
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
verifyNoInteractions(inputManager)
@@ -83,7 +95,29 @@ class QuickstepKeyGestureEventsHandlerTest {
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun unregisterKeyGestureEventsHandler_flagEnabled_unregisterHandler() {
fun registerOverviewHandler_flagEnabled_registerWithExpectedKeyGestureEvents() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
verify(inputManager)
.registerKeyGestureEventHandler(
keyGestureEventsCaptor.capture(),
eq(keyGestureEventsManager.overviewKeyGestureEventHandler),
)
assertThat(keyGestureEventsCaptor.firstValue)
.containsExactly(KEY_GESTURE_TYPE_RECENT_APPS, KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun registerOverviewHandler_flagDisabled_noRegister() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
verifyNoInteractions(inputManager)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun unregisterAllAppsHandler_flagEnabled_unregisterHandler() {
keyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
verify(inputManager)
@@ -94,7 +128,7 @@ class QuickstepKeyGestureEventsHandlerTest {
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun unregisterKeyGestureEventsHandler_flagDisabled_noUnregister() {
fun unregisterAllAppsHandler_flagDisabled_noUnregister() {
keyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
verifyNoInteractions(inputManager)
@@ -102,7 +136,26 @@ class QuickstepKeyGestureEventsHandlerTest {
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleEvent_flagEnabled_allApps_toggleAllAppsSearch() {
fun unregisterOverviewHandler_flagEnabled_unregisterHandler() {
keyGestureEventsManager.unregisterOverviewKeyGestureEvent()
verify(inputManager)
.unregisterKeyGestureEventHandler(
eq(keyGestureEventsManager.overviewKeyGestureEventHandler)
)
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun unregisterOverviewHandler_flagDisabled_noUnregister() {
keyGestureEventsManager.unregisterOverviewKeyGestureEvent()
verifyNoInteractions(inputManager)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleAllAppsEvent_flagEnabled_toggleAllAppsSearch() {
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
keyGestureEventsManager.allAppsKeyGestureEventHandler.handleKeyGestureEvent(
@@ -117,8 +170,11 @@ class QuickstepKeyGestureEventsHandlerTest {
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleEvent_flagDisabled_allApps_noInteractionWithTaskbar() {
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleAllAppsEvent_flagEnabled_userSetupIncomplete_noInteractionWithTaskbar() {
keyGestureEventsManager.onUserSetupCompleteListener.onSettingsChanged(
/* isEnabled= */ false
)
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
keyGestureEventsManager.allAppsKeyGestureEventHandler.handleKeyGestureEvent(
@@ -132,6 +188,202 @@ class QuickstepKeyGestureEventsHandlerTest {
verifyNoInteractions(allAppsPendingIntent)
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleAllAppsEvent_flagDisabled_noInteractionWithTaskbar() {
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
keyGestureEventsManager.allAppsKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
.build(),
/* focusedToken= */ null,
)
verifyNoInteractions(allAppsPendingIntent)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsEvent_flagEnabled_showOverviewWithUndefinedType() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent)
.isEqualTo(OverviewEvent(shouldShowOverview = true, type = UNDEFINED))
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsEvent_userSetupIncomplete_noOverviewEventInFake() {
keyGestureEventsManager.onUserSetupCompleteListener.onSettingsChanged(
/* isEnabled= */ false
)
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsEvent_flagDisabled_noOverviewEventInFake() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherStartEvent_flagEnabled_showOverviewWithAltTabType() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_START)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent)
.isEqualTo(OverviewEvent(shouldShowOverview = true, type = ALT_TAB))
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherStartEvent_userSetupIncomplete_noOverviewEventInFake() {
keyGestureEventsManager.onUserSetupCompleteListener.onSettingsChanged(
/* isEnabled= */ false
)
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_START)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherStartEvent_flagDisabled_noOverviewEventInFake() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_START)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherCompleteEvent_flagEnabled_hideOverviewWithAltTabType() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent)
.isEqualTo(OverviewEvent(shouldShowOverview = false, type = ALT_TAB))
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherCompleteEvent_userSetupIncomplete_noOverviewEventInFake() {
keyGestureEventsManager.onUserSetupCompleteListener.onSettingsChanged(
/* isEnabled= */ false
)
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
fun handleRecentAppsSwitcherCompleteEvent_flagDisabled_noOverviewEventInFake() {
keyGestureEventsManager.registerOverviewKeyGestureEvent(fakeOverviewHandler)
keyGestureEventsManager.overviewKeyGestureEventHandler.handleKeyGestureEvent(
KeyGestureEvent.Builder()
.setDisplayId(TEST_DISPLAY_ID)
.setKeyGestureType(KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER)
.setAction(ACTION_GESTURE_COMPLETE)
.build(),
/* focusedToken= */ null,
)
assertThat(fakeOverviewHandler.overviewEvent).isNull()
}
private class FakeOverviewHandler : OverviewGestureHandler {
data class OverviewEvent(val shouldShowOverview: Boolean, val type: OverviewType)
var overviewEvent: OverviewEvent? = null
private set
override fun showOverview(type: OverviewType) {
overviewEvent = OverviewEvent(shouldShowOverview = true, type)
}
override fun hideOverview(type: OverviewType) {
overviewEvent = OverviewEvent(shouldShowOverview = false, type)
}
}
private companion object {
const val TEST_DISPLAY_ID = 6789
}