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