@@ -28,16 +28,13 @@ import io.github.sds100.keymapper.common.utils.KMError.SdkVersionTooLow
2828import io.github.sds100.keymapper.common.utils.KMResult
2929import io.github.sds100.keymapper.common.utils.Orientation
3030import io.github.sds100.keymapper.common.utils.Success
31- import io.github.sds100.keymapper.common.utils.dataOrNull
3231import io.github.sds100.keymapper.common.utils.firstBlocking
3332import io.github.sds100.keymapper.common.utils.getWordBoundaries
34- import io.github.sds100.keymapper.common.utils.ifIsData
3533import io.github.sds100.keymapper.common.utils.onFailure
3634import io.github.sds100.keymapper.common.utils.onSuccess
3735import io.github.sds100.keymapper.common.utils.otherwise
3836import io.github.sds100.keymapper.common.utils.success
3937import io.github.sds100.keymapper.common.utils.then
40- import io.github.sds100.keymapper.common.utils.withFlag
4138import io.github.sds100.keymapper.data.Keys
4239import io.github.sds100.keymapper.data.PreferenceDefaults
4340import io.github.sds100.keymapper.data.repositories.PreferenceRepository
@@ -52,7 +49,6 @@ import io.github.sds100.keymapper.system.devices.DevicesAdapter
5249import io.github.sds100.keymapper.system.display.DisplayAdapter
5350import io.github.sds100.keymapper.system.files.FileAdapter
5451import io.github.sds100.keymapper.system.files.FileUtils
55- import io.github.sds100.keymapper.system.inputevents.KeyEventUtils
5652import io.github.sds100.keymapper.system.inputevents.Scancode
5753import io.github.sds100.keymapper.system.inputmethod.InputMethodAdapter
5854import io.github.sds100.keymapper.system.intents.IntentAdapter
@@ -78,12 +74,9 @@ import kotlin.math.absoluteValue
7874import kotlinx.coroutines.CoroutineScope
7975import kotlinx.coroutines.delay
8076import kotlinx.coroutines.flow.Flow
81- import kotlinx.coroutines.flow.SharingStarted
82- import kotlinx.coroutines.flow.StateFlow
8377import kotlinx.coroutines.flow.filterNotNull
8478import kotlinx.coroutines.flow.first
8579import kotlinx.coroutines.flow.map
86- import kotlinx.coroutines.flow.stateIn
8780import kotlinx.coroutines.runBlocking
8881import kotlinx.coroutines.withTimeoutOrNull
8982import timber.log.Timber
@@ -143,15 +136,19 @@ class PerformActionsUseCaseImpl @AssistedInject constructor(
143136 )
144137 }
145138
146- private val injectKeyEventsWithSystemBridge: StateFlow <Boolean > =
147- settingsRepository.get(Keys .keyEventActionsUseSystemBridge)
148- .map { it ? : PreferenceDefaults .KEY_EVENT_ACTIONS_USE_SYSTEM_BRIDGE }
149- .stateIn(coroutineScope, SharingStarted .Eagerly , false )
139+ private val performKeyEventActionDelegate: PerformKeyEventActionDelegate =
140+ PerformKeyEventActionDelegate (
141+ coroutineScope,
142+ settingsRepository,
143+ inputEventHub,
144+ devicesAdapter,
145+ )
150146
151147 override suspend fun perform (
152148 action : ActionData ,
153149 inputEventAction : InputEventAction ,
154150 keyMetaState : Int ,
151+ device : PerformActionTriggerDevice ,
155152 ) {
156153 /* *
157154 * Is null if the action is being performed asynchronously
@@ -172,48 +169,12 @@ class PerformActionsUseCaseImpl @AssistedInject constructor(
172169 }
173170
174171 is ActionData .InputKeyEvent -> {
175- val deviceId: Int = getDeviceIdForKeyEventAction(action)
176-
177- // See issue #1683. Some apps ignore key events which do not have a source.
178- val source = when {
179- KeyEventUtils .isDpadKeyCode(action.keyCode) -> InputDevice .SOURCE_DPAD
180- KeyEventUtils .isGamepadButton(action.keyCode) -> InputDevice .SOURCE_GAMEPAD
181- else -> InputDevice .SOURCE_KEYBOARD
182- }
183-
184- val firstInputAction = if (inputEventAction == InputEventAction .UP ) {
185- KeyEvent .ACTION_UP
186- } else {
187- KeyEvent .ACTION_DOWN
188- }
189-
190- val model = InjectKeyEventModel (
191- keyCode = action.keyCode,
192- action = firstInputAction,
193- metaState = keyMetaState.withFlag(action.metaState),
194- deviceId = deviceId,
195- source = source,
196- repeatCount = 0 ,
197- scanCode = 0 ,
172+ result = performKeyEventActionDelegate.perform(
173+ action,
174+ inputEventAction,
175+ keyMetaState,
176+ device,
198177 )
199-
200- if (inputEventAction == InputEventAction .DOWN_UP ) {
201- result = inputEventHub.injectKeyEvent(
202- model,
203- useSystemBridgeIfAvailable = injectKeyEventsWithSystemBridge.value,
204- )
205- .then {
206- inputEventHub.injectKeyEvent(
207- model.copy(action = KeyEvent .ACTION_UP ),
208- useSystemBridgeIfAvailable = injectKeyEventsWithSystemBridge.value,
209- )
210- }
211- } else {
212- result = inputEventHub.injectKeyEvent(
213- model,
214- useSystemBridgeIfAvailable = injectKeyEventsWithSystemBridge.value,
215- )
216- }
217178 }
218179
219180 is ActionData .PhoneCall -> {
@@ -1108,53 +1069,6 @@ class PerformActionsUseCaseImpl @AssistedInject constructor(
11081069 .map { it ? : PreferenceDefaults .HOLD_DOWN_DURATION }
11091070 .map { it.toLong() }
11101071
1111- private fun getDeviceIdForKeyEventAction (action : ActionData .InputKeyEvent ): Int {
1112- if (action.device?.descriptor == null ) {
1113- // automatically select a game controller as the input device for game controller key events
1114-
1115- if (KeyEventUtils .isGamepadKeyCode(action.keyCode)) {
1116- devicesAdapter.connectedInputDevices.value.ifIsData { inputDevices ->
1117- val device = inputDevices.find { it.isGameController }
1118-
1119- if (device != null ) {
1120- return device.id
1121- }
1122- }
1123- }
1124-
1125- return 0
1126- }
1127-
1128- val inputDevices = devicesAdapter.connectedInputDevices.value
1129-
1130- val devicesWithSameDescriptor =
1131- inputDevices.dataOrNull()
1132- ?.filter { it.descriptor == action.device.descriptor }
1133- ? : emptyList()
1134-
1135- if (devicesWithSameDescriptor.isEmpty()) {
1136- return - 1
1137- }
1138-
1139- if (devicesWithSameDescriptor.size == 1 ) {
1140- return devicesWithSameDescriptor[0 ].id
1141- }
1142-
1143- /*
1144- if there are multiple devices use the device that supports the key
1145- code. if none do then use the first one
1146- */
1147- val deviceThatHasKey = devicesWithSameDescriptor.singleOrNull {
1148- devicesAdapter.deviceHasKey(it.id, action.keyCode)
1149- }
1150-
1151- val device = deviceThatHasKey
1152- ? : devicesWithSameDescriptor.singleOrNull { it.name == action.device.name }
1153- ? : devicesWithSameDescriptor[0 ]
1154-
1155- return device.id
1156- }
1157-
11581072 private fun closeStatusBarShade (): KMResult <* > {
11591073 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S ) {
11601074 return service
@@ -1233,6 +1147,7 @@ interface PerformActionsUseCase {
12331147 action : ActionData ,
12341148 inputEventAction : InputEventAction = InputEventAction .DOWN_UP ,
12351149 keyMetaState : Int = 0,
1150+ device : PerformActionTriggerDevice = PerformActionTriggerDevice .Default ,
12361151 )
12371152
12381153 fun getErrorSnapshot (): ActionErrorSnapshot
0 commit comments