mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-04 09:56:49 +00:00
Merge "Register all apps key gesture event in quickstep launcher" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
a2b5b589dc
@@ -35,6 +35,7 @@ import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
|
||||
import com.android.launcher3.util.TestUtil
|
||||
import com.android.quickstep.AllAppsActionManager
|
||||
import com.android.quickstep.fallback.window.RecentsDisplayModel
|
||||
import com.android.quickstep.input.QuickstepKeyGestureEventsManager
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.util.Locale
|
||||
@@ -108,7 +109,11 @@ class TaskbarUnitTestRule(
|
||||
object :
|
||||
TaskbarManager(
|
||||
context,
|
||||
AllAppsActionManager(context, UI_HELPER_EXECUTOR) {
|
||||
AllAppsActionManager(
|
||||
context,
|
||||
UI_HELPER_EXECUTOR,
|
||||
QuickstepKeyGestureEventsManager(context),
|
||||
) {
|
||||
PendingIntent(IIntentSender.Default())
|
||||
},
|
||||
object : TaskbarNavButtonCallbacks {},
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.quickstep
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.IIntentSender
|
||||
import android.hardware.input.InputManager
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.Secure.USER_SETUP_COMPLETE
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
@@ -29,6 +30,7 @@ import com.android.launcher3.util.SandboxApplication
|
||||
import com.android.launcher3.util.SettingsCache
|
||||
import com.android.launcher3.util.SettingsCacheSandbox
|
||||
import com.android.launcher3.util.TestUtil
|
||||
import com.android.quickstep.input.QuickstepKeyGestureEventsManager
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
@@ -39,6 +41,11 @@ import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
private const val TIMEOUT = 5L
|
||||
private val USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(USER_SETUP_COMPLETE)
|
||||
@@ -49,24 +56,29 @@ class AllAppsActionManagerTest {
|
||||
private val bgExecutor = UI_HELPER_EXECUTOR
|
||||
|
||||
@get:Rule val context = SandboxApplication()
|
||||
private val inputManager = context.spyService(InputManager::class.java)
|
||||
|
||||
private val settingsCacheSandbox =
|
||||
SettingsCacheSandbox().also { it[USER_SETUP_COMPLETE_URI] = 1 }
|
||||
private val quickstepKeyGestureEventsManager = spy(QuickstepKeyGestureEventsManager(context))
|
||||
|
||||
private val allAppsActionManager by
|
||||
lazy(LazyThreadSafetyMode.NONE) {
|
||||
AllAppsActionManager(context, bgExecutor) {
|
||||
AllAppsActionManager(context, bgExecutor, quickstepKeyGestureEventsManager) {
|
||||
callbackSemaphore.release()
|
||||
PendingIntent(IIntentSender.Default())
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
fun initDaggerComponent() {
|
||||
fun setUp() {
|
||||
context.initDaggerComponent(
|
||||
DaggerAllAppsActionManagerTestComponent.builder()
|
||||
.bindSettingsCache(settingsCacheSandbox.cache)
|
||||
)
|
||||
|
||||
doNothing().whenever(inputManager).registerKeyGestureEventHandler(any(), any())
|
||||
doNothing().whenever(inputManager).unregisterKeyGestureEventHandler(any())
|
||||
}
|
||||
|
||||
@After fun destroyManager() = allAppsActionManager.onDestroy()
|
||||
@@ -74,15 +86,19 @@ class AllAppsActionManagerTest {
|
||||
@Test
|
||||
fun taskbarPresent_actionRegistered() {
|
||||
allAppsActionManager.isTaskbarPresent = true
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to register.
|
||||
assertThat(callbackSemaphore.tryAcquire(TIMEOUT, SECONDS)).isTrue()
|
||||
assertThat(allAppsActionManager.isActionRegistered).isTrue()
|
||||
verify(quickstepKeyGestureEventsManager).registerAllAppsKeyGestureEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun homeAndOverviewSame_actionRegistered() {
|
||||
allAppsActionManager.isHomeAndOverviewSame = true
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to register.
|
||||
assertThat(callbackSemaphore.tryAcquire(TIMEOUT, SECONDS)).isTrue()
|
||||
assertThat(allAppsActionManager.isActionRegistered).isTrue()
|
||||
verify(quickstepKeyGestureEventsManager).registerAllAppsKeyGestureEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,6 +109,7 @@ class AllAppsActionManagerTest {
|
||||
allAppsActionManager.isTaskbarPresent = false
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to unregister.
|
||||
assertThat(allAppsActionManager.isActionRegistered).isFalse()
|
||||
verify(quickstepKeyGestureEventsManager).unregisterAllAppsKeyGestureEvent()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,6 +120,7 @@ class AllAppsActionManagerTest {
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to unregister.
|
||||
assertThat(callbackSemaphore.tryAcquire(TIMEOUT, SECONDS)).isTrue()
|
||||
assertThat(allAppsActionManager.isActionRegistered).isFalse()
|
||||
verify(quickstepKeyGestureEventsManager).unregisterAllAppsKeyGestureEvent()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -136,8 +154,10 @@ class AllAppsActionManagerTest {
|
||||
allAppsActionManager.isTaskbarPresent = true
|
||||
|
||||
settingsCacheSandbox[USER_SETUP_COMPLETE_URI] = 1
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to register.
|
||||
assertThat(callbackSemaphore.tryAcquire(TIMEOUT, SECONDS)).isTrue()
|
||||
assertThat(allAppsActionManager.isActionRegistered).isTrue()
|
||||
verify(quickstepKeyGestureEventsManager).registerAllAppsKeyGestureEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,8 +166,10 @@ class AllAppsActionManagerTest {
|
||||
allAppsActionManager.isTaskbarPresent = true
|
||||
|
||||
allAppsActionManager.isSetupUiVisible = false
|
||||
TestUtil.runOnExecutorSync(bgExecutor) {} // Force system action to register.
|
||||
assertThat(callbackSemaphore.tryAcquire(TIMEOUT, SECONDS)).isTrue()
|
||||
assertThat(allAppsActionManager.isActionRegistered).isTrue()
|
||||
verify(quickstepKeyGestureEventsManager).registerAllAppsKeyGestureEvent(any())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.quickstep.input
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.hardware.input.InputManager
|
||||
import android.hardware.input.KeyGestureEvent
|
||||
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
|
||||
import android.os.Bundle
|
||||
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.taskbar.TaskbarManager.EXTRA_KEY_ALL_APPS_ACTION_DISPLAY_ID
|
||||
import com.android.launcher3.util.SandboxApplication
|
||||
import com.android.window.flags.Flags
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.KArgumentCaptor
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class QuickstepKeyGestureEventsHandlerTest {
|
||||
@get:Rule val context = SandboxApplication()
|
||||
|
||||
@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 bundleCaptor: KArgumentCaptor<Bundle> = argumentCaptor()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
doNothing().whenever(inputManager).registerKeyGestureEventHandler(any(), any())
|
||||
doNothing().whenever(inputManager).unregisterKeyGestureEventHandler(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun registerKeyGestureEventsHandler_flagEnabled_registerWithExpectedKeyGestureEvents() {
|
||||
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
|
||||
|
||||
verify(inputManager)
|
||||
.registerKeyGestureEventHandler(
|
||||
keyGestureEventsCaptor.capture(),
|
||||
eq(keyGestureEventsManager.allAppsKeyGestureEventHandler),
|
||||
)
|
||||
assertThat(keyGestureEventsCaptor.firstValue).containsExactly(KEY_GESTURE_TYPE_ALL_APPS)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun registerKeyGestureEventsHandler_flagDisabled_noRegister() {
|
||||
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
|
||||
|
||||
verifyNoInteractions(inputManager)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun unregisterKeyGestureEventsHandler_flagEnabled_unregisterHandler() {
|
||||
keyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
|
||||
|
||||
verify(inputManager)
|
||||
.unregisterKeyGestureEventHandler(
|
||||
eq(keyGestureEventsManager.allAppsKeyGestureEventHandler)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun unregisterKeyGestureEventsHandler_flagDisabled_noUnregister() {
|
||||
keyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
|
||||
|
||||
verifyNoInteractions(inputManager)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun handleEvent_flagEnabled_allApps_toggleAllAppsSearchWithDisplayId() {
|
||||
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
|
||||
|
||||
keyGestureEventsManager.allAppsKeyGestureEventHandler.handleKeyGestureEvent(
|
||||
KeyGestureEvent.Builder()
|
||||
.setDisplayId(TEST_DISPLAY_ID)
|
||||
.setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
|
||||
.build(),
|
||||
/* focusedToken= */ null,
|
||||
)
|
||||
|
||||
verify(allAppsPendingIntent).send(bundleCaptor.capture())
|
||||
assertThat(bundleCaptor.firstValue.getInt(EXTRA_KEY_ALL_APPS_ACTION_DISPLAY_ID))
|
||||
.isEqualTo(TEST_DISPLAY_ID)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_RECENTS)
|
||||
fun handleEvent_flagDisabled_allApps_noInteractionWithTaskbar() {
|
||||
keyGestureEventsManager.registerAllAppsKeyGestureEvent(allAppsPendingIntent)
|
||||
|
||||
keyGestureEventsManager.allAppsKeyGestureEventHandler.handleKeyGestureEvent(
|
||||
KeyGestureEvent.Builder()
|
||||
.setDisplayId(TEST_DISPLAY_ID)
|
||||
.setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
|
||||
.build(),
|
||||
/* focusedToken= */ null,
|
||||
)
|
||||
|
||||
verifyNoInteractions(allAppsPendingIntent)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TEST_DISPLAY_ID = 6789
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user