1 /* 2 * 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 18 19 import android.content.BroadcastReceiver 20 import android.content.Context 21 import android.content.Intent 22 import android.content.IntentFilter 23 import android.os.UserHandle 24 import com.android.systemui.CoreStartable 25 import com.android.systemui.broadcast.BroadcastDispatcher 26 import com.android.systemui.dagger.SysUISingleton 27 import com.android.systemui.dagger.qualifiers.Background 28 import com.android.systemui.keyboard.shortcut.data.repository.CustomInputGesturesRepository 29 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository 30 import com.android.systemui.plugins.ActivityStarter 31 import com.android.systemui.statusbar.CommandQueue 32 import javax.inject.Inject 33 import kotlinx.coroutines.CoroutineScope 34 import kotlinx.coroutines.launch 35 36 @SysUISingleton 37 class ShortcutHelperCoreStartable 38 @Inject 39 constructor( 40 private val commandQueue: CommandQueue, 41 private val broadcastDispatcher: BroadcastDispatcher, 42 private val stateRepository: ShortcutHelperStateRepository, 43 private val activityStarter: ActivityStarter, 44 @Background private val backgroundScope: CoroutineScope, 45 private val customInputGesturesRepository: CustomInputGesturesRepository 46 ) : CoreStartable { startnull47 override fun start() { 48 registerBroadcastReceiver( 49 action = Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS, 50 onReceive = { showShortcutHelper() }, 51 ) 52 registerBroadcastReceiver( 53 action = Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS, 54 onReceive = { stateRepository.hide() }, 55 ) 56 registerBroadcastReceiver( 57 action = Intent.ACTION_CLOSE_SYSTEM_DIALOGS, 58 onReceive = { stateRepository.hide() }, 59 ) 60 registerBroadcastReceiver( 61 action = Intent.ACTION_USER_SWITCHED, 62 onReceive = { customInputGesturesRepository.refreshCustomInputGestures() }, 63 ) 64 commandQueue.addCallback( 65 object : CommandQueue.Callbacks { 66 override fun dismissKeyboardShortcutsMenu() { 67 stateRepository.hide() 68 } 69 70 override fun toggleKeyboardShortcutsMenu(deviceId: Int) { 71 toggleShortcutHelper(deviceId) 72 } 73 } 74 ) 75 } 76 registerBroadcastReceivernull77 private fun registerBroadcastReceiver(action: String, onReceive: () -> Unit) { 78 broadcastDispatcher.registerReceiver( 79 receiver = 80 object : BroadcastReceiver() { 81 override fun onReceive(context: Context, intent: Intent) { 82 onReceive() 83 } 84 }, 85 filter = IntentFilter(action), 86 flags = Context.RECEIVER_EXPORTED or Context.RECEIVER_VISIBLE_TO_INSTANT_APPS, 87 user = UserHandle.ALL, 88 ) 89 } 90 showShortcutHelpernull91 private fun showShortcutHelper() { 92 dismissKeyguardThenPerformShortcutHelperAction { stateRepository.show() } 93 } 94 toggleShortcutHelpernull95 private fun toggleShortcutHelper(deviceId: Int? = null) { 96 dismissKeyguardThenPerformShortcutHelperAction { stateRepository.toggle(deviceId) } 97 } 98 dismissKeyguardThenPerformShortcutHelperActionnull99 private fun dismissKeyguardThenPerformShortcutHelperAction(action: suspend () -> Unit) { 100 activityStarter.dismissKeyguardThenExecute( 101 /* action= */ { 102 backgroundScope.launch { action() } 103 false 104 }, 105 /* cancel= */ {}, 106 /* afterKeyguardGone= */ true, 107 ) 108 } 109 } 110