1 /* 2 * Copyright (C) 2014 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; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.pm.UserInfo; 23 import android.os.UserHandle; 24 25 import androidx.annotation.NonNull; 26 27 import com.android.internal.annotations.VisibleForTesting; 28 import com.android.internal.logging.UiEventLogger; 29 import com.android.systemui.broadcast.BroadcastDispatcher; 30 import com.android.systemui.dagger.qualifiers.Main; 31 import com.android.systemui.qs.QSUserSwitcherEvent; 32 import com.android.systemui.settings.UserTracker; 33 import com.android.systemui.statusbar.phone.SystemUIDialog; 34 import com.android.systemui.statusbar.policy.UserSwitcherController; 35 import com.android.systemui.util.settings.SecureSettings; 36 37 import java.util.concurrent.Executor; 38 39 import javax.inject.Inject; 40 41 import dagger.assisted.Assisted; 42 import dagger.assisted.AssistedFactory; 43 import dagger.assisted.AssistedInject; 44 45 /** 46 * Manages notification when a guest session is resumed. 47 */ 48 public class GuestResumeSessionReceiver { 49 50 @VisibleForTesting 51 public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in"; 52 53 @VisibleForTesting 54 public AlertDialog mNewSessionDialog; 55 private final Executor mMainExecutor; 56 private final UserTracker mUserTracker; 57 private final SecureSettings mSecureSettings; 58 private final ResetSessionDialog.Factory mResetSessionDialogFactory; 59 private final GuestSessionNotification mGuestSessionNotification; 60 61 @VisibleForTesting 62 public final UserTracker.Callback mUserChangedCallback = 63 new UserTracker.Callback() { 64 @Override 65 public void onUserChanged(int newUser, @NonNull Context userContext) { 66 cancelDialog(); 67 68 UserInfo currentUser = mUserTracker.getUserInfo(); 69 if (!currentUser.isGuest()) { 70 return; 71 } 72 73 int guestLoginState = mSecureSettings.getIntForUser( 74 SETTING_GUEST_HAS_LOGGED_IN, 0, newUser); 75 76 if (guestLoginState == 0) { 77 // set 1 to indicate, 1st login 78 guestLoginState = 1; 79 mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, 80 newUser); 81 } else if (guestLoginState == 1) { 82 // set 2 to indicate, 2nd or later login 83 guestLoginState = 2; 84 mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, 85 newUser); 86 } 87 88 mGuestSessionNotification.createPersistentNotification(currentUser, 89 (guestLoginState <= 1)); 90 91 if (guestLoginState > 1) { 92 mNewSessionDialog = mResetSessionDialogFactory.create(newUser); 93 mNewSessionDialog.show(); 94 } 95 } 96 }; 97 98 @Inject GuestResumeSessionReceiver( @ain Executor mainExecutor, UserTracker userTracker, SecureSettings secureSettings, GuestSessionNotification guestSessionNotification, ResetSessionDialog.Factory resetSessionDialogFactory)99 public GuestResumeSessionReceiver( 100 @Main Executor mainExecutor, 101 UserTracker userTracker, 102 SecureSettings secureSettings, 103 GuestSessionNotification guestSessionNotification, 104 ResetSessionDialog.Factory resetSessionDialogFactory) { 105 mMainExecutor = mainExecutor; 106 mUserTracker = userTracker; 107 mSecureSettings = secureSettings; 108 mGuestSessionNotification = guestSessionNotification; 109 mResetSessionDialogFactory = resetSessionDialogFactory; 110 } 111 112 /** 113 * Register this receiver with the {@link BroadcastDispatcher} 114 */ register()115 public void register() { 116 mUserTracker.addCallback(mUserChangedCallback, mMainExecutor); 117 } 118 cancelDialog()119 private void cancelDialog() { 120 if (mNewSessionDialog != null && mNewSessionDialog.isShowing()) { 121 mNewSessionDialog.cancel(); 122 mNewSessionDialog = null; 123 } 124 } 125 126 /** 127 * Dialog shown when user when asking for confirmation before deleting guest user. 128 */ 129 @VisibleForTesting 130 public static class ResetSessionDialog extends SystemUIDialog implements 131 DialogInterface.OnClickListener { 132 133 @VisibleForTesting 134 public static final int BUTTON_WIPE = BUTTON_NEGATIVE; 135 @VisibleForTesting 136 public static final int BUTTON_DONTWIPE = BUTTON_POSITIVE; 137 138 private final UserSwitcherController mUserSwitcherController; 139 private final UiEventLogger mUiEventLogger; 140 private final int mUserId; 141 142 143 /** Factory class to create guest reset dialog instance */ 144 @AssistedFactory 145 public interface Factory { 146 /** Create a guest reset dialog instance */ create(int userId)147 ResetSessionDialog create(int userId); 148 } 149 150 @AssistedInject ResetSessionDialog(Context context, UserSwitcherController userSwitcherController, UiEventLogger uiEventLogger, @Assisted int userId)151 public ResetSessionDialog(Context context, 152 UserSwitcherController userSwitcherController, 153 UiEventLogger uiEventLogger, 154 @Assisted int userId) { 155 super(context, false /* dismissOnDeviceLock */); 156 157 setTitle(context.getString(R.string.guest_wipe_session_title)); 158 setMessage(context.getString(R.string.guest_wipe_session_message)); 159 setCanceledOnTouchOutside(false); 160 161 setButton(BUTTON_WIPE, 162 context.getString(R.string.guest_wipe_session_wipe), this); 163 setButton(BUTTON_DONTWIPE, 164 context.getString(R.string.guest_wipe_session_dontwipe), this); 165 166 mUserSwitcherController = userSwitcherController; 167 mUiEventLogger = uiEventLogger; 168 mUserId = userId; 169 } 170 171 @Override onClick(DialogInterface dialog, int which)172 public void onClick(DialogInterface dialog, int which) { 173 if (which == BUTTON_WIPE) { 174 mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_WIPE); 175 mUserSwitcherController.removeGuestUser(mUserId, UserHandle.USER_NULL); 176 dismiss(); 177 } else if (which == BUTTON_DONTWIPE) { 178 mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_CONTINUE); 179 cancel(); 180 } 181 } 182 } 183 } 184