• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.shade.ShadeDisplayAware
44 import com.android.systemui.statusbar.policy.DeviceProvisionedController
45 import com.android.systemui.user.data.repository.UserSwitcherRepository
46 import com.android.systemui.user.domain.interactor.UserSwitcherInteractor
47 import javax.inject.Inject
48 import kotlinx.coroutines.CoroutineDispatcher
49 import kotlinx.coroutines.flow.Flow
50 import kotlinx.coroutines.flow.map
51 import kotlinx.coroutines.withContext
52 
53 /** Interactor for the footer actions business logic. */
54 interface FooterActionsInteractor {
55     /** The current [SecurityButtonConfig]. */
56     val securityButtonConfig: Flow<SecurityButtonConfig?>
57 
58     /** The number of packages with a service running in the foreground. */
59     val foregroundServicesCount: Flow<Int>
60 
61     /** Whether there are new packages with a service running in the foreground. */
62     val hasNewForegroundServices: Flow<Boolean>
63 
64     /** The current [UserSwitcherStatusModel]. */
65     val userSwitcherStatus: Flow<UserSwitcherStatusModel>
66 
67     /**
68      * The flow emitting `Unit` whenever a request to show the device monitoring dialog is fired.
69      */
70     val deviceMonitoringDialogRequests: Flow<Unit>
71 
72     /**
73      * Show the device monitoring dialog, expanded from [expandable] if it's not null.
74      *
75      * Important: [quickSettingsContext] *must* be the [Context] associated to the
76      * [Quick Settings fragment][com.android.systemui.qs.QSFragmentLegacy].
77      */
78     fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)
79 
80     /** Show the foreground services dialog. */
81     fun showForegroundServicesDialog(expandable: Expandable)
82 
83     /** Show the power menu dialog. */
84     fun showPowerMenuDialog(
85         globalActionsDialogLite: GlobalActionsDialogLite,
86         expandable: Expandable,
87     )
88 
89     /** Show the settings. */
90     fun showSettings(expandable: Expandable)
91 
92     /** Show the user switcher. */
93     fun showUserSwitcher(expandable: Expandable)
94 }
95 
96 @SysUISingleton
97 class FooterActionsInteractorImpl
98 @Inject
99 constructor(
100     private val activityStarter: ActivityStarter,
101     private val metricsLogger: MetricsLogger,
102     private val uiEventLogger: UiEventLogger,
103     private val deviceProvisionedController: DeviceProvisionedController,
104     private val qsSecurityFooterUtils: QSSecurityFooterUtils,
105     private val fgsManagerController: FgsManagerController,
106     private val userSwitcherInteractor: UserSwitcherInteractor,
107     securityRepository: SecurityRepository,
108     foregroundServicesRepository: ForegroundServicesRepository,
109     userSwitcherRepository: UserSwitcherRepository,
110     broadcastDispatcher: BroadcastDispatcher,
111     @Background bgDispatcher: CoroutineDispatcher,
112     @ShadeDisplayAware private val context: Context,
113 ) : FooterActionsInteractor {
114     override val securityButtonConfig: Flow<SecurityButtonConfig?> =
securitynull115         securityRepository.security.map { security ->
116             withContext(bgDispatcher) { qsSecurityFooterUtils.getButtonConfig(security) }
117         }
118 
119     override val foregroundServicesCount: Flow<Int> =
120         foregroundServicesRepository.foregroundServicesCount
121 
122     override val hasNewForegroundServices: Flow<Boolean> =
123         foregroundServicesRepository.hasNewChanges
124 
125     override val userSwitcherStatus: Flow<UserSwitcherStatusModel> =
126         userSwitcherRepository.userSwitcherStatus
127 
128     override val deviceMonitoringDialogRequests: Flow<Unit> =
129         broadcastDispatcher.broadcastFlow(
130             IntentFilter(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG),
131             UserHandle.ALL,
132             Context.RECEIVER_EXPORTED,
133             null,
134         )
135 
showDeviceMonitoringDialognull136     override fun showDeviceMonitoringDialog(
137         quickSettingsContext: Context,
138         expandable: Expandable?,
139     ) {
140         qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, expandable)
141         if (expandable != null) {
142             DevicePolicyEventLogger.createEvent(
143                     FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
144                 )
145                 .write()
146         }
147     }
148 
showForegroundServicesDialognull149     override fun showForegroundServicesDialog(expandable: Expandable) {
150         fgsManagerController.showDialog(expandable)
151     }
152 
showPowerMenuDialognull153     override fun showPowerMenuDialog(
154         globalActionsDialogLite: GlobalActionsDialogLite,
155         expandable: Expandable,
156     ) {
157         uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
158         globalActionsDialogLite.showOrHideDialog(
159             /* keyguardShowing= */ false,
160             /* isDeviceProvisioned= */ true,
161             expandable,
162             context.displayId,
163         )
164     }
165 
showSettingsnull166     override fun showSettings(expandable: Expandable) {
167         if (!deviceProvisionedController.isCurrentUserSetup) {
168             // If user isn't setup just unlock the device and dump them back at SUW.
169             activityStarter.postQSRunnableDismissingKeyguard {}
170             return
171         }
172 
173         metricsLogger.action(MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH)
174         activityStarter.startActivity(
175             Intent(Settings.ACTION_SETTINGS),
176             true /* dismissShade */,
177             expandable.activityTransitionController(
178                 InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON
179             ),
180         )
181     }
182 
showUserSwitchernull183     override fun showUserSwitcher(expandable: Expandable) {
184         userSwitcherInteractor.showUserSwitcher(expandable)
185     }
186 }
187