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 18 package com.android.systemui.user.ui.dialog 19 20 import android.app.Dialog 21 import android.content.Context 22 import com.android.internal.jank.InteractionJankMonitor 23 import com.android.internal.logging.UiEventLogger 24 import com.android.settingslib.users.UserCreatingDialog 25 import com.android.systemui.CoreStartable 26 import com.android.systemui.animation.DialogCuj 27 import com.android.systemui.animation.DialogTransitionAnimator 28 import com.android.systemui.broadcast.BroadcastSender 29 import com.android.systemui.classifier.FalsingCollector 30 import com.android.systemui.dagger.SysUISingleton 31 import com.android.systemui.dagger.qualifiers.Application 32 import com.android.systemui.plugins.ActivityStarter 33 import com.android.systemui.plugins.FalsingManager 34 import com.android.systemui.qs.tiles.UserDetailView 35 import com.android.systemui.user.UserSwitchFullscreenDialog 36 import com.android.systemui.user.domain.interactor.UserSwitcherInteractor 37 import com.android.systemui.user.domain.model.ShowDialogRequestModel 38 import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel 39 import dagger.Lazy 40 import javax.inject.Inject 41 import javax.inject.Provider 42 import kotlinx.coroutines.CoroutineScope 43 import kotlinx.coroutines.flow.filterNotNull 44 import kotlinx.coroutines.launch 45 46 /** Coordinates dialogs for user switcher logic. */ 47 @SysUISingleton 48 class UserSwitcherDialogCoordinator 49 @Inject 50 constructor( 51 @Application private val context: Lazy<Context>, 52 @Application private val applicationScope: Lazy<CoroutineScope>, 53 private val falsingManager: Lazy<FalsingManager>, 54 private val broadcastSender: Lazy<BroadcastSender>, 55 private val dialogTransitionAnimator: Lazy<DialogTransitionAnimator>, 56 private val interactor: Lazy<UserSwitcherInteractor>, 57 private val userDetailAdapterProvider: Provider<UserDetailView.Adapter>, 58 private val eventLogger: Lazy<UiEventLogger>, 59 private val activityStarter: Lazy<ActivityStarter>, 60 private val falsingCollector: Lazy<FalsingCollector>, 61 private val userSwitcherViewModel: Lazy<UserSwitcherViewModel>, 62 ) : CoreStartable { 63 64 private var currentDialog: Dialog? = null 65 66 override fun start() { 67 startHandlingDialogShowRequests() 68 startHandlingDialogDismissRequests() 69 } 70 71 private fun startHandlingDialogShowRequests() { 72 applicationScope.get().launch { 73 interactor.get().dialogShowRequests.filterNotNull().collect { request -> 74 val (dialog, dialogCuj) = 75 when (request) { 76 is ShowDialogRequestModel.ShowAddUserDialog -> 77 Pair( 78 AddUserDialog( 79 context = context.get(), 80 userHandle = request.userHandle, 81 isKeyguardShowing = request.isKeyguardShowing, 82 showEphemeralMessage = request.showEphemeralMessage, 83 falsingManager = falsingManager.get(), 84 broadcastSender = broadcastSender.get(), 85 dialogTransitionAnimator = dialogTransitionAnimator.get(), 86 ), 87 DialogCuj( 88 InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, 89 INTERACTION_JANK_ADD_NEW_USER_TAG, 90 ), 91 ) 92 is ShowDialogRequestModel.ShowUserCreationDialog -> 93 Pair( 94 UserCreatingDialog( 95 context.get(), 96 request.isGuest, 97 ), 98 null, 99 ) 100 is ShowDialogRequestModel.ShowExitGuestDialog -> 101 Pair( 102 ExitGuestDialog( 103 context = context.get(), 104 guestUserId = request.guestUserId, 105 isGuestEphemeral = request.isGuestEphemeral, 106 targetUserId = request.targetUserId, 107 isKeyguardShowing = request.isKeyguardShowing, 108 falsingManager = falsingManager.get(), 109 dialogTransitionAnimator = dialogTransitionAnimator.get(), 110 onExitGuestUserListener = request.onExitGuestUser, 111 ), 112 DialogCuj( 113 InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, 114 INTERACTION_JANK_EXIT_GUEST_MODE_TAG, 115 ), 116 ) 117 is ShowDialogRequestModel.ShowUserSwitcherDialog -> 118 Pair( 119 UserSwitchDialog( 120 context = context.get(), 121 adapter = userDetailAdapterProvider.get(), 122 uiEventLogger = eventLogger.get(), 123 falsingManager = falsingManager.get(), 124 activityStarter = activityStarter.get(), 125 dialogTransitionAnimator = dialogTransitionAnimator.get(), 126 ), 127 DialogCuj( 128 InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, 129 INTERACTION_JANK_EXIT_GUEST_MODE_TAG, 130 ), 131 ) 132 is ShowDialogRequestModel.ShowUserSwitcherFullscreenDialog -> 133 Pair( 134 UserSwitchFullscreenDialog( 135 context = context.get(), 136 falsingCollector = falsingCollector.get(), 137 userSwitcherViewModel = userSwitcherViewModel.get(), 138 ), 139 null, /* dialogCuj */ 140 ) 141 } 142 currentDialog = dialog 143 144 val controller = request.expandable?.dialogTransitionController(dialogCuj) 145 if (controller != null) { 146 dialogTransitionAnimator.get().show(dialog, controller) 147 } else if (request.dialogShower != null && dialogCuj != null) { 148 request.dialogShower?.showDialog(dialog, dialogCuj) 149 } else { 150 dialog.show() 151 } 152 153 interactor.get().onDialogShown() 154 } 155 } 156 } 157 158 private fun startHandlingDialogDismissRequests() { 159 applicationScope.get().launch { 160 interactor.get().dialogDismissRequests.filterNotNull().collect { 161 currentDialog?.let { 162 if (it.isShowing) { 163 it.cancel() 164 } 165 } 166 167 interactor.get().onDialogDismissed() 168 } 169 } 170 } 171 172 companion object { 173 private const val INTERACTION_JANK_ADD_NEW_USER_TAG = "add_new_user" 174 private const val INTERACTION_JANK_EXIT_GUEST_MODE_TAG = "exit_guest_mode" 175 } 176 } 177