blob: ff74d836e1ba858376d7391b9c758c700021940a [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;
23import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
24import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
25import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
26import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
27import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
28import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
29import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
30import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
31
32import android.app.ActivityManager;
33import android.app.AppOpsManager;
34import android.app.IStopUserCallback;
35import android.app.IUserSwitchObserver;
36import android.content.IIntentReceiver;
37import android.content.Intent;
38import android.content.pm.PackageManager;
39import android.content.pm.UserInfo;
40import android.os.BatteryStats;
41import android.os.Binder;
42import android.os.Bundle;
43import android.os.Handler;
44import android.os.IRemoteCallback;
45import android.os.Process;
46import android.os.RemoteCallbackList;
47import android.os.RemoteException;
48import android.os.UserHandle;
49import android.os.UserManager;
50import android.util.Slog;
51import android.util.SparseArray;
52import android.util.SparseIntArray;
53
54import com.android.internal.R;
55import com.android.internal.util.ArrayUtils;
56import com.android.server.pm.UserManagerService;
57
58import java.io.PrintWriter;
59import java.util.ArrayList;
60import java.util.Arrays;
61import java.util.List;
62
63/**
64 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
65 */
66final class UserController {
67 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
68 // Maximum number of users we allow to be running at a time.
69 static final int MAX_RUNNING_USERS = 3;
70
71 // Amount of time we wait for observers to handle a user switch before
72 // giving up on them and unfreezing the screen.
73 static final int USER_SWITCH_TIMEOUT = 2 * 1000;
74
75 private final ActivityManagerService mService;
76 private final Handler mHandler;
77
78 // Holds the current foreground user's id
79 int mCurrentUserId = 0;
80 // Holds the target user's id during a user switch
81 int mTargetUserId = UserHandle.USER_NULL;
82
83 /**
84 * Which users have been started, so are allowed to run code.
85 */
86 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
87 /**
88 * LRU list of history of current users. Most recently current is at the end.
89 */
90 private final ArrayList<Integer> mUserLru = new ArrayList<>();
91
92 /**
93 * Constant array of the users that are currently started.
94 */
95 private int[] mStartedUserArray = new int[] { 0 };
96
97 // If there are multiple profiles for the current user, their ids are here
98 // Currently only the primary user can have managed profiles
99 int[] mCurrentProfileIds = new int[] {}; // Accessed by ActivityStack
100
101 /**
102 * Mapping from each known user ID to the profile group ID it is associated with.
103 */
104 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
105
106 /**
107 * Registered observers of the user switching mechanics.
108 */
109 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
110 = new RemoteCallbackList<>();
111
112 /**
113 * Currently active user switch.
114 */
115 Object mCurUserSwitchCallback;
116
117 UserController(ActivityManagerService service) {
118 mService = service;
119 mHandler = mService.mHandler;
120 // User 0 is the first and only user that runs at boot.
121 mStartedUsers.put(UserHandle.USER_SYSTEM, new UserState(UserHandle.SYSTEM, true));
122 mUserLru.add(UserHandle.USER_SYSTEM);
123 updateStartedUserArrayLocked();
124 }
125
126 void finishUserSwitch(UserState uss) {
127 synchronized (mService) {
128 finishUserBoot(uss);
129
130 startProfilesLocked();
131
132 int num = mUserLru.size();
133 int i = 0;
134 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
135 Integer oldUserId = mUserLru.get(i);
136 UserState oldUss = mStartedUsers.get(oldUserId);
137 if (oldUss == null) {
138 // Shouldn't happen, but be sane if it does.
139 mUserLru.remove(i);
140 num--;
141 continue;
142 }
143 if (oldUss.mState == UserState.STATE_STOPPING
144 || oldUss.mState == UserState.STATE_SHUTDOWN) {
145 // This user is already stopping, doesn't count.
146 num--;
147 i++;
148 continue;
149 }
150 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
151 // Owner/System user and current user can't be stopped. We count it as running
152 // when it is not a pure system user.
153 if (UserInfo.isSystemOnly(oldUserId)) {
154 num--;
155 }
156 i++;
157 continue;
158 }
159 // This is a user to be stopped.
160 stopUserLocked(oldUserId, null);
161 num--;
162 i++;
163 }
164 }
165 }
166
167 void finishUserBoot(UserState uss) {
168 synchronized (mService) {
169 if (uss.mState == UserState.STATE_BOOTING
170 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
171 uss.mState = UserState.STATE_RUNNING;
172 final int userId = uss.mHandle.getIdentifier();
173 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
174 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
175 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
176 mService.broadcastIntentLocked(null, null, intent,
177 null, null, 0, null, null,
178 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
179 AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
180 Process.SYSTEM_UID, userId);
181 }
182 }
183 }
184
185 int stopUser(final int userId, final IStopUserCallback callback) {
186 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
187 != PackageManager.PERMISSION_GRANTED) {
188 String msg = "Permission Denial: switchUser() from pid="
189 + Binder.getCallingPid()
190 + ", uid=" + Binder.getCallingUid()
191 + " requires " + INTERACT_ACROSS_USERS_FULL;
192 Slog.w(TAG, msg);
193 throw new SecurityException(msg);
194 }
195 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
196 throw new IllegalArgumentException("Can't stop system user " + userId);
197 }
198 mService.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
199 userId);
200 synchronized (mService) {
201 return stopUserLocked(userId, callback);
202 }
203 }
204
205 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
206 if (DEBUG_MU) Slog.i(TAG, "stopUserLocked userId=" + userId);
207 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
208 return USER_OP_IS_CURRENT;
209 }
210
211 final UserState uss = mStartedUsers.get(userId);
212 if (uss == null) {
213 // User is not started, nothing to do... but we do need to
214 // callback if requested.
215 if (callback != null) {
216 mHandler.post(new Runnable() {
217 @Override
218 public void run() {
219 try {
220 callback.userStopped(userId);
221 } catch (RemoteException e) {
222 }
223 }
224 });
225 }
226 return USER_OP_SUCCESS;
227 }
228
229 if (callback != null) {
230 uss.mStopCallbacks.add(callback);
231 }
232
233 if (uss.mState != UserState.STATE_STOPPING
234 && uss.mState != UserState.STATE_SHUTDOWN) {
235 uss.mState = UserState.STATE_STOPPING;
236 updateStartedUserArrayLocked();
237
238 long ident = Binder.clearCallingIdentity();
239 try {
240 // We are going to broadcast ACTION_USER_STOPPING and then
241 // once that is done send a final ACTION_SHUTDOWN and then
242 // stop the user.
243 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
244 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
245 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
246 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
247 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
248 // This is the result receiver for the final shutdown broadcast.
249 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
250 @Override
251 public void performReceive(Intent intent, int resultCode, String data,
252 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
253 finishUserStop(uss);
254 }
255 };
256 // This is the result receiver for the initial stopping broadcast.
257 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
258 @Override
259 public void performReceive(Intent intent, int resultCode, String data,
260 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
261 // On to the next.
262 synchronized (mService) {
263 if (uss.mState != UserState.STATE_STOPPING) {
264 // Whoops, we are being started back up. Abort, abort!
265 return;
266 }
267 uss.mState = UserState.STATE_SHUTDOWN;
268 }
269 mService.mBatteryStatsService.noteEvent(
270 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
271 Integer.toString(userId), userId);
272 mService.mSystemServiceManager.stopUser(userId);
273 mService.broadcastIntentLocked(null, null, shutdownIntent,
274 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
275 null, true, false, ActivityManagerService.MY_PID,
276 android.os.Process.SYSTEM_UID, userId);
277 }
278 };
279 // Kick things off.
280 mService.broadcastIntentLocked(null, null, stoppingIntent,
281 null, stoppingReceiver, 0, null, null,
282 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
283 null, true, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID,
284 UserHandle.USER_ALL);
285 } finally {
286 Binder.restoreCallingIdentity(ident);
287 }
288 }
289
290 return USER_OP_SUCCESS;
291 }
292
293 void finishUserStop(UserState uss) {
294 final int userId = uss.mHandle.getIdentifier();
295 boolean stopped;
296 ArrayList<IStopUserCallback> callbacks;
297 synchronized (mService) {
298 callbacks = new ArrayList<>(uss.mStopCallbacks);
299 if (mStartedUsers.get(userId) != uss) {
300 stopped = false;
301 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
302 stopped = false;
303 } else {
304 stopped = true;
305 // User can no longer run.
306 mStartedUsers.remove(userId);
307 mUserLru.remove(Integer.valueOf(userId));
308 updateStartedUserArrayLocked();
309
310 // Clean up all state and processes associated with the user.
311 // Kill all the processes for the user.
312 forceStopUserLocked(userId, "finish user");
313 }
314 }
315
316 for (int i = 0; i < callbacks.size(); i++) {
317 try {
318 if (stopped) callbacks.get(i).userStopped(userId);
319 else callbacks.get(i).userStopAborted(userId);
320 } catch (RemoteException e) {
321 }
322 }
323
324 if (stopped) {
325 mService.mSystemServiceManager.cleanupUser(userId);
326 synchronized (mService) {
327 mService.mStackSupervisor.removeUserLocked(userId);
328 }
329 }
330 }
331
332 private void forceStopUserLocked(int userId, String reason) {
333 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
334 userId, reason);
335 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
336 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
337 | Intent.FLAG_RECEIVER_FOREGROUND);
338 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
339 mService.broadcastIntentLocked(null, null, intent,
340 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
341 null, false, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID,
342 UserHandle.USER_ALL);
343 }
344
345
346 /**
347 * Stops the guest user if it has gone to the background.
348 */
349 private void stopGuestUserIfBackground() {
350 synchronized (mService) {
351 final int num = mUserLru.size();
352 for (int i = 0; i < num; i++) {
353 Integer oldUserId = mUserLru.get(i);
354 UserState oldUss = mStartedUsers.get(oldUserId);
355 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
356 || oldUss.mState == UserState.STATE_STOPPING
357 || oldUss.mState == UserState.STATE_SHUTDOWN) {
358 continue;
359 }
360 UserInfo userInfo = getUserManagerLocked().getUserInfo(oldUserId);
361 if (userInfo.isGuest()) {
362 // This is a user to be stopped.
363 stopUserLocked(oldUserId, null);
364 break;
365 }
366 }
367 }
368 }
369
370 void startProfilesLocked() {
371 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
372 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
373 mCurrentUserId, false /* enabledOnly */);
374 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
375 for (UserInfo user : profiles) {
376 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
377 && user.id != mCurrentUserId) {
378 profilesToStart.add(user);
379 }
380 }
381 final int profilesToStartSize = profilesToStart.size();
382 int i = 0;
383 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
384 startUser(profilesToStart.get(i).id, /* foreground= */ false);
385 }
386 if (i < profilesToStartSize) {
387 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
388 }
389 }
390
391 private UserManagerService getUserManagerLocked() {
392 return mService.getUserManagerLocked();
393 }
394
395 boolean startUser(final int userId, final boolean foreground) {
396 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
397 != PackageManager.PERMISSION_GRANTED) {
398 String msg = "Permission Denial: switchUser() from pid="
399 + Binder.getCallingPid()
400 + ", uid=" + Binder.getCallingUid()
401 + " requires " + INTERACT_ACROSS_USERS_FULL;
402 Slog.w(TAG, msg);
403 throw new SecurityException(msg);
404 }
405
406 if (DEBUG_MU) Slog.i(TAG, "starting userid:" + userId + " fore:" + foreground);
407
408 final long ident = Binder.clearCallingIdentity();
409 try {
410 synchronized (mService) {
411 final int oldUserId = mCurrentUserId;
412 if (oldUserId == userId) {
413 return true;
414 }
415
416 mService.mStackSupervisor.setLockTaskModeLocked(null,
417 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
418
419 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
420 if (userInfo == null) {
421 Slog.w(TAG, "No user info for user #" + userId);
422 return false;
423 }
424 if (foreground && userInfo.isManagedProfile()) {
425 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
426 return false;
427 }
428
429 if (foreground) {
430 mService.mWindowManager.startFreezingScreen(
431 R.anim.screen_user_exit, R.anim.screen_user_enter);
432 }
433
434 boolean needStart = false;
435
436 // If the user we are switching to is not currently started, then
437 // we need to start it now.
438 if (mStartedUsers.get(userId) == null) {
439 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
440 updateStartedUserArrayLocked();
441 needStart = true;
442 }
443
444 final Integer userIdInt = userId;
445 mUserLru.remove(userIdInt);
446 mUserLru.add(userIdInt);
447
448 if (foreground) {
449 mCurrentUserId = userId;
450 mService.updateUserConfigurationLocked();
451 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
452 updateCurrentProfileIdsLocked();
453 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
454 // Once the internal notion of the active user has switched, we lock the device
455 // with the option to show the user switcher on the keyguard.
456 mService.mWindowManager.lockNow(null);
457 } else {
458 final Integer currentUserIdInt = mCurrentUserId;
459 updateCurrentProfileIdsLocked();
460 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
461 mUserLru.remove(currentUserIdInt);
462 mUserLru.add(currentUserIdInt);
463 }
464
465 final UserState uss = mStartedUsers.get(userId);
466
467 // Make sure user is in the started state. If it is currently
468 // stopping, we need to knock that off.
469 if (uss.mState == UserState.STATE_STOPPING) {
470 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
471 // so we can just fairly silently bring the user back from
472 // the almost-dead.
473 uss.mState = UserState.STATE_RUNNING;
474 updateStartedUserArrayLocked();
475 needStart = true;
476 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
477 // This means ACTION_SHUTDOWN has been sent, so we will
478 // need to treat this as a new boot of the user.
479 uss.mState = UserState.STATE_BOOTING;
480 updateStartedUserArrayLocked();
481 needStart = true;
482 }
483
484 if (uss.mState == UserState.STATE_BOOTING) {
485 // Booting up a new user, need to tell system services about it.
486 // Note that this is on the same handler as scheduling of broadcasts,
487 // which is important because it needs to go first.
488 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
489 }
490
491 if (foreground) {
492 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
493 oldUserId));
494 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
495 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
496 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
497 oldUserId, userId, uss));
498 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
499 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
500 }
501
502 if (needStart) {
503 // Send USER_STARTED broadcast
504 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
506 | Intent.FLAG_RECEIVER_FOREGROUND);
507 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
508 mService.broadcastIntentLocked(null, null, intent,
509 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
510 null, false, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID,
511 userId);
512 }
513
514 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
515 if (userId != UserHandle.USER_SYSTEM) {
516 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
517 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
518 mService.broadcastIntentLocked(null, null, intent, null,
519 new IIntentReceiver.Stub() {
520 public void performReceive(Intent intent, int resultCode,
521 String data, Bundle extras, boolean ordered,
522 boolean sticky, int sendingUser) {
523 onUserInitialized(uss, foreground, oldUserId, userId);
524 }
525 }, 0, null, null, null, AppOpsManager.OP_NONE,
526 null, true, false, ActivityManagerService.MY_PID,
527 Process.SYSTEM_UID, userId);
528 uss.initializing = true;
529 } else {
530 getUserManagerLocked().makeInitialized(userInfo.id);
531 }
532 }
533
534 if (foreground) {
535 if (!uss.initializing) {
536 moveUserToForegroundLocked(uss, oldUserId, userId);
537 }
538 } else {
539 mService.mStackSupervisor.startBackgroundUserLocked(userId, uss);
540 }
541
542 if (needStart) {
543 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
544 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
545 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
546 mService.broadcastIntentLocked(null, null, intent,
547 null, new IIntentReceiver.Stub() {
548 @Override
549 public void performReceive(Intent intent, int resultCode,
550 String data, Bundle extras, boolean ordered, boolean sticky,
551 int sendingUser) throws RemoteException {
552 }
553 }, 0, null, null,
554 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
555 null, true, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID,
556 UserHandle.USER_ALL);
557 }
558 }
559 } finally {
560 Binder.restoreCallingIdentity(ident);
561 }
562
563 return true;
564 }
565
566 void dispatchForegroundProfileChanged(int userId) {
567 final int observerCount = mUserSwitchObservers.beginBroadcast();
568 for (int i = 0; i < observerCount; i++) {
569 try {
570 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
571 } catch (RemoteException e) {
572 // Ignore
573 }
574 }
575 mUserSwitchObservers.finishBroadcast();
576 }
577
578 /** Called on handler thread */
579 void dispatchUserSwitchComplete(int userId) {
580 final int observerCount = mUserSwitchObservers.beginBroadcast();
581 for (int i = 0; i < observerCount; i++) {
582 try {
583 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
584 } catch (RemoteException e) {
585 }
586 }
587 mUserSwitchObservers.finishBroadcast();
588 }
589
590 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
591 synchronized (mService) {
592 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
593 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
594 }
595 }
596
597 void dispatchUserSwitch(final UserState uss, final int oldUserId,
598 final int newUserId) {
599 final int observerCount = mUserSwitchObservers.beginBroadcast();
600 if (observerCount > 0) {
601 final IRemoteCallback callback = new IRemoteCallback.Stub() {
602 int mCount = 0;
603 @Override
604 public void sendResult(Bundle data) throws RemoteException {
605 synchronized (mService) {
606 if (mCurUserSwitchCallback == this) {
607 mCount++;
608 if (mCount == observerCount) {
609 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
610 }
611 }
612 }
613 }
614 };
615 synchronized (mService) {
616 uss.switching = true;
617 mCurUserSwitchCallback = callback;
618 }
619 for (int i = 0; i < observerCount; i++) {
620 try {
621 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
622 newUserId, callback);
623 } catch (RemoteException e) {
624 }
625 }
626 } else {
627 synchronized (mService) {
628 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
629 }
630 }
631 mUserSwitchObservers.finishBroadcast();
632 }
633
634 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
635 mCurUserSwitchCallback = null;
636 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
637 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
638 oldUserId, newUserId, uss));
639 }
640
641 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
642 completeSwitchAndInitialize(uss, newUserId, false, true);
643 }
644
645 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
646 synchronized (mService) {
647 if (foreground) {
648 moveUserToForegroundLocked(uss, oldUserId, newUserId);
649 }
650 }
651 completeSwitchAndInitialize(uss, newUserId, true, false);
652 }
653
654 void completeSwitchAndInitialize(UserState uss, int newUserId,
655 boolean clearInitializing, boolean clearSwitching) {
656 boolean unfrozen = false;
657 synchronized (mService) {
658 if (clearInitializing) {
659 uss.initializing = false;
660 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
661 }
662 if (clearSwitching) {
663 uss.switching = false;
664 }
665 if (!uss.switching && !uss.initializing) {
666 mService.mWindowManager.stopFreezingScreen();
667 unfrozen = true;
668 }
669 }
670 if (unfrozen) {
671 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
672 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
673 newUserId, 0));
674 }
675 stopGuestUserIfBackground();
676 }
677
678 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
679 boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
680 if (homeInFront) {
681 mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
682 } else {
683 mService.mStackSupervisor.resumeTopActivitiesLocked();
684 }
685 EventLogTags.writeAmSwitchUser(newUserId);
686 getUserManagerLocked().onUserForeground(newUserId);
687 mService.sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
688 }
689
690 void registerUserSwitchObserver(IUserSwitchObserver observer) {
691 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
692 != PackageManager.PERMISSION_GRANTED) {
693 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
694 + Binder.getCallingPid()
695 + ", uid=" + Binder.getCallingUid()
696 + " requires " + INTERACT_ACROSS_USERS_FULL;
697 Slog.w(TAG, msg);
698 throw new SecurityException(msg);
699 }
700
701 mUserSwitchObservers.register(observer);
702 }
703
704 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
705 mUserSwitchObservers.unregister(observer);
706 }
707
708 UserState getStartedUserState(int userId) {
709 return mStartedUsers.get(userId);
710 }
711
712 boolean hasStartedUserState(int userId) {
713 return mStartedUsers.get(userId) != null;
714 }
715
716 private void updateStartedUserArrayLocked() {
717 int num = 0;
718 for (int i = 0; i < mStartedUsers.size(); i++) {
719 UserState uss = mStartedUsers.valueAt(i);
720 // This list does not include stopping users.
721 if (uss.mState != UserState.STATE_STOPPING
722 && uss.mState != UserState.STATE_SHUTDOWN) {
723 num++;
724 }
725 }
726 mStartedUserArray = new int[num];
727 num = 0;
728 for (int i = 0; i < mStartedUsers.size(); i++) {
729 UserState uss = mStartedUsers.valueAt(i);
730 if (uss.mState != UserState.STATE_STOPPING
731 && uss.mState != UserState.STATE_SHUTDOWN) {
732 mStartedUserArray[num] = mStartedUsers.keyAt(i);
733 num++;
734 }
735 }
736 }
737
738 void sendBootCompletedLocked(IIntentReceiver resultTo) {
739 for (int i = 0; i < mStartedUsers.size(); i++) {
740 UserState uss = mStartedUsers.valueAt(i);
741 if (uss.mState == UserState.STATE_BOOTING) {
742 uss.mState = UserState.STATE_RUNNING;
743 final int userId = mStartedUsers.keyAt(i);
744 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
745 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
746 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
747 mService.broadcastIntentLocked(null, null, intent, null,
748 resultTo, 0, null, null,
749 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
750 AppOpsManager.OP_NONE, null, true, false,
751 ActivityManagerService.MY_PID, Process.SYSTEM_UID, userId);
752 }
753 }
754 }
755
756 /**
757 * Refreshes the list of users related to the current user when either a
758 * user switch happens or when a new related user is started in the
759 * background.
760 */
761 void updateCurrentProfileIdsLocked() {
762 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId,
763 false /* enabledOnly */);
764 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
765 for (int i = 0; i < currentProfileIds.length; i++) {
766 currentProfileIds[i] = profiles.get(i).id;
767 }
768 mCurrentProfileIds = currentProfileIds;
769
770 synchronized (mUserProfileGroupIdsSelfLocked) {
771 mUserProfileGroupIdsSelfLocked.clear();
772 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
773 for (int i = 0; i < users.size(); i++) {
774 UserInfo user = users.get(i);
775 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
776 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
777 }
778 }
779 }
780 }
781
782 int[] getStartedUserArrayLocked() {
783 return mStartedUserArray;
784 }
785
786 UserInfo getCurrentUser() {
787 if ((mService.checkCallingPermission(INTERACT_ACROSS_USERS)
788 != PackageManager.PERMISSION_GRANTED) && (
789 mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
790 != PackageManager.PERMISSION_GRANTED)) {
791 String msg = "Permission Denial: getCurrentUser() from pid="
792 + Binder.getCallingPid()
793 + ", uid=" + Binder.getCallingUid()
794 + " requires " + INTERACT_ACROSS_USERS;
795 Slog.w(TAG, msg);
796 throw new SecurityException(msg);
797 }
798 synchronized (mService) {
799 return getCurrentUserLocked();
800 }
801 }
802
803 UserInfo getCurrentUserLocked() {
804 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
805 return getUserManagerLocked().getUserInfo(userId);
806 }
807
808 int getCurrentUserIdLocked() {
809 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
810 }
811
812 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
813 synchronized (mUserProfileGroupIdsSelfLocked) {
814 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
815 UserInfo.NO_PROFILE_GROUP_ID);
816 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
817 UserInfo.NO_PROFILE_GROUP_ID);
818 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
819 && callingProfile == targetProfile;
820 }
821 }
822
823 boolean isCurrentProfileLocked(int userId) {
824 return ArrayUtils.contains(mCurrentProfileIds, userId);
825 }
826
827 void dump(PrintWriter pw, boolean dumpAll) {
828 pw.println(" mStartedUsers:");
829 for (int i = 0; i < mStartedUsers.size(); i++) {
830 UserState uss = mStartedUsers.valueAt(i);
831 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
832 pw.print(": "); uss.dump("", pw);
833 }
834 pw.print(" mStartedUserArray: [");
835 for (int i = 0; i < mStartedUserArray.length; i++) {
836 if (i > 0) pw.print(", ");
837 pw.print(mStartedUserArray[i]);
838 }
839 pw.println("]");
840 pw.print(" mUserLru: [");
841 for (int i = 0; i < mUserLru.size(); i++) {
842 if (i > 0) pw.print(", ");
843 pw.print(mUserLru.get(i));
844 }
845 pw.println("]");
846 if (dumpAll) {
847 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
848 }
849 synchronized (mUserProfileGroupIdsSelfLocked) {
850 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
851 pw.println(" mUserProfileGroupIds:");
852 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
853 pw.print(" User #");
854 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
855 pw.print(" -> profile #");
856 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
857 }
858 }
859 }
860 }
861
862}