blob: 4b2a55fff57a3a5907c35f2852bc026f7cd90f3a [file] [log] [blame]
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001/*
2 * Copyright (C) 2015 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
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.app.ActivityManager.USER_OP_IS_CURRENT;
22import static android.app.ActivityManager.USER_OP_SUCCESS;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070023import static android.os.Process.SYSTEM_UID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070024import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
25import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
26import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070027import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
28import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
29import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
30import static com.android.server.am.ActivityManagerService.MY_PID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070031import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
32import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
33import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
34import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
35import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
36
37import android.app.ActivityManager;
38import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070039import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070040import android.app.IStopUserCallback;
41import android.app.IUserSwitchObserver;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070042import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070043import android.content.IIntentReceiver;
44import android.content.Intent;
45import android.content.pm.PackageManager;
46import android.content.pm.UserInfo;
47import android.os.BatteryStats;
48import android.os.Binder;
49import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070050import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070051import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070052import android.os.IBinder;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070053import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070054import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.os.Process;
56import android.os.RemoteCallbackList;
57import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070058import android.os.ServiceManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080059import android.os.SystemProperties;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070060import android.os.UserHandle;
61import android.os.UserManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080062import android.os.storage.IMountService;
63import android.os.storage.StorageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070064import android.util.Slog;
65import android.util.SparseArray;
66import android.util.SparseIntArray;
67
68import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080069import com.android.internal.annotations.GuardedBy;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070070import com.android.internal.util.ArrayUtils;
71import com.android.server.pm.UserManagerService;
72
73import java.io.PrintWriter;
74import java.util.ArrayList;
75import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070076import java.util.HashSet;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070077import java.util.List;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070078import java.util.Set;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070079
80/**
81 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
82 */
83final class UserController {
84 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
85 // Maximum number of users we allow to be running at a time.
86 static final int MAX_RUNNING_USERS = 3;
87
88 // Amount of time we wait for observers to handle a user switch before
89 // giving up on them and unfreezing the screen.
90 static final int USER_SWITCH_TIMEOUT = 2 * 1000;
91
92 private final ActivityManagerService mService;
93 private final Handler mHandler;
94
95 // Holds the current foreground user's id
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070096 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070097 // Holds the target user's id during a user switch
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070098 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070099
100 /**
101 * Which users have been started, so are allowed to run code.
102 */
Jeff Sharkeyba512352015-11-12 20:17:45 -0800103 @GuardedBy("mService")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700104 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800105
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700106 /**
107 * LRU list of history of current users. Most recently current is at the end.
108 */
109 private final ArrayList<Integer> mUserLru = new ArrayList<>();
110
111 /**
112 * Constant array of the users that are currently started.
113 */
114 private int[] mStartedUserArray = new int[] { 0 };
115
116 // If there are multiple profiles for the current user, their ids are here
117 // Currently only the primary user can have managed profiles
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700118 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700119
120 /**
121 * Mapping from each known user ID to the profile group ID it is associated with.
122 */
123 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
124
125 /**
126 * Registered observers of the user switching mechanics.
127 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700128 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700129 = new RemoteCallbackList<>();
130
131 /**
132 * Currently active user switch.
133 */
134 Object mCurUserSwitchCallback;
135
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700136 private volatile UserManagerService mUserManager;
137
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700138 UserController(ActivityManagerService service) {
139 mService = service;
140 mHandler = mService.mHandler;
141 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800142 final UserState uss = new UserState(UserHandle.SYSTEM);
143 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
144 updateUserUnlockedState(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700145 mUserLru.add(UserHandle.USER_SYSTEM);
146 updateStartedUserArrayLocked();
147 }
148
149 void finishUserSwitch(UserState uss) {
150 synchronized (mService) {
151 finishUserBoot(uss);
152
153 startProfilesLocked();
154
155 int num = mUserLru.size();
156 int i = 0;
157 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
158 Integer oldUserId = mUserLru.get(i);
159 UserState oldUss = mStartedUsers.get(oldUserId);
160 if (oldUss == null) {
161 // Shouldn't happen, but be sane if it does.
162 mUserLru.remove(i);
163 num--;
164 continue;
165 }
166 if (oldUss.mState == UserState.STATE_STOPPING
167 || oldUss.mState == UserState.STATE_SHUTDOWN) {
168 // This user is already stopping, doesn't count.
169 num--;
170 i++;
171 continue;
172 }
173 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
174 // Owner/System user and current user can't be stopped. We count it as running
175 // when it is not a pure system user.
176 if (UserInfo.isSystemOnly(oldUserId)) {
177 num--;
178 }
179 i++;
180 continue;
181 }
182 // This is a user to be stopped.
183 stopUserLocked(oldUserId, null);
184 num--;
185 i++;
186 }
187 }
188 }
189
190 void finishUserBoot(UserState uss) {
191 synchronized (mService) {
192 if (uss.mState == UserState.STATE_BOOTING
193 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
194 uss.mState = UserState.STATE_RUNNING;
195 final int userId = uss.mHandle.getIdentifier();
196 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
197 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
198 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
199 mService.broadcastIntentLocked(null, null, intent,
200 null, null, 0, null, null,
201 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700202 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700203 }
204 }
205 }
206
207 int stopUser(final int userId, final IStopUserCallback callback) {
208 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
209 != PackageManager.PERMISSION_GRANTED) {
210 String msg = "Permission Denial: switchUser() from pid="
211 + Binder.getCallingPid()
212 + ", uid=" + Binder.getCallingUid()
213 + " requires " + INTERACT_ACROSS_USERS_FULL;
214 Slog.w(TAG, msg);
215 throw new SecurityException(msg);
216 }
217 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
218 throw new IllegalArgumentException("Can't stop system user " + userId);
219 }
220 mService.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
221 userId);
222 synchronized (mService) {
223 return stopUserLocked(userId, callback);
224 }
225 }
226
227 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
228 if (DEBUG_MU) Slog.i(TAG, "stopUserLocked userId=" + userId);
229 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
230 return USER_OP_IS_CURRENT;
231 }
232
233 final UserState uss = mStartedUsers.get(userId);
234 if (uss == null) {
235 // User is not started, nothing to do... but we do need to
236 // callback if requested.
237 if (callback != null) {
238 mHandler.post(new Runnable() {
239 @Override
240 public void run() {
241 try {
242 callback.userStopped(userId);
243 } catch (RemoteException e) {
244 }
245 }
246 });
247 }
248 return USER_OP_SUCCESS;
249 }
250
251 if (callback != null) {
252 uss.mStopCallbacks.add(callback);
253 }
254
255 if (uss.mState != UserState.STATE_STOPPING
256 && uss.mState != UserState.STATE_SHUTDOWN) {
257 uss.mState = UserState.STATE_STOPPING;
258 updateStartedUserArrayLocked();
259
260 long ident = Binder.clearCallingIdentity();
261 try {
262 // We are going to broadcast ACTION_USER_STOPPING and then
263 // once that is done send a final ACTION_SHUTDOWN and then
264 // stop the user.
265 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
266 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
267 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
268 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
269 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
270 // This is the result receiver for the final shutdown broadcast.
271 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
272 @Override
273 public void performReceive(Intent intent, int resultCode, String data,
274 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
275 finishUserStop(uss);
276 }
277 };
278 // This is the result receiver for the initial stopping broadcast.
279 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
280 @Override
281 public void performReceive(Intent intent, int resultCode, String data,
282 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
283 // On to the next.
284 synchronized (mService) {
285 if (uss.mState != UserState.STATE_STOPPING) {
286 // Whoops, we are being started back up. Abort, abort!
287 return;
288 }
289 uss.mState = UserState.STATE_SHUTDOWN;
290 }
291 mService.mBatteryStatsService.noteEvent(
292 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
293 Integer.toString(userId), userId);
294 mService.mSystemServiceManager.stopUser(userId);
295 mService.broadcastIntentLocked(null, null, shutdownIntent,
296 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700297 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700298 }
299 };
300 // Kick things off.
301 mService.broadcastIntentLocked(null, null, stoppingIntent,
302 null, stoppingReceiver, 0, null, null,
303 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700304 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700305 } finally {
306 Binder.restoreCallingIdentity(ident);
307 }
308 }
309
310 return USER_OP_SUCCESS;
311 }
312
313 void finishUserStop(UserState uss) {
314 final int userId = uss.mHandle.getIdentifier();
315 boolean stopped;
316 ArrayList<IStopUserCallback> callbacks;
317 synchronized (mService) {
318 callbacks = new ArrayList<>(uss.mStopCallbacks);
319 if (mStartedUsers.get(userId) != uss) {
320 stopped = false;
321 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
322 stopped = false;
323 } else {
324 stopped = true;
325 // User can no longer run.
326 mStartedUsers.remove(userId);
327 mUserLru.remove(Integer.valueOf(userId));
328 updateStartedUserArrayLocked();
329
330 // Clean up all state and processes associated with the user.
331 // Kill all the processes for the user.
332 forceStopUserLocked(userId, "finish user");
333 }
334 }
335
336 for (int i = 0; i < callbacks.size(); i++) {
337 try {
338 if (stopped) callbacks.get(i).userStopped(userId);
339 else callbacks.get(i).userStopAborted(userId);
340 } catch (RemoteException e) {
341 }
342 }
343
344 if (stopped) {
345 mService.mSystemServiceManager.cleanupUser(userId);
346 synchronized (mService) {
347 mService.mStackSupervisor.removeUserLocked(userId);
348 }
349 }
350 }
351
352 private void forceStopUserLocked(int userId, String reason) {
353 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
354 userId, reason);
355 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
356 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
357 | Intent.FLAG_RECEIVER_FOREGROUND);
358 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
359 mService.broadcastIntentLocked(null, null, intent,
360 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700361 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700362 }
363
364
365 /**
366 * Stops the guest user if it has gone to the background.
367 */
368 private void stopGuestUserIfBackground() {
369 synchronized (mService) {
370 final int num = mUserLru.size();
371 for (int i = 0; i < num; i++) {
372 Integer oldUserId = mUserLru.get(i);
373 UserState oldUss = mStartedUsers.get(oldUserId);
374 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
375 || oldUss.mState == UserState.STATE_STOPPING
376 || oldUss.mState == UserState.STATE_SHUTDOWN) {
377 continue;
378 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700379 UserInfo userInfo = getUserInfo(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700380 if (userInfo.isGuest()) {
381 // This is a user to be stopped.
382 stopUserLocked(oldUserId, null);
383 break;
384 }
385 }
386 }
387 }
388
389 void startProfilesLocked() {
390 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700391 List<UserInfo> profiles = getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700392 mCurrentUserId, false /* enabledOnly */);
393 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
394 for (UserInfo user : profiles) {
395 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
396 && user.id != mCurrentUserId) {
397 profilesToStart.add(user);
398 }
399 }
400 final int profilesToStartSize = profilesToStart.size();
401 int i = 0;
402 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
403 startUser(profilesToStart.get(i).id, /* foreground= */ false);
404 }
405 if (i < profilesToStartSize) {
406 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
407 }
408 }
409
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700410 private UserManagerService getUserManager() {
411 UserManagerService userManager = mUserManager;
412 if (userManager == null) {
413 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
414 userManager = mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
415 }
416 return userManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700417 }
418
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800419 private void updateUserUnlockedState(UserState uss) {
420 final IMountService mountService = IMountService.Stub
Jeff Sharkeyba512352015-11-12 20:17:45 -0800421 .asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800422 if (mountService != null) {
423 try {
424 uss.unlocked = mountService.isUserKeyUnlocked(uss.mHandle.getIdentifier());
425 } catch (RemoteException e) {
426 throw e.rethrowAsRuntimeException();
427 }
428 } else {
429 // System isn't fully booted yet, so guess based on property
Jeff Sharkeyba512352015-11-12 20:17:45 -0800430 uss.unlocked = !StorageManager.isFileBasedEncryptionEnabled();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800431 }
432 }
433
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700434 boolean startUser(final int userId, final boolean foreground) {
435 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
436 != PackageManager.PERMISSION_GRANTED) {
437 String msg = "Permission Denial: switchUser() from pid="
438 + Binder.getCallingPid()
439 + ", uid=" + Binder.getCallingUid()
440 + " requires " + INTERACT_ACROSS_USERS_FULL;
441 Slog.w(TAG, msg);
442 throw new SecurityException(msg);
443 }
444
445 if (DEBUG_MU) Slog.i(TAG, "starting userid:" + userId + " fore:" + foreground);
446
447 final long ident = Binder.clearCallingIdentity();
448 try {
449 synchronized (mService) {
450 final int oldUserId = mCurrentUserId;
451 if (oldUserId == userId) {
452 return true;
453 }
454
455 mService.mStackSupervisor.setLockTaskModeLocked(null,
456 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
457
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700458 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700459 if (userInfo == null) {
460 Slog.w(TAG, "No user info for user #" + userId);
461 return false;
462 }
463 if (foreground && userInfo.isManagedProfile()) {
464 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
465 return false;
466 }
467
468 if (foreground) {
469 mService.mWindowManager.startFreezingScreen(
470 R.anim.screen_user_exit, R.anim.screen_user_enter);
471 }
472
473 boolean needStart = false;
474
475 // If the user we are switching to is not currently started, then
476 // we need to start it now.
477 if (mStartedUsers.get(userId) == null) {
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800478 mStartedUsers.put(userId, new UserState(new UserHandle(userId)));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700479 updateStartedUserArrayLocked();
480 needStart = true;
481 }
482
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800483 final UserState uss = mStartedUsers.get(userId);
484 updateUserUnlockedState(uss);
485
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700486 final Integer userIdInt = userId;
487 mUserLru.remove(userIdInt);
488 mUserLru.add(userIdInt);
489
490 if (foreground) {
491 mCurrentUserId = userId;
492 mService.updateUserConfigurationLocked();
493 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
494 updateCurrentProfileIdsLocked();
495 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
496 // Once the internal notion of the active user has switched, we lock the device
497 // with the option to show the user switcher on the keyguard.
498 mService.mWindowManager.lockNow(null);
499 } else {
500 final Integer currentUserIdInt = mCurrentUserId;
501 updateCurrentProfileIdsLocked();
502 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
503 mUserLru.remove(currentUserIdInt);
504 mUserLru.add(currentUserIdInt);
505 }
506
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700507 // Make sure user is in the started state. If it is currently
508 // stopping, we need to knock that off.
509 if (uss.mState == UserState.STATE_STOPPING) {
510 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
511 // so we can just fairly silently bring the user back from
512 // the almost-dead.
513 uss.mState = UserState.STATE_RUNNING;
514 updateStartedUserArrayLocked();
515 needStart = true;
516 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
517 // This means ACTION_SHUTDOWN has been sent, so we will
518 // need to treat this as a new boot of the user.
519 uss.mState = UserState.STATE_BOOTING;
520 updateStartedUserArrayLocked();
521 needStart = true;
522 }
523
524 if (uss.mState == UserState.STATE_BOOTING) {
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800525 // Let user manager propagate user restrictions to other services.
526 getUserManager().onBeforeStartUser(userId);
527
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700528 // Booting up a new user, need to tell system services about it.
529 // Note that this is on the same handler as scheduling of broadcasts,
530 // which is important because it needs to go first.
531 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
532 }
533
534 if (foreground) {
535 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
536 oldUserId));
537 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
538 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
539 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
540 oldUserId, userId, uss));
541 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
542 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
543 }
544
545 if (needStart) {
546 // Send USER_STARTED broadcast
547 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
548 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
549 | Intent.FLAG_RECEIVER_FOREGROUND);
550 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
551 mService.broadcastIntentLocked(null, null, intent,
552 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700553 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700554 }
555
556 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
557 if (userId != UserHandle.USER_SYSTEM) {
558 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
559 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
560 mService.broadcastIntentLocked(null, null, intent, null,
561 new IIntentReceiver.Stub() {
562 public void performReceive(Intent intent, int resultCode,
563 String data, Bundle extras, boolean ordered,
564 boolean sticky, int sendingUser) {
565 onUserInitialized(uss, foreground, oldUserId, userId);
566 }
567 }, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700568 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700569 uss.initializing = true;
570 } else {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700571 getUserManager().makeInitialized(userInfo.id);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700572 }
573 }
574
575 if (foreground) {
576 if (!uss.initializing) {
577 moveUserToForegroundLocked(uss, oldUserId, userId);
578 }
579 } else {
580 mService.mStackSupervisor.startBackgroundUserLocked(userId, uss);
581 }
582
583 if (needStart) {
584 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
585 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
586 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
587 mService.broadcastIntentLocked(null, null, intent,
588 null, new IIntentReceiver.Stub() {
589 @Override
590 public void performReceive(Intent intent, int resultCode,
591 String data, Bundle extras, boolean ordered, boolean sticky,
592 int sendingUser) throws RemoteException {
593 }
594 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700595 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
596 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700597 }
598 }
599 } finally {
600 Binder.restoreCallingIdentity(ident);
601 }
602
603 return true;
604 }
605
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700606 /**
607 * Start user, if its not already running, and bring it to foreground.
608 */
609 boolean startUserInForeground(final int userId, Dialog dlg) {
610 boolean result = startUser(userId, /* foreground */ true);
611 dlg.dismiss();
612 return result;
613 }
614
Jeff Sharkeyba512352015-11-12 20:17:45 -0800615 boolean unlockUser(final int userId, byte[] token) {
616 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
617 != PackageManager.PERMISSION_GRANTED) {
618 String msg = "Permission Denial: unlockUser() from pid="
619 + Binder.getCallingPid()
620 + ", uid=" + Binder.getCallingUid()
621 + " requires " + INTERACT_ACROSS_USERS_FULL;
622 Slog.w(TAG, msg);
623 throw new SecurityException(msg);
624 }
625
626 final UserInfo userInfo = getUserInfo(userId);
627 final IMountService mountService = IMountService.Stub
628 .asInterface(ServiceManager.getService("mount"));
629 try {
630 mountService.unlockUserKey(userId, userInfo.serialNumber, token);
631 } catch (RemoteException e) {
632 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
633 throw e.rethrowAsRuntimeException();
634 }
635
636 synchronized (mService) {
637 final UserState uss = mStartedUsers.get(userId);
638 updateUserUnlockedState(uss);
639 }
640
641 return true;
642 }
643
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700644 void showUserSwitchDialog(int userId, String userName) {
645 // The dialog will show and then initiate the user switch by calling startUserInForeground
646 Dialog d = new UserSwitchingDialog(mService, mService.mContext, userId, userName,
647 true /* above system */);
648 d.show();
649 }
650
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700651 void dispatchForegroundProfileChanged(int userId) {
652 final int observerCount = mUserSwitchObservers.beginBroadcast();
653 for (int i = 0; i < observerCount; i++) {
654 try {
655 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
656 } catch (RemoteException e) {
657 // Ignore
658 }
659 }
660 mUserSwitchObservers.finishBroadcast();
661 }
662
663 /** Called on handler thread */
664 void dispatchUserSwitchComplete(int userId) {
665 final int observerCount = mUserSwitchObservers.beginBroadcast();
666 for (int i = 0; i < observerCount; i++) {
667 try {
668 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
669 } catch (RemoteException e) {
670 }
671 }
672 mUserSwitchObservers.finishBroadcast();
673 }
674
675 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
676 synchronized (mService) {
Amith Yamasanica0ac5c2015-11-20 09:44:08 -0800677 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700678 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
679 }
680 }
681
682 void dispatchUserSwitch(final UserState uss, final int oldUserId,
683 final int newUserId) {
684 final int observerCount = mUserSwitchObservers.beginBroadcast();
685 if (observerCount > 0) {
686 final IRemoteCallback callback = new IRemoteCallback.Stub() {
687 int mCount = 0;
688 @Override
689 public void sendResult(Bundle data) throws RemoteException {
690 synchronized (mService) {
691 if (mCurUserSwitchCallback == this) {
692 mCount++;
693 if (mCount == observerCount) {
694 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
695 }
696 }
697 }
698 }
699 };
700 synchronized (mService) {
701 uss.switching = true;
702 mCurUserSwitchCallback = callback;
703 }
704 for (int i = 0; i < observerCount; i++) {
705 try {
706 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
707 newUserId, callback);
708 } catch (RemoteException e) {
709 }
710 }
711 } else {
712 synchronized (mService) {
713 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
714 }
715 }
716 mUserSwitchObservers.finishBroadcast();
717 }
718
719 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
720 mCurUserSwitchCallback = null;
721 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
722 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
723 oldUserId, newUserId, uss));
724 }
725
726 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
727 completeSwitchAndInitialize(uss, newUserId, false, true);
728 }
729
730 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
731 synchronized (mService) {
732 if (foreground) {
733 moveUserToForegroundLocked(uss, oldUserId, newUserId);
734 }
735 }
736 completeSwitchAndInitialize(uss, newUserId, true, false);
737 }
738
739 void completeSwitchAndInitialize(UserState uss, int newUserId,
740 boolean clearInitializing, boolean clearSwitching) {
741 boolean unfrozen = false;
742 synchronized (mService) {
743 if (clearInitializing) {
744 uss.initializing = false;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700745 getUserManager().makeInitialized(uss.mHandle.getIdentifier());
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700746 }
747 if (clearSwitching) {
748 uss.switching = false;
749 }
750 if (!uss.switching && !uss.initializing) {
751 mService.mWindowManager.stopFreezingScreen();
752 unfrozen = true;
753 }
754 }
755 if (unfrozen) {
756 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
757 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
758 newUserId, 0));
759 }
760 stopGuestUserIfBackground();
761 }
762
763 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
764 boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
765 if (homeInFront) {
766 mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
767 } else {
768 mService.mStackSupervisor.resumeTopActivitiesLocked();
769 }
770 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700771 getUserManager().onUserForeground(newUserId);
772 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
773 }
774
775 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
776 long ident = Binder.clearCallingIdentity();
777 try {
778 Intent intent;
779 if (oldUserId >= 0) {
780 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
781 List<UserInfo> profiles = getUserManager().getProfiles(oldUserId, false);
782 int count = profiles.size();
783 for (int i = 0; i < count; i++) {
784 int profileUserId = profiles.get(i).id;
785 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
786 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
787 | Intent.FLAG_RECEIVER_FOREGROUND);
788 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
789 mService.broadcastIntentLocked(null, null, intent,
790 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
791 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
792 }
793 }
794 if (newUserId >= 0) {
795 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
796 List<UserInfo> profiles = getUserManager().getProfiles(newUserId, false);
797 int count = profiles.size();
798 for (int i = 0; i < count; i++) {
799 int profileUserId = profiles.get(i).id;
800 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
801 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
802 | Intent.FLAG_RECEIVER_FOREGROUND);
803 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
804 mService.broadcastIntentLocked(null, null, intent,
805 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
806 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
807 }
808 intent = new Intent(Intent.ACTION_USER_SWITCHED);
809 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
810 | Intent.FLAG_RECEIVER_FOREGROUND);
811 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
812 mService.broadcastIntentLocked(null, null, intent,
813 null, null, 0, null, null,
814 new String[] {android.Manifest.permission.MANAGE_USERS},
815 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
816 UserHandle.USER_ALL);
817 }
818 } finally {
819 Binder.restoreCallingIdentity(ident);
820 }
821 }
822
823
824 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
825 int allowMode, String name, String callerPackage) {
826 final int callingUserId = UserHandle.getUserId(callingUid);
827 if (callingUserId == userId) {
828 return userId;
829 }
830
831 // Note that we may be accessing mCurrentUserId outside of a lock...
832 // shouldn't be a big deal, if this is being called outside
833 // of a locked context there is intrinsically a race with
834 // the value the caller will receive and someone else changing it.
835 // We assume that USER_CURRENT_OR_SELF will use the current user; later
836 // we will switch to the calling user if access to the current user fails.
837 int targetUserId = unsafeConvertIncomingUserLocked(userId);
838
839 if (callingUid != 0 && callingUid != SYSTEM_UID) {
840 final boolean allow;
841 if (mService.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
842 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
843 // If the caller has this permission, they always pass go. And collect $200.
844 allow = true;
845 } else if (allowMode == ALLOW_FULL_ONLY) {
846 // We require full access, sucks to be you.
847 allow = false;
848 } else if (mService.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
849 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
850 // If the caller does not have either permission, they are always doomed.
851 allow = false;
852 } else if (allowMode == ALLOW_NON_FULL) {
853 // We are blanket allowing non-full access, you lucky caller!
854 allow = true;
855 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
856 // We may or may not allow this depending on whether the two users are
857 // in the same profile.
858 allow = isSameProfileGroup(callingUserId, targetUserId);
859 } else {
860 throw new IllegalArgumentException("Unknown mode: " + allowMode);
861 }
862 if (!allow) {
863 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
864 // In this case, they would like to just execute as their
865 // owner user instead of failing.
866 targetUserId = callingUserId;
867 } else {
868 StringBuilder builder = new StringBuilder(128);
869 builder.append("Permission Denial: ");
870 builder.append(name);
871 if (callerPackage != null) {
872 builder.append(" from ");
873 builder.append(callerPackage);
874 }
875 builder.append(" asks to run as user ");
876 builder.append(userId);
877 builder.append(" but is calling from user ");
878 builder.append(UserHandle.getUserId(callingUid));
879 builder.append("; this requires ");
880 builder.append(INTERACT_ACROSS_USERS_FULL);
881 if (allowMode != ALLOW_FULL_ONLY) {
882 builder.append(" or ");
883 builder.append(INTERACT_ACROSS_USERS);
884 }
885 String msg = builder.toString();
886 Slog.w(TAG, msg);
887 throw new SecurityException(msg);
888 }
889 }
890 }
891 if (!allowAll && targetUserId < 0) {
892 throw new IllegalArgumentException(
893 "Call does not support special user #" + targetUserId);
894 }
895 // Check shell permission
896 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
897 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
898 throw new SecurityException("Shell does not have permission to access user "
899 + targetUserId + "\n " + Debug.getCallers(3));
900 }
901 }
902 return targetUserId;
903 }
904
905 int unsafeConvertIncomingUserLocked(int userId) {
906 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
907 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700908 }
909
910 void registerUserSwitchObserver(IUserSwitchObserver observer) {
911 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
912 != PackageManager.PERMISSION_GRANTED) {
913 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
914 + Binder.getCallingPid()
915 + ", uid=" + Binder.getCallingUid()
916 + " requires " + INTERACT_ACROSS_USERS_FULL;
917 Slog.w(TAG, msg);
918 throw new SecurityException(msg);
919 }
920
921 mUserSwitchObservers.register(observer);
922 }
923
924 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
925 mUserSwitchObservers.unregister(observer);
926 }
927
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700928 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700929 return mStartedUsers.get(userId);
930 }
931
932 boolean hasStartedUserState(int userId) {
933 return mStartedUsers.get(userId) != null;
934 }
935
936 private void updateStartedUserArrayLocked() {
937 int num = 0;
938 for (int i = 0; i < mStartedUsers.size(); i++) {
939 UserState uss = mStartedUsers.valueAt(i);
940 // This list does not include stopping users.
941 if (uss.mState != UserState.STATE_STOPPING
942 && uss.mState != UserState.STATE_SHUTDOWN) {
943 num++;
944 }
945 }
946 mStartedUserArray = new int[num];
947 num = 0;
948 for (int i = 0; i < mStartedUsers.size(); i++) {
949 UserState uss = mStartedUsers.valueAt(i);
950 if (uss.mState != UserState.STATE_STOPPING
951 && uss.mState != UserState.STATE_SHUTDOWN) {
952 mStartedUserArray[num] = mStartedUsers.keyAt(i);
953 num++;
954 }
955 }
956 }
957
958 void sendBootCompletedLocked(IIntentReceiver resultTo) {
959 for (int i = 0; i < mStartedUsers.size(); i++) {
960 UserState uss = mStartedUsers.valueAt(i);
961 if (uss.mState == UserState.STATE_BOOTING) {
962 uss.mState = UserState.STATE_RUNNING;
963 final int userId = mStartedUsers.keyAt(i);
964 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
965 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
966 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
967 mService.broadcastIntentLocked(null, null, intent, null,
968 resultTo, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700969 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
970 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700971 }
972 }
973 }
974
975 /**
976 * Refreshes the list of users related to the current user when either a
977 * user switch happens or when a new related user is started in the
978 * background.
979 */
980 void updateCurrentProfileIdsLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700981 final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700982 false /* enabledOnly */);
983 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
984 for (int i = 0; i < currentProfileIds.length; i++) {
985 currentProfileIds[i] = profiles.get(i).id;
986 }
987 mCurrentProfileIds = currentProfileIds;
988
989 synchronized (mUserProfileGroupIdsSelfLocked) {
990 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700991 final List<UserInfo> users = getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700992 for (int i = 0; i < users.size(); i++) {
993 UserInfo user = users.get(i);
994 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
995 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
996 }
997 }
998 }
999 }
1000
1001 int[] getStartedUserArrayLocked() {
1002 return mStartedUserArray;
1003 }
1004
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001005 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001006 UserState state = getStartedUserStateLocked(userId);
1007 if (state == null) {
1008 return false;
1009 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001010 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001011 return true;
1012 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001013 if ((flags & ActivityManager.FLAG_WITH_AMNESIA) != 0) {
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -08001014 // If user is currently locked, we fall through to default "running"
1015 // behavior below
1016 if (state.unlocked) {
1017 return false;
1018 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001019 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001020 return state.mState != UserState.STATE_STOPPING
1021 && state.mState != UserState.STATE_SHUTDOWN;
1022 }
1023
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001024 UserInfo getCurrentUser() {
1025 if ((mService.checkCallingPermission(INTERACT_ACROSS_USERS)
1026 != PackageManager.PERMISSION_GRANTED) && (
1027 mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1028 != PackageManager.PERMISSION_GRANTED)) {
1029 String msg = "Permission Denial: getCurrentUser() from pid="
1030 + Binder.getCallingPid()
1031 + ", uid=" + Binder.getCallingUid()
1032 + " requires " + INTERACT_ACROSS_USERS;
1033 Slog.w(TAG, msg);
1034 throw new SecurityException(msg);
1035 }
1036 synchronized (mService) {
1037 return getCurrentUserLocked();
1038 }
1039 }
1040
1041 UserInfo getCurrentUserLocked() {
1042 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001043 return getUserInfo(userId);
1044 }
1045
1046 int getCurrentOrTargetUserIdLocked() {
1047 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001048 }
1049
1050 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001051 return mCurrentUserId;
1052 }
1053
1054 int setTargetUserIdLocked(int targetUserId) {
1055 return mTargetUserId = targetUserId;
1056 }
1057
1058 int[] getUsers() {
1059 UserManagerService ums = getUserManager();
1060 return ums != null ? ums.getUserIds() : new int[] { 0 };
1061 }
1062
1063 UserInfo getUserInfo(int userId) {
1064 return getUserManager().getUserInfo(userId);
1065 }
1066
1067 int[] getUserIds() {
1068 return getUserManager().getUserIds();
1069 }
1070
1071 boolean exists(int userId) {
1072 return getUserManager().exists(userId);
1073 }
1074
1075 boolean hasUserRestriction(String restriction, int userId) {
1076 return getUserManager().hasUserRestriction(restriction, userId);
1077 }
1078
1079 Set<Integer> getProfileIds(int userId) {
1080 Set<Integer> userIds = new HashSet<>();
1081 final List<UserInfo> profiles = getUserManager().getProfiles(userId,
1082 false /* enabledOnly */);
1083 for (UserInfo user : profiles) {
1084 userIds.add(user.id);
1085 }
1086 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001087 }
1088
1089 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
1090 synchronized (mUserProfileGroupIdsSelfLocked) {
1091 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1092 UserInfo.NO_PROFILE_GROUP_ID);
1093 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1094 UserInfo.NO_PROFILE_GROUP_ID);
1095 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1096 && callingProfile == targetProfile;
1097 }
1098 }
1099
1100 boolean isCurrentProfileLocked(int userId) {
1101 return ArrayUtils.contains(mCurrentProfileIds, userId);
1102 }
1103
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001104 int[] getCurrentProfileIdsLocked() {
1105 return mCurrentProfileIds;
1106 }
1107
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001108 void dump(PrintWriter pw, boolean dumpAll) {
1109 pw.println(" mStartedUsers:");
1110 for (int i = 0; i < mStartedUsers.size(); i++) {
1111 UserState uss = mStartedUsers.valueAt(i);
1112 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1113 pw.print(": "); uss.dump("", pw);
1114 }
1115 pw.print(" mStartedUserArray: [");
1116 for (int i = 0; i < mStartedUserArray.length; i++) {
1117 if (i > 0) pw.print(", ");
1118 pw.print(mStartedUserArray[i]);
1119 }
1120 pw.println("]");
1121 pw.print(" mUserLru: [");
1122 for (int i = 0; i < mUserLru.size(); i++) {
1123 if (i > 0) pw.print(", ");
1124 pw.print(mUserLru.get(i));
1125 }
1126 pw.println("]");
1127 if (dumpAll) {
1128 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1129 }
1130 synchronized (mUserProfileGroupIdsSelfLocked) {
1131 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1132 pw.println(" mUserProfileGroupIds:");
1133 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1134 pw.print(" User #");
1135 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1136 pw.print(" -> profile #");
1137 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1138 }
1139 }
1140 }
1141 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001142}