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.ActivityManager; 20 import android.app.Dialog; 21 import android.content.BroadcastReceiver; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.content.pm.UserInfo; 28 import android.os.RemoteException; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.provider.Settings; 32 import android.util.Log; 33 import android.view.WindowManagerGlobal; 34 35 import com.android.systemui.broadcast.BroadcastDispatcher; 36 import com.android.systemui.statusbar.phone.SystemUIDialog; 37 38 /** 39 * Manages notification when a guest session is resumed. 40 */ 41 public class GuestResumeSessionReceiver extends BroadcastReceiver { 42 43 private static final String TAG = "GuestResumeSessionReceiver"; 44 45 private static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in"; 46 47 private Dialog mNewSessionDialog; 48 49 /** 50 * Register this receiver with the {@link BroadcastDispatcher} 51 * 52 * @param broadcastDispatcher to register the receiver. 53 */ register(BroadcastDispatcher broadcastDispatcher)54 public void register(BroadcastDispatcher broadcastDispatcher) { 55 IntentFilter f = new IntentFilter(Intent.ACTION_USER_SWITCHED); 56 broadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM); 57 } 58 59 @Override onReceive(Context context, Intent intent)60 public void onReceive(Context context, Intent intent) { 61 String action = intent.getAction(); 62 63 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 64 cancelDialog(); 65 66 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 67 if (userId == UserHandle.USER_NULL) { 68 Log.e(TAG, intent + " sent to " + TAG + " without EXTRA_USER_HANDLE"); 69 return; 70 } 71 72 UserInfo currentUser; 73 try { 74 currentUser = ActivityManager.getService().getCurrentUser(); 75 } catch (RemoteException e) { 76 return; 77 } 78 if (!currentUser.isGuest()) { 79 return; 80 } 81 82 ContentResolver cr = context.getContentResolver(); 83 int notFirstLogin = Settings.System.getIntForUser( 84 cr, SETTING_GUEST_HAS_LOGGED_IN, 0, userId); 85 if (notFirstLogin != 0) { 86 mNewSessionDialog = new ResetSessionDialog(context, userId); 87 mNewSessionDialog.show(); 88 } else { 89 Settings.System.putIntForUser( 90 cr, SETTING_GUEST_HAS_LOGGED_IN, 1, userId); 91 } 92 } 93 } 94 95 /** 96 * Wipes the guest session. 97 * 98 * The guest must be the current user and its id must be {@param userId}. 99 */ wipeGuestSession(Context context, int userId)100 private static void wipeGuestSession(Context context, int userId) { 101 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 102 UserInfo currentUser; 103 try { 104 currentUser = ActivityManager.getService().getCurrentUser(); 105 } catch (RemoteException e) { 106 Log.e(TAG, "Couldn't wipe session because ActivityManager is dead"); 107 return; 108 } 109 if (currentUser.id != userId) { 110 Log.w(TAG, "User requesting to start a new session (" + userId + ")" 111 + " is not current user (" + currentUser.id + ")"); 112 return; 113 } 114 if (!currentUser.isGuest()) { 115 Log.w(TAG, "User requesting to start a new session (" + userId + ")" 116 + " is not a guest"); 117 return; 118 } 119 120 boolean marked = userManager.markGuestForDeletion(currentUser.id); 121 if (!marked) { 122 Log.w(TAG, "Couldn't mark the guest for deletion for user " + userId); 123 return; 124 } 125 UserInfo newGuest = userManager.createGuest(context, currentUser.name); 126 127 try { 128 if (newGuest == null) { 129 Log.e(TAG, "Could not create new guest, switching back to system user"); 130 ActivityManager.getService().switchUser(UserHandle.USER_SYSTEM); 131 userManager.removeUser(currentUser.id); 132 WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */); 133 return; 134 } 135 ActivityManager.getService().switchUser(newGuest.id); 136 userManager.removeUser(currentUser.id); 137 } catch (RemoteException e) { 138 Log.e(TAG, "Couldn't wipe session because ActivityManager or WindowManager is dead"); 139 return; 140 } 141 } 142 cancelDialog()143 private void cancelDialog() { 144 if (mNewSessionDialog != null && mNewSessionDialog.isShowing()) { 145 mNewSessionDialog.cancel(); 146 mNewSessionDialog = null; 147 } 148 } 149 150 private static class ResetSessionDialog extends SystemUIDialog implements 151 DialogInterface.OnClickListener { 152 153 private static final int BUTTON_WIPE = BUTTON_NEGATIVE; 154 private static final int BUTTON_DONTWIPE = BUTTON_POSITIVE; 155 156 private final int mUserId; 157 ResetSessionDialog(Context context, int userId)158 public ResetSessionDialog(Context context, int userId) { 159 super(context); 160 161 setTitle(context.getString(R.string.guest_wipe_session_title)); 162 setMessage(context.getString(R.string.guest_wipe_session_message)); 163 setCanceledOnTouchOutside(false); 164 165 setButton(BUTTON_WIPE, 166 context.getString(R.string.guest_wipe_session_wipe), this); 167 setButton(BUTTON_DONTWIPE, 168 context.getString(R.string.guest_wipe_session_dontwipe), this); 169 170 mUserId = userId; 171 } 172 173 @Override onClick(DialogInterface dialog, int which)174 public void onClick(DialogInterface dialog, int which) { 175 if (which == BUTTON_WIPE) { 176 wipeGuestSession(getContext(), mUserId); 177 dismiss(); 178 } else if (which == BUTTON_DONTWIPE) { 179 cancel(); 180 } 181 } 182 } 183 } 184