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