Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt +101 −26 Original line number Original line Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.keyboard.shortcut.data.repository 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.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import android.view.KeyboardShortcutInfo import android.view.WindowManager import android.view.WindowManager import android.view.WindowManager.KeyboardShortcutsReceiver import android.view.WindowManager.KeyboardShortcutsReceiver import com.android.systemui.dagger.SysUISingleton 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.data.source.KeyboardShortcutGroupsSource import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts Loading @@ -30,29 +36,46 @@ 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.ShortcutCategoryType import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext @SysUISingleton @SysUISingleton class ShortcutHelperCategoriesRepository class ShortcutHelperCategoriesRepository @Inject @Inject constructor( constructor( private val context: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource, @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource, @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource, @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource, private val windowManager: WindowManager, private val windowManager: WindowManager, shortcutHelperStateRepository: ShortcutHelperStateRepository private val inputManager: InputManager, stateRepository: ShortcutHelperStateRepository ) { ) { val systemShortcutsCategory = private val activeInputDevice = shortcutHelperStateRepository.state.map { stateRepository.state.map { if (it is Active) { if (it is Active) { withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) } } else { null } } val systemShortcutsCategory = activeInputDevice.map { if (it != null) { toShortcutCategory( toShortcutCategory( systemShortcutsSource.shortcutGroups(), it.keyCharacterMap, ShortcutCategoryType.SYSTEM SYSTEM, systemShortcutsSource.shortcutGroups() ) ) } else { } else { null null Loading @@ -60,76 +83,128 @@ constructor( } } val multitaskingShortcutsCategory = val multitaskingShortcutsCategory = shortcutHelperStateRepository.state.map { activeInputDevice.map { if (it is Active) { if (it != null) { toShortcutCategory(multitaskingShortcutsSource.shortcutGroups(), MULTI_TASKING) toShortcutCategory( it.keyCharacterMap, MULTI_TASKING, multitaskingShortcutsSource.shortcutGroups() ) } else { } else { null null } } } } val imeShortcutsCategory = val imeShortcutsCategory = shortcutHelperStateRepository.state.map { activeInputDevice.map { if (it != null) retrieveImeShortcuts(it) else null } if (it is Active) retrieveImeShortcuts(it.deviceId) else null } private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory? { private suspend fun retrieveImeShortcuts( inputDevice: InputDevice, ): ShortcutCategory? { return suspendCancellableCoroutine { continuation -> return suspendCancellableCoroutine { continuation -> val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups -> val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups -> continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups, IME))) continuation.resumeWith( Result.success( toShortcutCategory(inputDevice.keyCharacterMap, IME, shortcutGroups) ) ) } } windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId) windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, inputDevice.id) } } } } private fun toShortcutCategory( private fun toShortcutCategory( shortcutGroups: List<KeyboardShortcutGroup>, keyCharacterMap: KeyCharacterMap, type: ShortcutCategoryType, type: ShortcutCategoryType, shortcutGroups: List<KeyboardShortcutGroup>, ): ShortcutCategory? { ): ShortcutCategory? { val subCategories = val subCategories = shortcutGroups shortcutGroups .map { shortcutGroup -> .map { shortcutGroup -> ShortcutSubCategory( ShortcutSubCategory( label = shortcutGroup.label.toString(), shortcutGroup.label.toString(), shortcuts = toShortcuts(shortcutGroup.items) toShortcuts(keyCharacterMap, shortcutGroup.items) ) ) } } .filter { it.shortcuts.isNotEmpty() } .filter { it.shortcuts.isNotEmpty() } return if (subCategories.isEmpty()) { return if (subCategories.isEmpty()) { Log.wtf(TAG, "Empty sub categories after converting $shortcutGroups") null null } else { } else { ShortcutCategory(type, subCategories) ShortcutCategory(type, subCategories) } } } } private fun toShortcuts(infoList: List<KeyboardShortcutInfo>) = private fun toShortcuts( infoList.mapNotNull { toShortcut(it) } keyCharacterMap: KeyCharacterMap, infoList: List<KeyboardShortcutInfo> ) = infoList.mapNotNull { toShortcut(keyCharacterMap, it) } private fun toShortcut(shortcutInfo: KeyboardShortcutInfo): Shortcut? { private fun toShortcut( val shortcutCommand = toShortcutCommand(shortcutInfo) keyCharacterMap: KeyCharacterMap, shortcutInfo: KeyboardShortcutInfo ): Shortcut? { val shortcutCommand = toShortcutCommand(keyCharacterMap, shortcutInfo) return if (shortcutCommand == null) null return if (shortcutCommand == null) null else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand)) else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand)) } } private fun toShortcutCommand(info: KeyboardShortcutInfo): ShortcutCommand? { private fun toShortcutCommand( val keyCodes = mutableListOf<Int>() keyCharacterMap: KeyCharacterMap, info: KeyboardShortcutInfo ): ShortcutCommand? { val keys = mutableListOf<ShortcutKey>() var remainingModifiers = info.modifiers var remainingModifiers = info.modifiers SUPPORTED_MODIFIERS.forEach { supportedModifier -> SUPPORTED_MODIFIERS.forEach { supportedModifier -> if ((supportedModifier and remainingModifiers) != 0) { if ((supportedModifier and remainingModifiers) != 0) { keyCodes += supportedModifier keys += toShortcutKey(keyCharacterMap, supportedModifier) ?: return null // "Remove" the modifier from the remaining modifiers // "Remove" the modifier from the remaining modifiers remainingModifiers = remainingModifiers and supportedModifier.inv() remainingModifiers = remainingModifiers and supportedModifier.inv() } } } } if (remainingModifiers != 0) { if (remainingModifiers != 0) { // There is a remaining modifier we don't support // There is a remaining modifier we don't support Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null return null } } keyCodes += info.keycode if (info.keycode != 0) { return ShortcutCommand(keyCodes) keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null } if (keys.isEmpty()) { Log.wtf(TAG, "No keys for $info") return null } return ShortcutCommand(keys) } private fun toShortcutKey( keyCharacterMap: KeyCharacterMap, keyCode: Int, baseCharacter: Char = Char.MIN_VALUE, ): ShortcutKey? { val iconResId = ShortcutHelperKeys.keyIcons[keyCode] if (iconResId != null) { return ShortcutKey.Icon(iconResId) } if (baseCharacter > Char.MIN_VALUE) { return ShortcutKey.Text(baseCharacter.toString()) } val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode] if (specialKeyLabel != null) { val label = specialKeyLabel(context) return ShortcutKey.Text(label) } val displayLabelCharacter = keyCharacterMap.getDisplayLabel(keyCode) if (displayLabelCharacter.code != 0) { return ShortcutKey.Text(displayLabelCharacter.toString()) } Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode") return null } } companion object { companion object { private const val TAG = "SHCategoriesRepo" private val SUPPORTED_MODIFIERS = private val SUPPORTED_MODIFIERS = listOf( listOf( KeyEvent.META_META_ON, KeyEvent.META_META_ON, Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,8 @@ data class Shortcut(val label: String, val commands: List<ShortcutCommand>) class ShortcutBuilder(private val label: String) { class ShortcutBuilder(private val label: String) { val commands = mutableListOf<ShortcutCommand>() val commands = mutableListOf<ShortcutCommand>() fun command(vararg keyCodes: Int) { fun command(builder: ShortcutCommandBuilder.() -> Unit) { commands += ShortcutCommand(keyCodes.toList()) commands += ShortcutCommandBuilder().apply(builder).build() } } fun build() = Shortcut(label, commands) fun build() = Shortcut(label, commands) Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -30,8 +30,8 @@ data class ShortcutCategory( class ShortcutCategoryBuilder(val type: ShortcutCategoryType) { class ShortcutCategoryBuilder(val type: ShortcutCategoryType) { private val subCategories = mutableListOf<ShortcutSubCategory>() private val subCategories = mutableListOf<ShortcutSubCategory>() fun subCategory(label: String, shortcuts: List<Shortcut>) { fun subCategory(label: String, builder: ShortcutSubCategoryBuilder.() -> Unit) { subCategories += ShortcutSubCategory(label, shortcuts) subCategories += ShortcutSubCategoryBuilder(label).apply(builder).build() } } fun build() = ShortcutCategory(type, subCategories) fun build() = ShortcutCategory(type, subCategories) Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt +20 −1 Original line number Original line Diff line number Diff line Loading @@ -16,4 +16,23 @@ package com.android.systemui.keyboard.shortcut.shared.model package com.android.systemui.keyboard.shortcut.shared.model data class ShortcutCommand(val keyCodes: List<Int>) import androidx.annotation.DrawableRes data class ShortcutCommand(val keys: List<ShortcutKey>) class ShortcutCommandBuilder { private val keys = mutableListOf<ShortcutKey>() fun key(text: String) { keys += ShortcutKey.Text(text) } fun key(@DrawableRes drawableResId: Int) { keys += ShortcutKey.Icon(drawableResId) } fun build() = ShortcutCommand(keys) } fun shortcutCommand(block: ShortcutCommandBuilder.() -> Unit) = ShortcutCommandBuilder().apply(block).build() packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt 0 → 100644 +25 −0 Original line number Original line 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.shared.model import androidx.annotation.DrawableRes sealed interface ShortcutKey { data class Text(val value: String) : ShortcutKey data class Icon(@DrawableRes val drawableResId: Int) : ShortcutKey } Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt +101 −26 Original line number Original line Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.keyboard.shortcut.data.repository 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.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import android.view.KeyboardShortcutInfo import android.view.WindowManager import android.view.WindowManager import android.view.WindowManager.KeyboardShortcutsReceiver import android.view.WindowManager.KeyboardShortcutsReceiver import com.android.systemui.dagger.SysUISingleton 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.data.source.KeyboardShortcutGroupsSource import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts Loading @@ -30,29 +36,46 @@ 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.ShortcutCategoryType import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext @SysUISingleton @SysUISingleton class ShortcutHelperCategoriesRepository class ShortcutHelperCategoriesRepository @Inject @Inject constructor( constructor( private val context: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource, @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource, @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource, @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource, private val windowManager: WindowManager, private val windowManager: WindowManager, shortcutHelperStateRepository: ShortcutHelperStateRepository private val inputManager: InputManager, stateRepository: ShortcutHelperStateRepository ) { ) { val systemShortcutsCategory = private val activeInputDevice = shortcutHelperStateRepository.state.map { stateRepository.state.map { if (it is Active) { if (it is Active) { withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) } } else { null } } val systemShortcutsCategory = activeInputDevice.map { if (it != null) { toShortcutCategory( toShortcutCategory( systemShortcutsSource.shortcutGroups(), it.keyCharacterMap, ShortcutCategoryType.SYSTEM SYSTEM, systemShortcutsSource.shortcutGroups() ) ) } else { } else { null null Loading @@ -60,76 +83,128 @@ constructor( } } val multitaskingShortcutsCategory = val multitaskingShortcutsCategory = shortcutHelperStateRepository.state.map { activeInputDevice.map { if (it is Active) { if (it != null) { toShortcutCategory(multitaskingShortcutsSource.shortcutGroups(), MULTI_TASKING) toShortcutCategory( it.keyCharacterMap, MULTI_TASKING, multitaskingShortcutsSource.shortcutGroups() ) } else { } else { null null } } } } val imeShortcutsCategory = val imeShortcutsCategory = shortcutHelperStateRepository.state.map { activeInputDevice.map { if (it != null) retrieveImeShortcuts(it) else null } if (it is Active) retrieveImeShortcuts(it.deviceId) else null } private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory? { private suspend fun retrieveImeShortcuts( inputDevice: InputDevice, ): ShortcutCategory? { return suspendCancellableCoroutine { continuation -> return suspendCancellableCoroutine { continuation -> val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups -> val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups -> continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups, IME))) continuation.resumeWith( Result.success( toShortcutCategory(inputDevice.keyCharacterMap, IME, shortcutGroups) ) ) } } windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId) windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, inputDevice.id) } } } } private fun toShortcutCategory( private fun toShortcutCategory( shortcutGroups: List<KeyboardShortcutGroup>, keyCharacterMap: KeyCharacterMap, type: ShortcutCategoryType, type: ShortcutCategoryType, shortcutGroups: List<KeyboardShortcutGroup>, ): ShortcutCategory? { ): ShortcutCategory? { val subCategories = val subCategories = shortcutGroups shortcutGroups .map { shortcutGroup -> .map { shortcutGroup -> ShortcutSubCategory( ShortcutSubCategory( label = shortcutGroup.label.toString(), shortcutGroup.label.toString(), shortcuts = toShortcuts(shortcutGroup.items) toShortcuts(keyCharacterMap, shortcutGroup.items) ) ) } } .filter { it.shortcuts.isNotEmpty() } .filter { it.shortcuts.isNotEmpty() } return if (subCategories.isEmpty()) { return if (subCategories.isEmpty()) { Log.wtf(TAG, "Empty sub categories after converting $shortcutGroups") null null } else { } else { ShortcutCategory(type, subCategories) ShortcutCategory(type, subCategories) } } } } private fun toShortcuts(infoList: List<KeyboardShortcutInfo>) = private fun toShortcuts( infoList.mapNotNull { toShortcut(it) } keyCharacterMap: KeyCharacterMap, infoList: List<KeyboardShortcutInfo> ) = infoList.mapNotNull { toShortcut(keyCharacterMap, it) } private fun toShortcut(shortcutInfo: KeyboardShortcutInfo): Shortcut? { private fun toShortcut( val shortcutCommand = toShortcutCommand(shortcutInfo) keyCharacterMap: KeyCharacterMap, shortcutInfo: KeyboardShortcutInfo ): Shortcut? { val shortcutCommand = toShortcutCommand(keyCharacterMap, shortcutInfo) return if (shortcutCommand == null) null return if (shortcutCommand == null) null else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand)) else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand)) } } private fun toShortcutCommand(info: KeyboardShortcutInfo): ShortcutCommand? { private fun toShortcutCommand( val keyCodes = mutableListOf<Int>() keyCharacterMap: KeyCharacterMap, info: KeyboardShortcutInfo ): ShortcutCommand? { val keys = mutableListOf<ShortcutKey>() var remainingModifiers = info.modifiers var remainingModifiers = info.modifiers SUPPORTED_MODIFIERS.forEach { supportedModifier -> SUPPORTED_MODIFIERS.forEach { supportedModifier -> if ((supportedModifier and remainingModifiers) != 0) { if ((supportedModifier and remainingModifiers) != 0) { keyCodes += supportedModifier keys += toShortcutKey(keyCharacterMap, supportedModifier) ?: return null // "Remove" the modifier from the remaining modifiers // "Remove" the modifier from the remaining modifiers remainingModifiers = remainingModifiers and supportedModifier.inv() remainingModifiers = remainingModifiers and supportedModifier.inv() } } } } if (remainingModifiers != 0) { if (remainingModifiers != 0) { // There is a remaining modifier we don't support // There is a remaining modifier we don't support Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null return null } } keyCodes += info.keycode if (info.keycode != 0) { return ShortcutCommand(keyCodes) keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null } if (keys.isEmpty()) { Log.wtf(TAG, "No keys for $info") return null } return ShortcutCommand(keys) } private fun toShortcutKey( keyCharacterMap: KeyCharacterMap, keyCode: Int, baseCharacter: Char = Char.MIN_VALUE, ): ShortcutKey? { val iconResId = ShortcutHelperKeys.keyIcons[keyCode] if (iconResId != null) { return ShortcutKey.Icon(iconResId) } if (baseCharacter > Char.MIN_VALUE) { return ShortcutKey.Text(baseCharacter.toString()) } val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode] if (specialKeyLabel != null) { val label = specialKeyLabel(context) return ShortcutKey.Text(label) } val displayLabelCharacter = keyCharacterMap.getDisplayLabel(keyCode) if (displayLabelCharacter.code != 0) { return ShortcutKey.Text(displayLabelCharacter.toString()) } Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode") return null } } companion object { companion object { private const val TAG = "SHCategoriesRepo" private val SUPPORTED_MODIFIERS = private val SUPPORTED_MODIFIERS = listOf( listOf( KeyEvent.META_META_ON, KeyEvent.META_META_ON, Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,8 @@ data class Shortcut(val label: String, val commands: List<ShortcutCommand>) class ShortcutBuilder(private val label: String) { class ShortcutBuilder(private val label: String) { val commands = mutableListOf<ShortcutCommand>() val commands = mutableListOf<ShortcutCommand>() fun command(vararg keyCodes: Int) { fun command(builder: ShortcutCommandBuilder.() -> Unit) { commands += ShortcutCommand(keyCodes.toList()) commands += ShortcutCommandBuilder().apply(builder).build() } } fun build() = Shortcut(label, commands) fun build() = Shortcut(label, commands) Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -30,8 +30,8 @@ data class ShortcutCategory( class ShortcutCategoryBuilder(val type: ShortcutCategoryType) { class ShortcutCategoryBuilder(val type: ShortcutCategoryType) { private val subCategories = mutableListOf<ShortcutSubCategory>() private val subCategories = mutableListOf<ShortcutSubCategory>() fun subCategory(label: String, shortcuts: List<Shortcut>) { fun subCategory(label: String, builder: ShortcutSubCategoryBuilder.() -> Unit) { subCategories += ShortcutSubCategory(label, shortcuts) subCategories += ShortcutSubCategoryBuilder(label).apply(builder).build() } } fun build() = ShortcutCategory(type, subCategories) fun build() = ShortcutCategory(type, subCategories) Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt +20 −1 Original line number Original line Diff line number Diff line Loading @@ -16,4 +16,23 @@ package com.android.systemui.keyboard.shortcut.shared.model package com.android.systemui.keyboard.shortcut.shared.model data class ShortcutCommand(val keyCodes: List<Int>) import androidx.annotation.DrawableRes data class ShortcutCommand(val keys: List<ShortcutKey>) class ShortcutCommandBuilder { private val keys = mutableListOf<ShortcutKey>() fun key(text: String) { keys += ShortcutKey.Text(text) } fun key(@DrawableRes drawableResId: Int) { keys += ShortcutKey.Icon(drawableResId) } fun build() = ShortcutCommand(keys) } fun shortcutCommand(block: ShortcutCommandBuilder.() -> Unit) = ShortcutCommandBuilder().apply(block).build()
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt 0 → 100644 +25 −0 Original line number Original line 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.shared.model import androidx.annotation.DrawableRes sealed interface ShortcutKey { data class Text(val value: String) : ShortcutKey data class Icon(@DrawableRes val drawableResId: Int) : ShortcutKey }