1 /* <lambda>null2 * Copyright (C) 2022 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.qs.footer.domain.interactor 18 19 import android.app.admin.DevicePolicyEventLogger 20 import android.app.admin.DevicePolicyManager 21 import android.content.Context 22 import android.content.Intent 23 import android.content.IntentFilter 24 import android.os.UserHandle 25 import android.provider.Settings 26 import com.android.internal.jank.InteractionJankMonitor 27 import com.android.internal.logging.MetricsLogger 28 import com.android.internal.logging.UiEventLogger 29 import com.android.internal.logging.nano.MetricsProto 30 import com.android.internal.util.FrameworkStatsLog 31 import com.android.systemui.animation.Expandable 32 import com.android.systemui.broadcast.BroadcastDispatcher 33 import com.android.systemui.dagger.SysUISingleton 34 import com.android.systemui.dagger.qualifiers.Background 35 import com.android.systemui.globalactions.GlobalActionsDialogLite 36 import com.android.systemui.plugins.ActivityStarter 37 import com.android.systemui.qs.FgsManagerController 38 import com.android.systemui.qs.QSSecurityFooterUtils 39 import com.android.systemui.qs.footer.data.model.UserSwitcherStatusModel 40 import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepository 41 import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig 42 import com.android.systemui.security.data.repository.SecurityRepository 43 import com.android.systemui.statusbar.policy.DeviceProvisionedController 44 import com.android.systemui.user.data.repository.UserSwitcherRepository 45 import com.android.systemui.user.domain.interactor.UserSwitcherInteractor 46 import javax.inject.Inject 47 import kotlinx.coroutines.CoroutineDispatcher 48 import kotlinx.coroutines.flow.Flow 49 import kotlinx.coroutines.flow.map 50 import kotlinx.coroutines.withContext 51 52 /** Interactor for the footer actions business logic. */ 53 interface FooterActionsInteractor { 54 /** The current [SecurityButtonConfig]. */ 55 val securityButtonConfig: Flow<SecurityButtonConfig?> 56 57 /** The number of packages with a service running in the foreground. */ 58 val foregroundServicesCount: Flow<Int> 59 60 /** Whether there are new packages with a service running in the foreground. */ 61 val hasNewForegroundServices: Flow<Boolean> 62 63 /** The current [UserSwitcherStatusModel]. */ 64 val userSwitcherStatus: Flow<UserSwitcherStatusModel> 65 66 /** 67 * The flow emitting `Unit` whenever a request to show the device monitoring dialog is fired. 68 */ 69 val deviceMonitoringDialogRequests: Flow<Unit> 70 71 /** 72 * Show the device monitoring dialog, expanded from [expandable] if it's not null. 73 * 74 * Important: [quickSettingsContext] *must* be the [Context] associated to the 75 * [Quick Settings fragment][com.android.systemui.qs.QSFragmentLegacy]. 76 */ 77 fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?) 78 79 /** Show the foreground services dialog. */ 80 fun showForegroundServicesDialog(expandable: Expandable) 81 82 /** Show the power menu dialog. */ 83 fun showPowerMenuDialog( 84 globalActionsDialogLite: GlobalActionsDialogLite, 85 expandable: Expandable, 86 ) 87 88 /** Show the settings. */ 89 fun showSettings(expandable: Expandable) 90 91 /** Show the user switcher. */ 92 fun showUserSwitcher(expandable: Expandable) 93 } 94 95 @SysUISingleton 96 class FooterActionsInteractorImpl 97 @Inject 98 constructor( 99 private val activityStarter: ActivityStarter, 100 private val metricsLogger: MetricsLogger, 101 private val uiEventLogger: UiEventLogger, 102 private val deviceProvisionedController: DeviceProvisionedController, 103 private val qsSecurityFooterUtils: QSSecurityFooterUtils, 104 private val fgsManagerController: FgsManagerController, 105 private val userSwitcherInteractor: UserSwitcherInteractor, 106 securityRepository: SecurityRepository, 107 foregroundServicesRepository: ForegroundServicesRepository, 108 userSwitcherRepository: UserSwitcherRepository, 109 broadcastDispatcher: BroadcastDispatcher, 110 @Background bgDispatcher: CoroutineDispatcher, 111 ) : FooterActionsInteractor { 112 override val securityButtonConfig: Flow<SecurityButtonConfig?> = securitynull113 securityRepository.security.map { security -> 114 withContext(bgDispatcher) { qsSecurityFooterUtils.getButtonConfig(security) } 115 } 116 117 override val foregroundServicesCount: Flow<Int> = 118 foregroundServicesRepository.foregroundServicesCount 119 120 override val hasNewForegroundServices: Flow<Boolean> = 121 foregroundServicesRepository.hasNewChanges 122 123 override val userSwitcherStatus: Flow<UserSwitcherStatusModel> = 124 userSwitcherRepository.userSwitcherStatus 125 126 override val deviceMonitoringDialogRequests: Flow<Unit> = 127 broadcastDispatcher.broadcastFlow( 128 IntentFilter(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG), 129 UserHandle.ALL, 130 Context.RECEIVER_EXPORTED, 131 null, 132 ) 133 showDeviceMonitoringDialognull134 override fun showDeviceMonitoringDialog( 135 quickSettingsContext: Context, 136 expandable: Expandable?, 137 ) { 138 qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, expandable) 139 if (expandable != null) { 140 DevicePolicyEventLogger.createEvent( 141 FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED 142 ) 143 .write() 144 } 145 } 146 showForegroundServicesDialognull147 override fun showForegroundServicesDialog(expandable: Expandable) { 148 fgsManagerController.showDialog(expandable) 149 } 150 showPowerMenuDialognull151 override fun showPowerMenuDialog( 152 globalActionsDialogLite: GlobalActionsDialogLite, 153 expandable: Expandable, 154 ) { 155 uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS) 156 globalActionsDialogLite.showOrHideDialog( 157 /* keyguardShowing= */ false, 158 /* isDeviceProvisioned= */ true, 159 expandable, 160 ) 161 } 162 showSettingsnull163 override fun showSettings(expandable: Expandable) { 164 if (!deviceProvisionedController.isCurrentUserSetup) { 165 // If user isn't setup just unlock the device and dump them back at SUW. 166 activityStarter.postQSRunnableDismissingKeyguard {} 167 return 168 } 169 170 metricsLogger.action(MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH) 171 activityStarter.startActivity( 172 Intent(Settings.ACTION_SETTINGS), 173 true /* dismissShade */, 174 expandable.activityTransitionController( 175 InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON 176 ), 177 ) 178 } 179 showUserSwitchernull180 override fun showUserSwitcher(expandable: Expandable) { 181 userSwitcherInteractor.showUserSwitcher(expandable) 182 } 183 } 184