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.repository 18 19 import android.hardware.input.AppLaunchData 20 import android.hardware.input.InputGestureData.KeyTrigger 21 import android.hardware.input.InputManager 22 import android.util.Log 23 import android.view.InputDevice 24 import com.android.systemui.Flags.shortcutHelperKeyGlyph 25 import com.android.systemui.dagger.SysUISingleton 26 import com.android.systemui.dagger.qualifiers.Background 27 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand 28 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey 29 import kotlinx.coroutines.CoroutineScope 30 import kotlinx.coroutines.flow.SharingStarted 31 import kotlinx.coroutines.flow.StateFlow 32 import kotlinx.coroutines.flow.map 33 import kotlinx.coroutines.flow.stateIn 34 import javax.inject.Inject 35 36 @SysUISingleton 37 class AppLaunchDataRepository 38 @Inject 39 constructor( 40 private val inputManager: InputManager, 41 @Background private val backgroundScope: CoroutineScope, 42 private val shortcutCategoriesUtils: ShortcutCategoriesUtils, 43 inputDeviceRepository: ShortcutHelperInputDeviceRepository, 44 ) { 45 46 private val shortcutCommandToAppLaunchDataMap: 47 StateFlow<Map<ShortcutCommandKey, AppLaunchData>> = 48 inputDeviceRepository.activeInputDevice 49 .map { inputDevice -> 50 if (inputDevice == null) { 51 emptyMap() 52 } 53 else{ 54 buildCommandToAppLaunchDataMap(inputDevice) 55 } 56 } 57 .stateIn( 58 scope = backgroundScope, 59 started = SharingStarted.Eagerly, 60 initialValue = mapOf(), 61 ) 62 63 fun getAppLaunchDataForShortcutWithCommand(shortcutCommand: ShortcutCommand): AppLaunchData? { 64 val shortcutCommandAsKey = ShortcutCommandKey(shortcutCommand) 65 return shortcutCommandToAppLaunchDataMap.value[shortcutCommandAsKey] 66 } 67 68 private fun buildCommandToAppLaunchDataMap(inputDevice: InputDevice): 69 Map<ShortcutCommandKey, AppLaunchData> { 70 val commandToAppLaunchDataMap = 71 mutableMapOf<ShortcutCommandKey, AppLaunchData>() 72 val appLaunchInputGestures = inputManager.appLaunchBookmarks 73 appLaunchInputGestures.forEach { inputGesture -> 74 val keyGlyphMap = 75 if (shortcutHelperKeyGlyph()) { 76 inputManager.getKeyGlyphMap(inputDevice.id) 77 } else null 78 79 val shortcutCommand = 80 shortcutCategoriesUtils.toShortcutCommand( 81 keyGlyphMap, 82 inputDevice.keyCharacterMap, 83 inputGesture.trigger as KeyTrigger, 84 ) 85 86 if (shortcutCommand != null) { 87 commandToAppLaunchDataMap[ShortcutCommandKey(shortcutCommand)] = 88 inputGesture.action.appLaunchData()!! 89 } else { 90 Log.w( 91 TAG, 92 "could not get Shortcut Command. inputGesture: $inputGesture", 93 ) 94 } 95 } 96 97 return commandToAppLaunchDataMap 98 } 99 100 private data class ShortcutCommandKey(val keys: List<ShortcutKey>) { 101 constructor( 102 shortcutCommand: ShortcutCommand 103 ) : this(shortcutCommand.keys.sortedBy { it.toString() }) 104 } 105 106 private companion object { 107 private const val TAG = "AppLaunchDataRepository" 108 } 109 } 110