diff options
11 files changed, 162 insertions, 45 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt index 30a391e63220..6364a6fb53c9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt @@ -20,9 +20,11 @@ import android.app.Activity import com.android.systemui.CoreStartable import com.android.systemui.Flags.keyboardShortcutHelperRewrite import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository +import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource +import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter @@ -50,6 +52,10 @@ interface ShortcutHelperModule { @MultitaskingShortcuts fun multitaskingShortcutsSource(impl: MultitaskingShortcutsSource): KeyboardShortcutGroupsSource + @Binds + @InputShortcuts + fun inputShortcutsSources(impl: InputShortcutsSource): KeyboardShortcutGroupsSource + companion object { @Provides @IntoMap diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt index b47fb65ae9e8..133dab6b4d7b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt @@ -19,16 +19,14 @@ package com.android.systemui.keyboard.shortcut.data.repository import android.content.Context import android.hardware.input.InputManager import android.util.Log -import android.view.InputDevice import android.view.KeyCharacterMap import android.view.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo -import android.view.WindowManager -import android.view.WindowManager.KeyboardShortcutsReceiver import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource +import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts import com.android.systemui.keyboard.shortcut.shared.model.Shortcut @@ -44,7 +42,6 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.map -import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext @SysUISingleton @@ -55,7 +52,7 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource, @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource, - private val windowManager: WindowManager, + @InputShortcuts private val inputShortcutsSource: KeyboardShortcutGroupsSource, private val inputManager: InputManager, stateRepository: ShortcutHelperStateRepository ) { @@ -75,7 +72,7 @@ constructor( toShortcutCategory( it.keyCharacterMap, SYSTEM, - systemShortcutsSource.shortcutGroups() + systemShortcutsSource.shortcutGroups(it.id) ) } else { null @@ -88,7 +85,7 @@ constructor( toShortcutCategory( it.keyCharacterMap, MULTI_TASKING, - multitaskingShortcutsSource.shortcutGroups() + multitaskingShortcutsSource.shortcutGroups(it.id) ) } else { null @@ -96,22 +93,17 @@ constructor( } val imeShortcutsCategory = - activeInputDevice.map { if (it != null) retrieveImeShortcuts(it) else null } - - private suspend fun retrieveImeShortcuts( - inputDevice: InputDevice, - ): ShortcutCategory? { - return suspendCancellableCoroutine { continuation -> - val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups -> - continuation.resumeWith( - Result.success( - toShortcutCategory(inputDevice.keyCharacterMap, IME, shortcutGroups) - ) + activeInputDevice.map { + if (it != null) { + toShortcutCategory( + it.keyCharacterMap, + IME, + inputShortcutsSource.shortcutGroups(it.id) ) + } else { + null } - windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, inputDevice.id) } - } private fun toShortcutCategory( keyCharacterMap: KeyCharacterMap, diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt new file mode 100644 index 000000000000..aba441546e35 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt @@ -0,0 +1,66 @@ +/* + * 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.source + +import android.content.res.Resources +import android.view.KeyEvent.KEYCODE_SPACE +import android.view.KeyEvent.META_CTRL_ON +import android.view.KeyEvent.META_SHIFT_ON +import android.view.KeyboardShortcutGroup +import android.view.WindowManager +import android.view.WindowManager.KeyboardShortcutsReceiver +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo +import com.android.systemui.res.R +import javax.inject.Inject +import kotlinx.coroutines.suspendCancellableCoroutine + +class InputShortcutsSource +@Inject +constructor(@Main private val resources: Resources, private val windowManager: WindowManager) : + KeyboardShortcutGroupsSource { + override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = + getInputLanguageShortcutGroup() + getImeShortcutGroup(deviceId) + + private fun getInputLanguageShortcutGroup() = + listOf( + KeyboardShortcutGroup( + resources.getString(R.string.shortcut_helper_category_input), + inputLanguageShortcuts() + ) + ) + + private fun inputLanguageShortcuts() = + listOf( + /* Switch input language (next language): Ctrl + Space */ + shortcutInfo(resources.getString(R.string.input_switch_input_language_next)) { + command(META_CTRL_ON, KEYCODE_SPACE) + }, + /* Switch previous language (next language): Ctrl + Shift + Space */ + shortcutInfo(resources.getString(R.string.input_switch_input_language_previous)) { + command(META_CTRL_ON or META_SHIFT_ON, KEYCODE_SPACE) + } + ) + + private suspend fun getImeShortcutGroup(deviceId: Int): List<KeyboardShortcutGroup> = + suspendCancellableCoroutine { continuation -> + val shortcutsReceiver = KeyboardShortcutsReceiver { + continuation.resumeWith(Result.success(it)) + } + windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt index 1e2b333171d8..39d03771ecf4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt @@ -20,5 +20,5 @@ import android.view.KeyboardShortcutGroup interface KeyboardShortcutGroupsSource { - fun shortcutGroups(): List<KeyboardShortcutGroup> + suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> } diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt index f4022a01aedb..eddac4d4ad73 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt @@ -34,7 +34,7 @@ import javax.inject.Inject class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) : KeyboardShortcutGroupsSource { - override fun shortcutGroups() = + override suspend fun shortcutGroups(deviceId: Int) = listOf( KeyboardShortcutGroup( resources.getString(R.string.shortcutHelper_category_recent_apps), diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt index 6cd2d2f91b30..e55e339704ee 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt @@ -40,7 +40,7 @@ import javax.inject.Inject class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) : KeyboardShortcutGroupsSource { - override fun shortcutGroups() = + override suspend fun shortcutGroups(deviceId: Int) = listOf( KeyboardShortcutGroup( resources.getString(R.string.shortcut_helper_category_system_controls), diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt new file mode 100644 index 000000000000..f8a4a49cc3ce --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt @@ -0,0 +1,21 @@ +/* + * 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.qualifiers + +import javax.inject.Qualifier + +@Qualifier annotation class InputShortcuts diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt index c2814bd45e86..765cd014864c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt @@ -154,6 +154,29 @@ object TestShortcuts { listOf(standardShortcutInfo3, shortcutInfoWithUnsupportedModifiers) ) + private val switchToNextLanguageShortcut = + shortcut("Switch to next language") { + command { + key("Ctrl") + key("Space") + } + } + + private val switchToPreviousLanguageShortcut = + shortcut("Switch to previous language") { + command { + key("Ctrl") + key("Shift") + key("Space") + } + } + + private val subCategoryForInputLanguageSwitchShortcuts = + ShortcutSubCategory( + "Input", + listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut) + ) + private val subCategoryWithUnsupportedShortcutsRemoved = ShortcutSubCategory( groupWithSupportedAndUnsupportedModifierShortcut.label!!.toString(), @@ -198,7 +221,13 @@ object TestShortcuts { val imeCategory = ShortcutCategory( type = ShortcutCategoryType.IME, - subCategories = listOf(standardSubCategory1, standardSubCategory2, standardSubCategory3) + subCategories = + listOf( + subCategoryForInputLanguageSwitchShortcuts, + standardSubCategory1, + standardSubCategory2, + standardSubCategory3 + ) ) val systemGroups = listOf(standardGroup3, standardGroup2, standardGroup1) @@ -221,6 +250,13 @@ object TestShortcuts { val subCategoriesWithGroupedDuplicatedShortcutLabels = listOf(subCategoryWithGroupedRepeatedShortcutLabels, subCategoryWithStandardShortcut) + val imeSubCategoriesWithGroupedDuplicatedShortcutLabels = + listOf( + subCategoryForInputLanguageSwitchShortcuts, + subCategoryWithGroupedRepeatedShortcutLabels, + subCategoryWithStandardShortcut + ) + val groupsWithUnsupportedModifier = listOf( groupWithStandardShortcutInfo, @@ -231,5 +267,12 @@ object TestShortcuts { val subCategoriesWithUnsupportedModifiersRemoved = listOf(subCategoryWithStandardShortcut, subCategoryWithUnsupportedShortcutsRemoved) + val imeSubCategoriesWithUnsupportedModifiersRemoved = + listOf( + subCategoryForInputLanguageSwitchShortcuts, + subCategoryWithStandardShortcut, + subCategoryWithUnsupportedShortcutsRemoved + ) + val groupsWithOnlyUnsupportedModifiers = listOf(groupWithOnlyUnsupportedModifierShortcut) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt index c6a7565efcd7..a5f1f8c0896a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt @@ -116,7 +116,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() { ShortcutCategory( type = IME, subCategories = - TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels + TestShortcuts.imeSubCategoriesWithGroupedDuplicatedShortcutLabels ), ) .inOrder() @@ -180,7 +180,8 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() { TestShortcuts.multitaskingCategory, ShortcutCategory( type = IME, - subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved + subCategories = + TestShortcuts.imeSubCategoriesWithUnsupportedModifiersRemoved ), ) .inOrder() @@ -227,23 +228,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() { } @Test - fun categories_stateActive_imeShortcutsWitOnlyUnsupportedModifiers_discardsCategory() = - testScope.runTest { - helper.setImeShortcuts(TestShortcuts.groupsWithOnlyUnsupportedModifiers) - val categories by collectLastValue(interactor.shortcutCategories) - - helper.showFromActivity() - - assertThat(categories) - .containsExactly( - TestShortcuts.systemCategory, - TestShortcuts.multitaskingCategory, - ) - .inOrder() - } - - @Test - fun categories_stateActive_systemShortcutsWitOnlyUnsupportedModifiers_discardsCategory() = + fun categories_stateActive_systemShortcutsWithOnlyUnsupportedModifiers_discardsCategory() = testScope.runTest { systemShortcutsSource.setGroups(TestShortcuts.groupsWithOnlyUnsupportedModifiers) val categories by collectLastValue(interactor.shortcutCategories) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt index f947db8ede81..55c803a39ef7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt @@ -24,6 +24,7 @@ import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper +import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource @@ -56,6 +57,9 @@ val Kosmos.shortcutHelperStateRepository by ) } +val Kosmos.shortcutHelperInputShortcutsSource by + Kosmos.Fixture { InputShortcutsSource(mainResources, windowManager) } + val Kosmos.shortcutHelperCategoriesRepository by Kosmos.Fixture { ShortcutHelperCategoriesRepository( @@ -63,7 +67,7 @@ val Kosmos.shortcutHelperCategoriesRepository by testDispatcher, shortcutHelperSystemShortcutsSource, shortcutHelperMultiTaskingShortcutsSource, - windowManager, + shortcutHelperInputShortcutsSource, fakeInputManager.inputManager, shortcutHelperStateRepository, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt index e4c17a03f262..2bab1a4b32cf 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt @@ -22,7 +22,7 @@ class FakeKeyboardShortcutGroupsSource : KeyboardShortcutGroupsSource { private var groups = listOf<KeyboardShortcutGroup>() - override fun shortcutGroups(): List<KeyboardShortcutGroup> = groups + override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = groups fun setGroups(groups: List<KeyboardShortcutGroup>) { this.groups = groups |