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.stickykeys.data.repository 18 19 import android.hardware.input.InputManager 20 import android.hardware.input.InputManager.StickyModifierStateListener 21 import android.hardware.input.StickyModifierState 22 import android.provider.Settings 23 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging 24 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow 25 import com.android.systemui.dagger.SysUISingleton 26 import com.android.systemui.dagger.qualifiers.Background 27 import com.android.systemui.keyboard.stickykeys.StickyKeysLogger 28 import com.android.systemui.keyboard.stickykeys.shared.model.Locked 29 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey 30 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.ALT 31 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.ALT_GR 32 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.CTRL 33 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.META 34 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT 35 import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository 36 import kotlinx.coroutines.CoroutineDispatcher 37 import kotlinx.coroutines.channels.awaitClose 38 import kotlinx.coroutines.flow.Flow 39 import kotlinx.coroutines.flow.flowOn 40 import kotlinx.coroutines.flow.map 41 import kotlinx.coroutines.flow.onEach 42 import javax.inject.Inject 43 44 interface StickyKeysRepository { 45 val stickyKeys: Flow<LinkedHashMap<ModifierKey, Locked>> 46 val settingEnabled: Flow<Boolean> 47 } 48 49 @SysUISingleton 50 class StickyKeysRepositoryImpl 51 @Inject 52 constructor( 53 private val inputManager: InputManager, 54 @Background private val backgroundDispatcher: CoroutineDispatcher, 55 secureSettingsRepository: UserAwareSecureSettingsRepository, 56 private val stickyKeysLogger: StickyKeysLogger, 57 ) : StickyKeysRepository { 58 59 override val stickyKeys: Flow<LinkedHashMap<ModifierKey, Locked>> = <lambda>null60 conflatedCallbackFlow { 61 val listener = StickyModifierStateListener { stickyModifierState -> 62 trySendWithFailureLogging(stickyModifierState, TAG) 63 } 64 // after registering, InputManager calls listener with the current value 65 inputManager.registerStickyModifierStateListener(Runnable::run, listener) 66 awaitClose { inputManager.unregisterStickyModifierStateListener(listener) } 67 } <lambda>null68 .map { toStickyKeysMap(it) } <lambda>null69 .onEach { stickyKeysLogger.logNewStickyKeysReceived(it) } 70 .flowOn(backgroundDispatcher) 71 72 override val settingEnabled: Flow<Boolean> = 73 secureSettingsRepository 74 .boolSettingForActiveUser(SETTING_KEY, defaultValue = false) <lambda>null75 .onEach { stickyKeysLogger.logNewSettingValue(it) } 76 .flowOn(backgroundDispatcher) 77 toStickyKeysMapnull78 private fun toStickyKeysMap(state: StickyModifierState): LinkedHashMap<ModifierKey, Locked> { 79 val keys = linkedMapOf<ModifierKey, Locked>() 80 state.apply { 81 if (isAltGrModifierOn) keys[ALT_GR] = Locked(false) 82 if (isAltGrModifierLocked) keys[ALT_GR] = Locked(true) 83 if (isAltModifierOn) keys[ALT] = Locked(false) 84 if (isAltModifierLocked) keys[ALT] = Locked(true) 85 if (isCtrlModifierOn) keys[CTRL] = Locked(false) 86 if (isCtrlModifierLocked) keys[CTRL] = Locked(true) 87 if (isMetaModifierOn) keys[META] = Locked(false) 88 if (isMetaModifierLocked) keys[META] = Locked(true) 89 if (isShiftModifierOn) keys[SHIFT] = Locked(false) 90 if (isShiftModifierLocked) keys[SHIFT] = Locked(true) 91 } 92 return keys 93 } 94 95 companion object { 96 const val TAG = "StickyKeysRepositoryImpl" 97 const val SETTING_KEY = Settings.Secure.ACCESSIBILITY_STICKY_KEYS 98 } 99 } 100