Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt +81 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,14 @@ import android.content.Context.INPUT_SERVICE import android.hardware.input.fakeInputManager import android.hardware.input.fakeInputManager import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.annotations.EnableFlags import android.view.KeyEvent.KEYCODE_SLASH import android.view.KeyEvent.META_ALT_ON import android.view.KeyEvent.META_CAPS_LOCK_ON import android.view.KeyEvent.META_CTRL_ON import android.view.KeyEvent.META_FUNCTION_ON import android.view.KeyEvent.META_META_ON import android.view.KeyEvent.META_SHIFT_ON import android.view.KeyEvent.META_SYM_ON import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES Loading @@ -31,8 +39,11 @@ import com.android.systemui.keyboard.shortcut.customShortcutCategoriesRepository import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.userTracker import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.android.systemui.testKosmos Loading Loading @@ -114,4 +125,74 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() { assertThat(categories).isEmpty() assertThat(categories).isEmpty() } } } } @Test fun pressedKeys_isEmptyByDefault() { testScope.runTest { val pressedKeys by collectLastValue(repo.pressedKeys) assertThat(pressedKeys).isEmpty() helper.toggle(deviceId = 123) assertThat(pressedKeys).isEmpty() } } @Test fun pressedKeys_recognizesAllSupportedModifiers() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = allSupportedModifiers, keyCode = null) ) assertThat(pressedKeys) .containsExactly( ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta), ShortcutKey.Text("Ctrl"), ShortcutKey.Text("Fn"), ShortcutKey.Text("Shift"), ShortcutKey.Text("Alt"), ShortcutKey.Text("Sym"), ) } } @Test fun pressedKeys_ignoresUnsupportedModifiers() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = META_CAPS_LOCK_ON, keyCode = null) ) assertThat(pressedKeys).isEmpty() } } @Test fun pressedKeys_assertCorrectConversion() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = META_META_ON, keyCode = KEYCODE_SLASH) ) assertThat(pressedKeys) .containsExactly( ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta), ShortcutKey.Text("/"), ) } } private val allSupportedModifiers = META_META_ON or META_CTRL_ON or META_FUNCTION_ON or META_SHIFT_ON or META_ALT_ON or META_SYM_ON } } packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt +46 −0 Original line number Original line Diff line number Diff line Loading @@ -23,19 +23,24 @@ import android.hardware.input.InputGestureData.KeyTrigger import android.hardware.input.InputManager import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.hardware.input.InputSettings import android.hardware.input.KeyGestureEvent import android.hardware.input.KeyGestureEvent import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo 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.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.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.settings.UserTracker import com.android.systemui.settings.UserTracker import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext Loading @@ -60,6 +65,8 @@ constructor( private val inputManager: InputManager private val inputManager: InputManager get() = userContext.getSystemService(INPUT_SERVICE) as InputManager get() = userContext.getSystemService(INPUT_SERVICE) as InputManager private val _selectedKeyCombination = MutableStateFlow<KeyCombination?>(null) private val activeInputDevice = private val activeInputDevice = stateRepository.state.map { stateRepository.state.map { if (it is Active) { if (it is Active) { Loading @@ -69,6 +76,41 @@ constructor( } } } } val pressedKeys = _selectedKeyCombination .combine(activeInputDevice) { keyCombination, inputDevice -> if (inputDevice == null || keyCombination == null) { return@combine emptyList() } else { val keyGlyphMap = if (shortcutHelperKeyGlyph()) { inputManager.getKeyGlyphMap(inputDevice.id) } else null val modifiers = shortcutCategoriesUtils.toShortcutModifierKeys( keyCombination.modifiers, keyGlyphMap, ) val triggerKey = keyCombination.keyCode?.let { shortcutCategoriesUtils.toShortcutKey( keyGlyphMap, inputDevice.keyCharacterMap, keyCode = it, ) } val keys = mutableListOf<ShortcutKey>() modifiers?.let { keys += it } triggerKey?.let { keys += it } return@combine keys } } .stateIn( scope = backgroundScope, started = SharingStarted.Lazily, initialValue = emptyList(), ) override val categories: Flow<List<ShortcutCategory>> = override val categories: Flow<List<ShortcutCategory>> = activeInputDevice activeInputDevice .map { inputDevice -> .map { inputDevice -> Loading Loading @@ -104,6 +146,10 @@ constructor( started = SharingStarted.Lazily, started = SharingStarted.Lazily, ) ) fun updateUserKeyCombination(keyCombination: KeyCombination?) { _selectedKeyCombination.value = keyCombination } private fun toInternalGroupSources( private fun toInternalGroupSources( inputGestures: List<InputGestureData> inputGestures: List<InputGestureData> ): List<InternalGroupsSource> { ): List<InternalGroupsSource> { Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt +20 −8 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.util.Log import android.view.InputDevice import android.view.InputDevice import android.view.KeyCharacterMap import android.view.KeyCharacterMap import android.view.KeyEvent import android.view.KeyEvent import android.view.KeyEvent.META_META_ON import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup Loading @@ -35,9 +36,9 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey 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 kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.withContext class ShortcutCategoriesUtils class ShortcutCategoriesUtils @Inject @Inject Loading Loading @@ -161,7 +162,7 @@ constructor( } } 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") Log.w(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null return null } } if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { Loading @@ -170,21 +171,32 @@ constructor( ?: return null ?: return null } } if (keys.isEmpty()) { if (keys.isEmpty()) { Log.wtf(TAG, "No keys for $info") Log.w(TAG, "No keys for $info") return null return null } } return ShortcutCommand(keys = keys, isCustom = info.isCustomShortcut) return ShortcutCommand(keys = keys, isCustom = info.isCustomShortcut) } } fun toShortcutModifierKeys(modifiers: Int, keyGlyphMap: KeyGlyphMap?): List<ShortcutKey>? { val keys: MutableList<ShortcutKey> = mutableListOf() var remainingModifiers = modifiers SUPPORTED_MODIFIERS.forEach { supportedModifier -> if ((supportedModifier and remainingModifiers) != 0) { keys += toShortcutModifierKey(keyGlyphMap, supportedModifier) ?: return null remainingModifiers = remainingModifiers and supportedModifier.inv() } } return keys } private fun toShortcutModifierKey(keyGlyphMap: KeyGlyphMap?, modifierMask: Int): ShortcutKey? { private fun toShortcutModifierKey(keyGlyphMap: KeyGlyphMap?, modifierMask: Int): ShortcutKey? { val modifierDrawable = keyGlyphMap?.getDrawableForModifierState(context, modifierMask) val modifierDrawable = keyGlyphMap?.getDrawableForModifierState(context, modifierMask) if (modifierDrawable != null) { if (modifierDrawable != null) { return ShortcutKey.Icon.DrawableIcon(drawable = modifierDrawable) return ShortcutKey.Icon.DrawableIcon(drawable = modifierDrawable) } } val iconResId = ShortcutHelperKeys.keyIcons[modifierMask] if (modifierMask == META_META_ON) { if (iconResId != null) { return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId) return ShortcutKey.Icon.ResIdIcon(iconResId) } } val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask] val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask] Loading @@ -195,7 +207,7 @@ constructor( return null return null } } private fun toShortcutKey( fun toShortcutKey( keyGlyphMap: KeyGlyphMap?, keyGlyphMap: KeyGlyphMap?, keyCharacterMap: KeyCharacterMap, keyCharacterMap: KeyCharacterMap, keyCode: Int, keyCode: Int, Loading @@ -222,7 +234,7 @@ constructor( if (displayLabelCharacter.code != 0) { if (displayLabelCharacter.code != 0) { return ShortcutKey.Text(displayLabelCharacter.toString()) return ShortcutKey.Text(displayLabelCharacter.toString()) } } Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode") Log.w(TAG, "Couldn't find label or icon for key: $keyCode") return null return null } } Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt +2 −1 Original line number Original line Diff line number Diff line Loading @@ -116,9 +116,10 @@ import com.android.systemui.res.R object ShortcutHelperKeys { object ShortcutHelperKeys { val metaModifierIconResId = R.drawable.ic_ksh_key_meta val keyIcons = val keyIcons = mapOf( mapOf( META_META_ON to R.drawable.ic_ksh_key_meta, KEYCODE_BACK to R.drawable.ic_arrow_back_2, KEYCODE_BACK to R.drawable.ic_arrow_back_2, KEYCODE_HOME to R.drawable.ic_radio_button_unchecked, KEYCODE_HOME to R.drawable.ic_radio_button_unchecked, KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank, KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank, Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt +12 −3 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,22 @@ package com.android.systemui.keyboard.shortcut.domain.interactor package com.android.systemui.keyboard.shortcut.domain.interactor import android.view.KeyEvent.META_META_ON import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import javax.inject.Inject import javax.inject.Inject class ShortcutCustomizationInteractor @Inject constructor() { class ShortcutCustomizationInteractor @Inject constructor(private val customShortcutRepository: CustomShortcutCategoriesRepository) { val pressedKeys = customShortcutRepository.pressedKeys fun updateUserSelectedKeyCombination(keyCombination: KeyCombination?) { customShortcutRepository.updateUserKeyCombination(keyCombination) } fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon { fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon { return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.keyIcons[META_META_ON]!!) return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId) } } } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt +81 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,14 @@ import android.content.Context.INPUT_SERVICE import android.hardware.input.fakeInputManager import android.hardware.input.fakeInputManager import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.annotations.EnableFlags import android.view.KeyEvent.KEYCODE_SLASH import android.view.KeyEvent.META_ALT_ON import android.view.KeyEvent.META_CAPS_LOCK_ON import android.view.KeyEvent.META_CTRL_ON import android.view.KeyEvent.META_FUNCTION_ON import android.view.KeyEvent.META_META_ON import android.view.KeyEvent.META_SHIFT_ON import android.view.KeyEvent.META_SYM_ON import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES Loading @@ -31,8 +39,11 @@ import com.android.systemui.keyboard.shortcut.customShortcutCategoriesRepository import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.userTracker import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.android.systemui.testKosmos Loading Loading @@ -114,4 +125,74 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() { assertThat(categories).isEmpty() assertThat(categories).isEmpty() } } } } @Test fun pressedKeys_isEmptyByDefault() { testScope.runTest { val pressedKeys by collectLastValue(repo.pressedKeys) assertThat(pressedKeys).isEmpty() helper.toggle(deviceId = 123) assertThat(pressedKeys).isEmpty() } } @Test fun pressedKeys_recognizesAllSupportedModifiers() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = allSupportedModifiers, keyCode = null) ) assertThat(pressedKeys) .containsExactly( ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta), ShortcutKey.Text("Ctrl"), ShortcutKey.Text("Fn"), ShortcutKey.Text("Shift"), ShortcutKey.Text("Alt"), ShortcutKey.Text("Sym"), ) } } @Test fun pressedKeys_ignoresUnsupportedModifiers() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = META_CAPS_LOCK_ON, keyCode = null) ) assertThat(pressedKeys).isEmpty() } } @Test fun pressedKeys_assertCorrectConversion() { testScope.runTest { helper.toggle(deviceId = 123) val pressedKeys by collectLastValue(repo.pressedKeys) repo.updateUserKeyCombination( KeyCombination(modifiers = META_META_ON, keyCode = KEYCODE_SLASH) ) assertThat(pressedKeys) .containsExactly( ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta), ShortcutKey.Text("/"), ) } } private val allSupportedModifiers = META_META_ON or META_CTRL_ON or META_FUNCTION_ON or META_SHIFT_ON or META_ALT_ON or META_SYM_ON } }
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt +46 −0 Original line number Original line Diff line number Diff line Loading @@ -23,19 +23,24 @@ import android.hardware.input.InputGestureData.KeyTrigger import android.hardware.input.InputManager import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.hardware.input.InputSettings import android.hardware.input.KeyGestureEvent import android.hardware.input.KeyGestureEvent import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo 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.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.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.settings.UserTracker import com.android.systemui.settings.UserTracker import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext Loading @@ -60,6 +65,8 @@ constructor( private val inputManager: InputManager private val inputManager: InputManager get() = userContext.getSystemService(INPUT_SERVICE) as InputManager get() = userContext.getSystemService(INPUT_SERVICE) as InputManager private val _selectedKeyCombination = MutableStateFlow<KeyCombination?>(null) private val activeInputDevice = private val activeInputDevice = stateRepository.state.map { stateRepository.state.map { if (it is Active) { if (it is Active) { Loading @@ -69,6 +76,41 @@ constructor( } } } } val pressedKeys = _selectedKeyCombination .combine(activeInputDevice) { keyCombination, inputDevice -> if (inputDevice == null || keyCombination == null) { return@combine emptyList() } else { val keyGlyphMap = if (shortcutHelperKeyGlyph()) { inputManager.getKeyGlyphMap(inputDevice.id) } else null val modifiers = shortcutCategoriesUtils.toShortcutModifierKeys( keyCombination.modifiers, keyGlyphMap, ) val triggerKey = keyCombination.keyCode?.let { shortcutCategoriesUtils.toShortcutKey( keyGlyphMap, inputDevice.keyCharacterMap, keyCode = it, ) } val keys = mutableListOf<ShortcutKey>() modifiers?.let { keys += it } triggerKey?.let { keys += it } return@combine keys } } .stateIn( scope = backgroundScope, started = SharingStarted.Lazily, initialValue = emptyList(), ) override val categories: Flow<List<ShortcutCategory>> = override val categories: Flow<List<ShortcutCategory>> = activeInputDevice activeInputDevice .map { inputDevice -> .map { inputDevice -> Loading Loading @@ -104,6 +146,10 @@ constructor( started = SharingStarted.Lazily, started = SharingStarted.Lazily, ) ) fun updateUserKeyCombination(keyCombination: KeyCombination?) { _selectedKeyCombination.value = keyCombination } private fun toInternalGroupSources( private fun toInternalGroupSources( inputGestures: List<InputGestureData> inputGestures: List<InputGestureData> ): List<InternalGroupsSource> { ): List<InternalGroupsSource> { Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt +20 −8 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.util.Log import android.view.InputDevice import android.view.InputDevice import android.view.KeyCharacterMap import android.view.KeyCharacterMap import android.view.KeyEvent import android.view.KeyEvent import android.view.KeyEvent.META_META_ON import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.Flags.shortcutHelperKeyGlyph import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup Loading @@ -35,9 +36,9 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey 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 kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.withContext class ShortcutCategoriesUtils class ShortcutCategoriesUtils @Inject @Inject Loading Loading @@ -161,7 +162,7 @@ constructor( } } 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") Log.w(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null return null } } if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { Loading @@ -170,21 +171,32 @@ constructor( ?: return null ?: return null } } if (keys.isEmpty()) { if (keys.isEmpty()) { Log.wtf(TAG, "No keys for $info") Log.w(TAG, "No keys for $info") return null return null } } return ShortcutCommand(keys = keys, isCustom = info.isCustomShortcut) return ShortcutCommand(keys = keys, isCustom = info.isCustomShortcut) } } fun toShortcutModifierKeys(modifiers: Int, keyGlyphMap: KeyGlyphMap?): List<ShortcutKey>? { val keys: MutableList<ShortcutKey> = mutableListOf() var remainingModifiers = modifiers SUPPORTED_MODIFIERS.forEach { supportedModifier -> if ((supportedModifier and remainingModifiers) != 0) { keys += toShortcutModifierKey(keyGlyphMap, supportedModifier) ?: return null remainingModifiers = remainingModifiers and supportedModifier.inv() } } return keys } private fun toShortcutModifierKey(keyGlyphMap: KeyGlyphMap?, modifierMask: Int): ShortcutKey? { private fun toShortcutModifierKey(keyGlyphMap: KeyGlyphMap?, modifierMask: Int): ShortcutKey? { val modifierDrawable = keyGlyphMap?.getDrawableForModifierState(context, modifierMask) val modifierDrawable = keyGlyphMap?.getDrawableForModifierState(context, modifierMask) if (modifierDrawable != null) { if (modifierDrawable != null) { return ShortcutKey.Icon.DrawableIcon(drawable = modifierDrawable) return ShortcutKey.Icon.DrawableIcon(drawable = modifierDrawable) } } val iconResId = ShortcutHelperKeys.keyIcons[modifierMask] if (modifierMask == META_META_ON) { if (iconResId != null) { return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId) return ShortcutKey.Icon.ResIdIcon(iconResId) } } val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask] val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask] Loading @@ -195,7 +207,7 @@ constructor( return null return null } } private fun toShortcutKey( fun toShortcutKey( keyGlyphMap: KeyGlyphMap?, keyGlyphMap: KeyGlyphMap?, keyCharacterMap: KeyCharacterMap, keyCharacterMap: KeyCharacterMap, keyCode: Int, keyCode: Int, Loading @@ -222,7 +234,7 @@ constructor( if (displayLabelCharacter.code != 0) { if (displayLabelCharacter.code != 0) { return ShortcutKey.Text(displayLabelCharacter.toString()) return ShortcutKey.Text(displayLabelCharacter.toString()) } } Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode") Log.w(TAG, "Couldn't find label or icon for key: $keyCode") return null return null } } Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt +2 −1 Original line number Original line Diff line number Diff line Loading @@ -116,9 +116,10 @@ import com.android.systemui.res.R object ShortcutHelperKeys { object ShortcutHelperKeys { val metaModifierIconResId = R.drawable.ic_ksh_key_meta val keyIcons = val keyIcons = mapOf( mapOf( META_META_ON to R.drawable.ic_ksh_key_meta, KEYCODE_BACK to R.drawable.ic_arrow_back_2, KEYCODE_BACK to R.drawable.ic_arrow_back_2, KEYCODE_HOME to R.drawable.ic_radio_button_unchecked, KEYCODE_HOME to R.drawable.ic_radio_button_unchecked, KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank, KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank, Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt +12 −3 Original line number Original line Diff line number Diff line Loading @@ -16,13 +16,22 @@ package com.android.systemui.keyboard.shortcut.domain.interactor package com.android.systemui.keyboard.shortcut.domain.interactor import android.view.KeyEvent.META_META_ON import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import javax.inject.Inject import javax.inject.Inject class ShortcutCustomizationInteractor @Inject constructor() { class ShortcutCustomizationInteractor @Inject constructor(private val customShortcutRepository: CustomShortcutCategoriesRepository) { val pressedKeys = customShortcutRepository.pressedKeys fun updateUserSelectedKeyCombination(keyCombination: KeyCombination?) { customShortcutRepository.updateUserKeyCombination(keyCombination) } fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon { fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon { return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.keyIcons[META_META_ON]!!) return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId) } } } }