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