blob: 8387c1dd60a5538055e2c51d88a70aaf04faeb31 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.qs.footer.domain.interactor
import android.app.admin.DevicePolicyEventLogger
import android.app.admin.DevicePolicyManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.UserHandle
import android.provider.Settings
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.nano.MetricsProto
import com.android.internal.util.FrameworkStatsLog
import com.android.systemui.animation.Expandable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.FgsManagerController
import com.android.systemui.qs.QSSecurityFooterUtils
import com.android.systemui.qs.footer.data.model.UserSwitcherStatusModel
import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepository
import com.android.systemui.qs.footer.data.repository.UserSwitcherRepository
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig
import com.android.systemui.security.data.repository.SecurityRepository
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.user.domain.interactor.UserInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
/** Interactor for the footer actions business logic. */
interface FooterActionsInteractor {
/** The current [SecurityButtonConfig]. */
val securityButtonConfig: Flow<SecurityButtonConfig?>
/** The number of packages with a service running in the foreground. */
val foregroundServicesCount: Flow<Int>
/** Whether there are new packages with a service running in the foreground. */
val hasNewForegroundServices: Flow<Boolean>
/** The current [UserSwitcherStatusModel]. */
val userSwitcherStatus: Flow<UserSwitcherStatusModel>
/**
* The flow emitting `Unit` whenever a request to show the device monitoring dialog is fired.
*/
val deviceMonitoringDialogRequests: Flow<Unit>
/**
* Show the device monitoring dialog, expanded from [expandable] if it's not null.
*
* Important: [quickSettingsContext] *must* be the [Context] associated to the
* [Quick Settings fragment][com.android.systemui.qs.QSFragment].
*/
fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)
/** Show the foreground services dialog. */
fun showForegroundServicesDialog(expandable: Expandable)
/** Show the power menu dialog. */
fun showPowerMenuDialog(
globalActionsDialogLite: GlobalActionsDialogLite,
expandable: Expandable,
)
/** Show the settings. */
fun showSettings(expandable: Expandable)
/** Show the user switcher. */
fun showUserSwitcher(context: Context, expandable: Expandable)
}
@SysUISingleton
class FooterActionsInteractorImpl
@Inject
constructor(
private val activityStarter: ActivityStarter,
private val metricsLogger: MetricsLogger,
private val uiEventLogger: UiEventLogger,
private val deviceProvisionedController: DeviceProvisionedController,
private val qsSecurityFooterUtils: QSSecurityFooterUtils,
private val fgsManagerController: FgsManagerController,
private val userInteractor: UserInteractor,
securityRepository: SecurityRepository,
foregroundServicesRepository: ForegroundServicesRepository,
userSwitcherRepository: UserSwitcherRepository,
broadcastDispatcher: BroadcastDispatcher,
@Background bgDispatcher: CoroutineDispatcher,
) : FooterActionsInteractor {
override val securityButtonConfig: Flow<SecurityButtonConfig?> =
securityRepository.security.map { security ->
withContext(bgDispatcher) { qsSecurityFooterUtils.getButtonConfig(security) }
}
override val foregroundServicesCount: Flow<Int> =
foregroundServicesRepository.foregroundServicesCount
override val hasNewForegroundServices: Flow<Boolean> =
foregroundServicesRepository.hasNewChanges
override val userSwitcherStatus: Flow<UserSwitcherStatusModel> =
userSwitcherRepository.userSwitcherStatus
override val deviceMonitoringDialogRequests: Flow<Unit> =
broadcastDispatcher.broadcastFlow(
IntentFilter(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG),
UserHandle.ALL,
Context.RECEIVER_EXPORTED,
null,
)
override fun showDeviceMonitoringDialog(
quickSettingsContext: Context,
expandable: Expandable?,
) {
qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, expandable)
if (expandable != null) {
DevicePolicyEventLogger.createEvent(
FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
)
.write()
}
}
override fun showForegroundServicesDialog(expandable: Expandable) {
fgsManagerController.showDialog(expandable)
}
override fun showPowerMenuDialog(
globalActionsDialogLite: GlobalActionsDialogLite,
expandable: Expandable,
) {
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
globalActionsDialogLite.showOrHideDialog(
/* keyguardShowing= */ false,
/* isDeviceProvisioned= */ true,
expandable,
)
}
override fun showSettings(expandable: Expandable) {
if (!deviceProvisionedController.isCurrentUserSetup) {
// If user isn't setup just unlock the device and dump them back at SUW.
activityStarter.postQSRunnableDismissingKeyguard {}
return
}
metricsLogger.action(MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH)
activityStarter.startActivity(
Intent(Settings.ACTION_SETTINGS),
true /* dismissShade */,
expandable.activityLaunchController(
InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON
),
)
}
override fun showUserSwitcher(context: Context, expandable: Expandable) {
userInteractor.showUserSwitcher(context, expandable)
}
}