1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.keyboard.shortcut.data.source 18 19 import android.content.res.Resources 20 import android.hardware.input.InputManager 21 import android.view.KeyEvent.KEYCODE_EMOJI_PICKER 22 import android.view.KeyEvent.KEYCODE_SPACE 23 import android.view.KeyEvent.META_CTRL_ON 24 import android.view.KeyEvent.META_SHIFT_ON 25 import android.view.KeyboardShortcutGroup 26 import android.view.KeyboardShortcutInfo 27 import android.view.WindowManager 28 import android.view.WindowManager.KeyboardShortcutsReceiver 29 import com.android.systemui.Flags.shortcutHelperKeyGlyph 30 import com.android.systemui.dagger.qualifiers.Main 31 import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo 32 import com.android.systemui.res.R 33 import javax.inject.Inject 34 import kotlinx.coroutines.suspendCancellableCoroutine 35 36 class InputShortcutsSource 37 @Inject 38 constructor( 39 @Main private val resources: Resources, 40 private val windowManager: WindowManager, 41 private val inputManager: InputManager, 42 ) : KeyboardShortcutGroupsSource { 43 override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = 44 getInputLanguageShortcutGroup(deviceId) + getImeShortcutGroup(deviceId) 45 46 private fun getInputLanguageShortcutGroup(deviceId: Int) = 47 listOf( 48 KeyboardShortcutGroup( 49 resources.getString(R.string.shortcut_helper_category_input), 50 inputLanguageShortcuts() + hardwareShortcuts(deviceId), 51 ) 52 ) 53 54 private fun inputLanguageShortcuts() = 55 listOf( 56 /* Switch input language (next language): Ctrl + Space */ 57 shortcutInfo(resources.getString(R.string.input_switch_input_language_next)) { 58 command(META_CTRL_ON, KEYCODE_SPACE) 59 }, 60 /* Switch previous language (next language): Ctrl + Shift + Space */ 61 shortcutInfo(resources.getString(R.string.input_switch_input_language_previous)) { 62 command(META_CTRL_ON or META_SHIFT_ON, KEYCODE_SPACE) 63 }, 64 ) 65 66 private fun hardwareShortcuts(deviceId: Int): List<KeyboardShortcutInfo> { 67 if (shortcutHelperKeyGlyph()) { 68 val keyGlyphMap = inputManager.getKeyGlyphMap(deviceId) 69 if (keyGlyphMap != null && keyGlyphMap.functionRowKeys.contains(KEYCODE_EMOJI_PICKER)) { 70 return listOf( 71 shortcutInfo(resources.getString(R.string.input_access_emoji)) { 72 command(modifiers = 0, KEYCODE_EMOJI_PICKER) 73 } 74 ) 75 } 76 } 77 return emptyList() 78 } 79 80 private suspend fun getImeShortcutGroup(deviceId: Int): List<KeyboardShortcutGroup> = 81 suspendCancellableCoroutine { continuation -> 82 val shortcutsReceiver = KeyboardShortcutsReceiver { 83 continuation.resumeWith(Result.success(it ?: emptyList())) 84 } 85 windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId) 86 } 87 } 88