Loading packages/SystemUI/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,9 @@ is ready --> <uses-permission android:name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" /> <!-- To be able to decipher default applications for certain roles in shortcut helper --> <uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS" /> <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" /> Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapterTest.kt 0 → 100644 +195 −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.keyboard.shortcut.data.repository import android.app.role.RoleManager import android.app.role.roleManager import android.content.Context import android.content.Intent import android.content.mockedContext import android.content.packageManager import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.hardware.input.AppLaunchData import android.hardware.input.AppLaunchData.RoleData import android.hardware.input.InputGestureData import android.hardware.input.InputGestureData.createKeyTrigger import android.view.KeyEvent.KEYCODE_A import android.view.KeyEvent.META_ALT_ON import android.view.KeyEvent.META_CTRL_ON import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.app.ResolverActivity import com.android.systemui.SysuiTestCase import com.android.systemui.keyboard.shortcut.data.model.InternalGroupsSource import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo import com.android.systemui.keyboard.shortcut.inputGestureDataAdapter import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType import com.android.systemui.kosmos.runTest import com.android.systemui.res.R import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class InputGestureDataAdapterTest : SysuiTestCase() { private val kosmos = testKosmos().also { kosmos -> kosmos.userTracker = FakeUserTracker(onCreateCurrentUserContext = { kosmos.mockedContext }) } private val adapter = kosmos.inputGestureDataAdapter private val roleManager = kosmos.roleManager private val packageManager: PackageManager = kosmos.packageManager private val mockUserContext: Context = kosmos.mockedContext private val intent: Intent = mock() private val fakeResolverActivityInfo = ActivityInfo().apply { name = ResolverActivity::class.qualifiedName } private val fakeActivityInfo: ActivityInfo = ActivityInfo().apply { name = FAKE_ACTIVITY_NAME icon = 0x1 nonLocalizedLabel = TEST_SHORTCUT_LABEL } private val mockSelectorIntent: Intent = mock() @Before fun setup() { whenever(mockUserContext.packageManager).thenReturn(packageManager) whenever(mockUserContext.getSystemService(RoleManager::class.java)).thenReturn(roleManager) whenever(roleManager.isRoleAvailable(TEST_ROLE)).thenReturn(true) whenever(roleManager.getDefaultApplication(TEST_ROLE)).thenReturn(TEST_ROLE_PACKAGE) whenever(packageManager.getActivityInfo(any(), anyInt())).thenReturn(mock()) whenever(packageManager.getLaunchIntentForPackage(TEST_ROLE_PACKAGE)).thenReturn(intent) whenever(intent.selector).thenReturn(mockSelectorIntent) whenever(mockSelectorIntent.categories).thenReturn(setOf(TEST_ACTIVITY_CATEGORY)) } @Test fun shortcutLabel_whenDefaultAppForCategoryIsNotSet_loadsLabelFromFirstAppMatchingIntent() = kosmos.runTest { setApiToRetrieveResolverActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val label = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label assertThat(label).isEqualTo(expectedShortcutLabelForFirstAppMatchingIntent) } @Test fun shortcutLabel_whenDefaultAppForCategoryIsSet_loadsLabelOfDefaultApp() { kosmos.runTest { setApiToRetrieveSpecificActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val label = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label assertThat(label).isEqualTo(TEST_SHORTCUT_LABEL) } } @Test fun shortcutIcon_whenDefaultAppForCategoryIsSet_loadsIconOfDefaultApp() { kosmos.runTest { setApiToRetrieveSpecificActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val icon = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.icon assertThat(icon).isNotNull() } } @Test fun internalGroupSource_isCorrectlyConvertedWithSimpleInputGestureData() = kosmos.runTest { setApiToRetrieveResolverActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) assertThat(internalGroups).containsExactly( InternalGroupsSource( type = ShortcutCategoryType.AppCategories, groups = listOf( InternalKeyboardShortcutGroup( label = APPLICATION_SHORTCUT_GROUP_LABEL, items = listOf( InternalKeyboardShortcutInfo( label = expectedShortcutLabelForFirstAppMatchingIntent, keycode = KEYCODE_A, modifiers = META_CTRL_ON or META_ALT_ON, isCustomShortcut = true ) ) ) ) ) ) } private fun setApiToRetrieveResolverActivity() { whenever(intent.resolveActivityInfo(eq(packageManager), anyInt())) .thenReturn(fakeResolverActivityInfo) } private fun setApiToRetrieveSpecificActivity() { whenever(intent.resolveActivityInfo(eq(packageManager), anyInt())) .thenReturn(fakeActivityInfo) } private fun buildInputGestureDataForAppLaunchShortcut( keyCode: Int = KEYCODE_A, modifiers: Int = META_CTRL_ON or META_ALT_ON, appLaunchData: AppLaunchData = RoleData(TEST_ROLE) ): InputGestureData { return InputGestureData.Builder() .setTrigger(createKeyTrigger(keyCode, modifiers)) .setAppLaunchData(appLaunchData) .build() } private val expectedShortcutLabelForFirstAppMatchingIntent = context.getString(R.string.keyboard_shortcut_group_applications_browser) private companion object { private const val TEST_ROLE = "Test Browser Role" private const val TEST_ROLE_PACKAGE = "test.browser.package" private const val APPLICATION_SHORTCUT_GROUP_LABEL = "Applications" private const val FAKE_ACTIVITY_NAME = "Fake activity" private const val TEST_SHORTCUT_LABEL = "Test shortcut label" private const val TEST_ACTIVITY_CATEGORY = Intent.CATEGORY_APP_BROWSER } } packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt +0 −28 Original line number Diff line number Diff line Loading @@ -567,13 +567,6 @@ object TestShortcuts { ), simpleShortcutCategory(System, "System controls", "Show shortcuts"), simpleShortcutCategory(System, "System controls", "View recent apps"), simpleShortcutCategory(AppCategories, "Applications", "Calculator"), simpleShortcutCategory(AppCategories, "Applications", "Calendar"), simpleShortcutCategory(AppCategories, "Applications", "Browser"), simpleShortcutCategory(AppCategories, "Applications", "Contacts"), simpleShortcutCategory(AppCategories, "Applications", "Email"), simpleShortcutCategory(AppCategories, "Applications", "Maps"), simpleShortcutCategory(AppCategories, "Applications", "SMS"), ) val customInputGestureTypeHome = simpleInputGestureData(keyGestureType = KEY_GESTURE_TYPE_HOME) Loading Loading @@ -614,27 +607,6 @@ object TestShortcuts { keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER ), simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER ), Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.input.InputGestureData import android.view.KeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType /** * Internal Keyboard Shortcut models to use with [ShortcutCategoriesUtils.fetchShortcutCategory] Loading Loading @@ -55,3 +56,8 @@ data class InternalKeyboardShortcutInfo( val icon: Icon? = null, val isCustomShortcut: Boolean = false, ) data class InternalGroupsSource( val groups: List<InternalKeyboardShortcutGroup>, val type: ShortcutCategoryType, ) No newline at end of file packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt +6 −74 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.systemui.keyboard.shortcut.data.repository import android.content.Context import android.hardware.input.InputGestureData import android.hardware.input.InputGestureData.Builder import android.hardware.input.InputGestureData.KeyTrigger import android.hardware.input.InputGestureData.createKeyTrigger import android.hardware.input.InputManager import android.hardware.input.KeyGestureEvent.KeyGestureType Loading @@ -30,11 +28,8 @@ import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey Loading @@ -57,8 +52,7 @@ constructor( @Background private val backgroundScope: CoroutineScope, @Background private val bgCoroutineContext: CoroutineContext, private val shortcutCategoriesUtils: ShortcutCategoriesUtils, private val context: Context, private val inputGestureMaps: InputGestureMaps, private val inputGestureDataAdapter: InputGestureDataAdapter, private val customInputGesturesRepository: CustomInputGesturesRepository, private val inputManager: InputManager ) : ShortcutCategoriesRepository { Loading Loading @@ -116,7 +110,7 @@ constructor( if (inputDevice == null) { emptyList() } else { val sources = toInternalGroupSources(inputGestures) val sources = inputGestureDataAdapter.toInternalGroupSources(inputGestures) val supportedKeyCodes = shortcutCategoriesUtils.fetchSupportedKeyCodes( inputDevice.id, Loading Loading @@ -216,7 +210,8 @@ constructor( return null } return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label] return inputGestureDataAdapter .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label) } @KeyGestureType Loading @@ -232,7 +227,8 @@ constructor( return null } return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label] return inputGestureDataAdapter .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label) } private fun Builder.addTriggerFromSelectedKeyCombination(): Builder { Loading Loading @@ -261,70 +257,6 @@ constructor( return _shortcutBeingCustomized.value } private fun toInternalGroupSources( inputGestures: List<InputGestureData> ): List<InternalGroupsSource> { val ungroupedInternalGroupSources = inputGestures.mapNotNull { gestureData -> val keyTrigger = gestureData.trigger as KeyTrigger val keyGestureType = gestureData.action.keyGestureType() fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel -> toInternalKeyboardShortcutInfo(keyGestureType, keyTrigger)?.let { internalKeyboardShortcutInfo -> val group = InternalKeyboardShortcutGroup( label = groupLabel, items = listOf(internalKeyboardShortcutInfo), ) fetchShortcutCategoryTypeByGestureType(keyGestureType)?.let { InternalGroupsSource(groups = listOf(group), type = it) } } } } return ungroupedInternalGroupSources } private fun toInternalKeyboardShortcutInfo( keyGestureType: Int, keyTrigger: KeyTrigger, ): InternalKeyboardShortcutInfo? { fetchShortcutInfoLabelByGestureType(keyGestureType)?.let { return InternalKeyboardShortcutInfo( label = it, keycode = keyTrigger.keycode, modifiers = keyTrigger.modifierState, isCustomShortcut = true, ) } return null } private fun fetchGroupLabelByGestureType(@KeyGestureType keyGestureType: Int): String? { inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let { return context.getString(it) } ?: return null } private fun fetchShortcutInfoLabelByGestureType(@KeyGestureType keyGestureType: Int): String? { inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let { return context.getString(it) } ?: return null } private fun fetchShortcutCategoryTypeByGestureType( @KeyGestureType keyGestureType: Int ): ShortcutCategoryType? { return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType] } private data class InternalGroupsSource( val groups: List<InternalKeyboardShortcutGroup>, val type: ShortcutCategoryType, ) private companion object { private const val TAG = "CustomShortcutCategoriesRepository" } Loading Loading
packages/SystemUI/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,9 @@ is ready --> <uses-permission android:name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" /> <!-- To be able to decipher default applications for certain roles in shortcut helper --> <uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS" /> <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" /> Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapterTest.kt 0 → 100644 +195 −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.keyboard.shortcut.data.repository import android.app.role.RoleManager import android.app.role.roleManager import android.content.Context import android.content.Intent import android.content.mockedContext import android.content.packageManager import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.hardware.input.AppLaunchData import android.hardware.input.AppLaunchData.RoleData import android.hardware.input.InputGestureData import android.hardware.input.InputGestureData.createKeyTrigger import android.view.KeyEvent.KEYCODE_A import android.view.KeyEvent.META_ALT_ON import android.view.KeyEvent.META_CTRL_ON import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.app.ResolverActivity import com.android.systemui.SysuiTestCase import com.android.systemui.keyboard.shortcut.data.model.InternalGroupsSource import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo import com.android.systemui.keyboard.shortcut.inputGestureDataAdapter import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType import com.android.systemui.kosmos.runTest import com.android.systemui.res.R import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class InputGestureDataAdapterTest : SysuiTestCase() { private val kosmos = testKosmos().also { kosmos -> kosmos.userTracker = FakeUserTracker(onCreateCurrentUserContext = { kosmos.mockedContext }) } private val adapter = kosmos.inputGestureDataAdapter private val roleManager = kosmos.roleManager private val packageManager: PackageManager = kosmos.packageManager private val mockUserContext: Context = kosmos.mockedContext private val intent: Intent = mock() private val fakeResolverActivityInfo = ActivityInfo().apply { name = ResolverActivity::class.qualifiedName } private val fakeActivityInfo: ActivityInfo = ActivityInfo().apply { name = FAKE_ACTIVITY_NAME icon = 0x1 nonLocalizedLabel = TEST_SHORTCUT_LABEL } private val mockSelectorIntent: Intent = mock() @Before fun setup() { whenever(mockUserContext.packageManager).thenReturn(packageManager) whenever(mockUserContext.getSystemService(RoleManager::class.java)).thenReturn(roleManager) whenever(roleManager.isRoleAvailable(TEST_ROLE)).thenReturn(true) whenever(roleManager.getDefaultApplication(TEST_ROLE)).thenReturn(TEST_ROLE_PACKAGE) whenever(packageManager.getActivityInfo(any(), anyInt())).thenReturn(mock()) whenever(packageManager.getLaunchIntentForPackage(TEST_ROLE_PACKAGE)).thenReturn(intent) whenever(intent.selector).thenReturn(mockSelectorIntent) whenever(mockSelectorIntent.categories).thenReturn(setOf(TEST_ACTIVITY_CATEGORY)) } @Test fun shortcutLabel_whenDefaultAppForCategoryIsNotSet_loadsLabelFromFirstAppMatchingIntent() = kosmos.runTest { setApiToRetrieveResolverActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val label = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label assertThat(label).isEqualTo(expectedShortcutLabelForFirstAppMatchingIntent) } @Test fun shortcutLabel_whenDefaultAppForCategoryIsSet_loadsLabelOfDefaultApp() { kosmos.runTest { setApiToRetrieveSpecificActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val label = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label assertThat(label).isEqualTo(TEST_SHORTCUT_LABEL) } } @Test fun shortcutIcon_whenDefaultAppForCategoryIsSet_loadsIconOfDefaultApp() { kosmos.runTest { setApiToRetrieveSpecificActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) val icon = internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.icon assertThat(icon).isNotNull() } } @Test fun internalGroupSource_isCorrectlyConvertedWithSimpleInputGestureData() = kosmos.runTest { setApiToRetrieveResolverActivity() val inputGestureData = buildInputGestureDataForAppLaunchShortcut() val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData)) assertThat(internalGroups).containsExactly( InternalGroupsSource( type = ShortcutCategoryType.AppCategories, groups = listOf( InternalKeyboardShortcutGroup( label = APPLICATION_SHORTCUT_GROUP_LABEL, items = listOf( InternalKeyboardShortcutInfo( label = expectedShortcutLabelForFirstAppMatchingIntent, keycode = KEYCODE_A, modifiers = META_CTRL_ON or META_ALT_ON, isCustomShortcut = true ) ) ) ) ) ) } private fun setApiToRetrieveResolverActivity() { whenever(intent.resolveActivityInfo(eq(packageManager), anyInt())) .thenReturn(fakeResolverActivityInfo) } private fun setApiToRetrieveSpecificActivity() { whenever(intent.resolveActivityInfo(eq(packageManager), anyInt())) .thenReturn(fakeActivityInfo) } private fun buildInputGestureDataForAppLaunchShortcut( keyCode: Int = KEYCODE_A, modifiers: Int = META_CTRL_ON or META_ALT_ON, appLaunchData: AppLaunchData = RoleData(TEST_ROLE) ): InputGestureData { return InputGestureData.Builder() .setTrigger(createKeyTrigger(keyCode, modifiers)) .setAppLaunchData(appLaunchData) .build() } private val expectedShortcutLabelForFirstAppMatchingIntent = context.getString(R.string.keyboard_shortcut_group_applications_browser) private companion object { private const val TEST_ROLE = "Test Browser Role" private const val TEST_ROLE_PACKAGE = "test.browser.package" private const val APPLICATION_SHORTCUT_GROUP_LABEL = "Applications" private const val FAKE_ACTIVITY_NAME = "Fake activity" private const val TEST_SHORTCUT_LABEL = "Test shortcut label" private const val TEST_ACTIVITY_CATEGORY = Intent.CATEGORY_APP_BROWSER } }
packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt +0 −28 Original line number Diff line number Diff line Loading @@ -567,13 +567,6 @@ object TestShortcuts { ), simpleShortcutCategory(System, "System controls", "Show shortcuts"), simpleShortcutCategory(System, "System controls", "View recent apps"), simpleShortcutCategory(AppCategories, "Applications", "Calculator"), simpleShortcutCategory(AppCategories, "Applications", "Calendar"), simpleShortcutCategory(AppCategories, "Applications", "Browser"), simpleShortcutCategory(AppCategories, "Applications", "Contacts"), simpleShortcutCategory(AppCategories, "Applications", "Email"), simpleShortcutCategory(AppCategories, "Applications", "Maps"), simpleShortcutCategory(AppCategories, "Applications", "SMS"), ) val customInputGestureTypeHome = simpleInputGestureData(keyGestureType = KEY_GESTURE_TYPE_HOME) Loading Loading @@ -614,27 +607,6 @@ object TestShortcuts { keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER ), simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING ), simpleInputGestureData( keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER ), Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.input.InputGestureData import android.view.KeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType /** * Internal Keyboard Shortcut models to use with [ShortcutCategoriesUtils.fetchShortcutCategory] Loading Loading @@ -55,3 +56,8 @@ data class InternalKeyboardShortcutInfo( val icon: Icon? = null, val isCustomShortcut: Boolean = false, ) data class InternalGroupsSource( val groups: List<InternalKeyboardShortcutGroup>, val type: ShortcutCategoryType, ) No newline at end of file
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt +6 −74 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.systemui.keyboard.shortcut.data.repository import android.content.Context import android.hardware.input.InputGestureData import android.hardware.input.InputGestureData.Builder import android.hardware.input.InputGestureData.KeyTrigger import android.hardware.input.InputGestureData.createKeyTrigger import android.hardware.input.InputManager import android.hardware.input.KeyGestureEvent.KeyGestureType Loading @@ -30,11 +28,8 @@ import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey Loading @@ -57,8 +52,7 @@ constructor( @Background private val backgroundScope: CoroutineScope, @Background private val bgCoroutineContext: CoroutineContext, private val shortcutCategoriesUtils: ShortcutCategoriesUtils, private val context: Context, private val inputGestureMaps: InputGestureMaps, private val inputGestureDataAdapter: InputGestureDataAdapter, private val customInputGesturesRepository: CustomInputGesturesRepository, private val inputManager: InputManager ) : ShortcutCategoriesRepository { Loading Loading @@ -116,7 +110,7 @@ constructor( if (inputDevice == null) { emptyList() } else { val sources = toInternalGroupSources(inputGestures) val sources = inputGestureDataAdapter.toInternalGroupSources(inputGestures) val supportedKeyCodes = shortcutCategoriesUtils.fetchSupportedKeyCodes( inputDevice.id, Loading Loading @@ -216,7 +210,8 @@ constructor( return null } return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label] return inputGestureDataAdapter .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label) } @KeyGestureType Loading @@ -232,7 +227,8 @@ constructor( return null } return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label] return inputGestureDataAdapter .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label) } private fun Builder.addTriggerFromSelectedKeyCombination(): Builder { Loading Loading @@ -261,70 +257,6 @@ constructor( return _shortcutBeingCustomized.value } private fun toInternalGroupSources( inputGestures: List<InputGestureData> ): List<InternalGroupsSource> { val ungroupedInternalGroupSources = inputGestures.mapNotNull { gestureData -> val keyTrigger = gestureData.trigger as KeyTrigger val keyGestureType = gestureData.action.keyGestureType() fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel -> toInternalKeyboardShortcutInfo(keyGestureType, keyTrigger)?.let { internalKeyboardShortcutInfo -> val group = InternalKeyboardShortcutGroup( label = groupLabel, items = listOf(internalKeyboardShortcutInfo), ) fetchShortcutCategoryTypeByGestureType(keyGestureType)?.let { InternalGroupsSource(groups = listOf(group), type = it) } } } } return ungroupedInternalGroupSources } private fun toInternalKeyboardShortcutInfo( keyGestureType: Int, keyTrigger: KeyTrigger, ): InternalKeyboardShortcutInfo? { fetchShortcutInfoLabelByGestureType(keyGestureType)?.let { return InternalKeyboardShortcutInfo( label = it, keycode = keyTrigger.keycode, modifiers = keyTrigger.modifierState, isCustomShortcut = true, ) } return null } private fun fetchGroupLabelByGestureType(@KeyGestureType keyGestureType: Int): String? { inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let { return context.getString(it) } ?: return null } private fun fetchShortcutInfoLabelByGestureType(@KeyGestureType keyGestureType: Int): String? { inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let { return context.getString(it) } ?: return null } private fun fetchShortcutCategoryTypeByGestureType( @KeyGestureType keyGestureType: Int ): ShortcutCategoryType? { return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType] } private data class InternalGroupsSource( val groups: List<InternalKeyboardShortcutGroup>, val type: ShortcutCategoryType, ) private companion object { private const val TAG = "CustomShortcutCategoriesRepository" } Loading