blob: 5baba524aab43a610c13e05d448bf64827cd31f9 [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;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070021import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
22import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070023import static android.app.ActivityManager.USER_OP_IS_CURRENT;
24import static android.app.ActivityManager.USER_OP_SUCCESS;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000025import static android.content.Context.KEYGUARD_SERVICE;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070026import static android.os.Process.SYSTEM_UID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070027import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
28import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
29import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070030import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
31import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
32import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
33import static com.android.server.am.ActivityManagerService.MY_PID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070034import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
35import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
36import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
37import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -070038import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070039import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
40
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070041import android.annotation.NonNull;
Tony Mak8c536f92016-03-21 12:20:41 +000042import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070043import android.app.ActivityManager;
44import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070045import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070046import android.app.IStopUserCallback;
47import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000048import android.app.KeyguardManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070049import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070050import android.content.IIntentReceiver;
51import android.content.Intent;
52import android.content.pm.PackageManager;
53import android.content.pm.UserInfo;
54import android.os.BatteryStats;
55import android.os.Binder;
56import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070057import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070058import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070059import android.os.IBinder;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070060import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070061import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070062import android.os.Process;
63import android.os.RemoteCallbackList;
64import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070065import android.os.ServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070066import android.os.UserHandle;
67import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010068import android.os.UserManagerInternal;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080069import android.os.storage.IMountService;
70import android.os.storage.StorageManager;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070071import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080072import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070073import android.util.Slog;
74import android.util.SparseArray;
75import android.util.SparseIntArray;
76
77import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080078import com.android.internal.annotations.GuardedBy;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070079import com.android.internal.util.ArrayUtils;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000080import com.android.internal.widget.LockPatternUtils;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010081import com.android.server.LocalServices;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070082import com.android.server.pm.UserManagerService;
83
84import java.io.PrintWriter;
85import java.util.ArrayList;
86import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070087import java.util.HashSet;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070088import java.util.List;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070089import java.util.Set;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070090
91/**
92 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
93 */
94final class UserController {
95 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
96 // Maximum number of users we allow to be running at a time.
97 static final int MAX_RUNNING_USERS = 3;
98
99 // Amount of time we wait for observers to handle a user switch before
100 // giving up on them and unfreezing the screen.
101 static final int USER_SWITCH_TIMEOUT = 2 * 1000;
102
103 private final ActivityManagerService mService;
104 private final Handler mHandler;
105
106 // Holds the current foreground user's id
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700107 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700108 // Holds the target user's id during a user switch
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700109 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700110
111 /**
112 * Which users have been started, so are allowed to run code.
113 */
Jeff Sharkeyba512352015-11-12 20:17:45 -0800114 @GuardedBy("mService")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700115 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800116
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700117 /**
118 * LRU list of history of current users. Most recently current is at the end.
119 */
120 private final ArrayList<Integer> mUserLru = new ArrayList<>();
121
122 /**
123 * Constant array of the users that are currently started.
124 */
125 private int[] mStartedUserArray = new int[] { 0 };
126
127 // If there are multiple profiles for the current user, their ids are here
128 // Currently only the primary user can have managed profiles
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700129 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700130
131 /**
132 * Mapping from each known user ID to the profile group ID it is associated with.
133 */
134 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
135
136 /**
137 * Registered observers of the user switching mechanics.
138 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700139 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700140 = new RemoteCallbackList<>();
141
142 /**
143 * Currently active user switch.
144 */
145 Object mCurUserSwitchCallback;
146
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700147 private volatile UserManagerService mUserManager;
148
Clara Bayarria1771112015-12-18 16:29:18 +0000149 private final LockPatternUtils mLockPatternUtils;
150
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700151 UserController(ActivityManagerService service) {
152 mService = service;
153 mHandler = mService.mHandler;
154 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800155 final UserState uss = new UserState(UserHandle.SYSTEM);
156 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700157 mUserLru.add(UserHandle.USER_SYSTEM);
Clara Bayarria1771112015-12-18 16:29:18 +0000158 mLockPatternUtils = new LockPatternUtils(mService.mContext);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700159 updateStartedUserArrayLocked();
160 }
161
162 void finishUserSwitch(UserState uss) {
163 synchronized (mService) {
164 finishUserBoot(uss);
165
166 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700167 stopRunningUsersLocked(MAX_RUNNING_USERS);
168 }
169 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700170
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700171 void stopRunningUsersLocked(int maxRunningUsers) {
172 int num = mUserLru.size();
173 int i = 0;
174 while (num > maxRunningUsers && i < mUserLru.size()) {
175 Integer oldUserId = mUserLru.get(i);
176 UserState oldUss = mStartedUsers.get(oldUserId);
177 if (oldUss == null) {
178 // Shouldn't happen, but be sane if it does.
179 mUserLru.remove(i);
180 num--;
181 continue;
182 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700183 if (oldUss.state == UserState.STATE_STOPPING
184 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700185 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700186 num--;
187 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700188 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700189 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700190 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
191 // Owner/System user and current user can't be stopped. We count it as running
192 // when it is not a pure system user.
193 if (UserInfo.isSystemOnly(oldUserId)) {
194 num--;
195 }
196 i++;
197 continue;
198 }
199 // This is a user to be stopped.
200 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
201 num--;
202 }
203 num--;
204 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700205 }
206 }
207
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800208 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700209 finishUserBoot(uss, null);
210 }
211
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800212 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700213 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700214 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700215 // Bail if we ended up with a stale user
216 if (mStartedUsers.get(userId) != uss) return;
217
218 // We always walk through all the user lifecycle states to send
219 // consistent developer events. We step into RUNNING_LOCKED here,
220 // but we might immediately step into RUNNING below if the user
221 // storage is already unlocked.
222 if (uss.state == UserState.STATE_BOOTING) {
223 uss.setState(UserState.STATE_RUNNING_LOCKED);
224
225 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700226 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700227 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
228 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700229 mService.broadcastIntentLocked(null, null, intent, null, resultTo, 0, null, null,
230 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
231 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
232 }
233
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700234 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700235 }
236 }
237
238 /**
239 * Consider stepping from {@link UserState#STATE_RUNNING_LOCKED} into
240 * {@link UserState#STATE_RUNNING}, which only occurs if the user storage is
241 * actually unlocked.
242 */
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700243 void finishUserUnlock(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700244 final int userId = uss.mHandle.getIdentifier();
245 synchronized (mService) {
246 // Bail if we ended up with a stale user
247 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
248
249 // Only keep marching forward if user is actually unlocked
250 if (!isUserKeyUnlocked(userId)) return;
251
252 if (uss.state == UserState.STATE_RUNNING_LOCKED) {
253 uss.setState(UserState.STATE_RUNNING);
254
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700255 // Give user manager a chance to prepare app storage
256 mUserManager.onBeforeUnlockUser(userId);
257
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700258 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
259
260 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
Jeff Sharkeyaf6ec292015-12-17 11:19:00 -0700261 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700262 unlockedIntent.addFlags(
263 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
264 mService.broadcastIntentLocked(null, null, unlockedIntent, null, null, 0, null,
265 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
266 userId);
267
Kenny Guyb1b30262016-02-09 16:02:35 +0000268 if (getUserInfo(userId).isManagedProfile()) {
269 UserInfo parent = getUserManager().getProfileParent(userId);
270 if (parent != null) {
271 final Intent profileUnlockedIntent = new Intent(
272 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
Rubin Xub5f00492016-02-15 13:50:18 +0000273 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
274 profileUnlockedIntent.addFlags(
Kenny Guyb1b30262016-02-09 16:02:35 +0000275 Intent.FLAG_RECEIVER_REGISTERED_ONLY
276 | Intent.FLAG_RECEIVER_FOREGROUND);
277 mService.broadcastIntentLocked(null, null, profileUnlockedIntent,
278 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
279 null, false, false, MY_PID, SYSTEM_UID,
280 parent.id);
281 }
282 }
283
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700284 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
285 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800286 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
287 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700288 mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0, null, null,
289 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700290 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700291 }
292 }
293 }
294
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700295 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700296 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
297 != PackageManager.PERMISSION_GRANTED) {
298 String msg = "Permission Denial: switchUser() from pid="
299 + Binder.getCallingPid()
300 + ", uid=" + Binder.getCallingUid()
301 + " requires " + INTERACT_ACROSS_USERS_FULL;
302 Slog.w(TAG, msg);
303 throw new SecurityException(msg);
304 }
305 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
306 throw new IllegalArgumentException("Can't stop system user " + userId);
307 }
308 mService.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
309 userId);
310 synchronized (mService) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700311 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700312 }
313 }
314
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700315 /**
316 * Stops the user along with its related users. The method calls
317 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
318 */
319 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
320 if (userId == UserHandle.USER_SYSTEM) {
321 return USER_OP_ERROR_IS_SYSTEM;
322 }
323 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700324 return USER_OP_IS_CURRENT;
325 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700326 int[] usersToStop = getUsersToStopLocked(userId);
327 // If one of related users is system or current, no related users should be stopped
328 for (int i = 0; i < usersToStop.length; i++) {
329 int relatedUserId = usersToStop[i];
330 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
331 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
332 + relatedUserId);
333 // We still need to stop the requested user if it's a force stop.
334 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800335 Slog.i(TAG,
336 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700337 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800338 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700339 }
340 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
341 }
342 }
343 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
344 for (int userIdToStop : usersToStop) {
345 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
346 }
347 return USER_OP_SUCCESS;
348 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700349
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700350 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
351 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700352 final UserState uss = mStartedUsers.get(userId);
353 if (uss == null) {
354 // User is not started, nothing to do... but we do need to
355 // callback if requested.
356 if (callback != null) {
357 mHandler.post(new Runnable() {
358 @Override
359 public void run() {
360 try {
361 callback.userStopped(userId);
362 } catch (RemoteException e) {
363 }
364 }
365 });
366 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700367 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700368 }
369
370 if (callback != null) {
371 uss.mStopCallbacks.add(callback);
372 }
373
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700374 if (uss.state != UserState.STATE_STOPPING
375 && uss.state != UserState.STATE_SHUTDOWN) {
376 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700377 updateStartedUserArrayLocked();
378
379 long ident = Binder.clearCallingIdentity();
380 try {
381 // We are going to broadcast ACTION_USER_STOPPING and then
382 // once that is done send a final ACTION_SHUTDOWN and then
383 // stop the user.
384 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
385 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
386 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
387 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
388 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
389 // This is the result receiver for the final shutdown broadcast.
390 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
391 @Override
392 public void performReceive(Intent intent, int resultCode, String data,
393 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
394 finishUserStop(uss);
395 }
396 };
397 // This is the result receiver for the initial stopping broadcast.
398 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
399 @Override
400 public void performReceive(Intent intent, int resultCode, String data,
401 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
402 // On to the next.
403 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700404 if (uss.state != UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700405 // Whoops, we are being started back up. Abort, abort!
406 return;
407 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700408 uss.setState(UserState.STATE_SHUTDOWN);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700409 }
410 mService.mBatteryStatsService.noteEvent(
411 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
412 Integer.toString(userId), userId);
413 mService.mSystemServiceManager.stopUser(userId);
414 mService.broadcastIntentLocked(null, null, shutdownIntent,
415 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700416 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700417 }
418 };
419 // Kick things off.
420 mService.broadcastIntentLocked(null, null, stoppingIntent,
421 null, stoppingReceiver, 0, null, null,
422 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700423 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700424 } finally {
425 Binder.restoreCallingIdentity(ident);
426 }
427 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700428 }
429
430 void finishUserStop(UserState uss) {
431 final int userId = uss.mHandle.getIdentifier();
432 boolean stopped;
433 ArrayList<IStopUserCallback> callbacks;
434 synchronized (mService) {
435 callbacks = new ArrayList<>(uss.mStopCallbacks);
436 if (mStartedUsers.get(userId) != uss) {
437 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700438 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700439 stopped = false;
440 } else {
441 stopped = true;
442 // User can no longer run.
443 mStartedUsers.remove(userId);
444 mUserLru.remove(Integer.valueOf(userId));
445 updateStartedUserArrayLocked();
446
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800447 mService.onUserStoppedLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700448 // Clean up all state and processes associated with the user.
449 // Kill all the processes for the user.
450 forceStopUserLocked(userId, "finish user");
451 }
452 }
453
454 for (int i = 0; i < callbacks.size(); i++) {
455 try {
456 if (stopped) callbacks.get(i).userStopped(userId);
457 else callbacks.get(i).userStopAborted(userId);
458 } catch (RemoteException e) {
459 }
460 }
461
462 if (stopped) {
463 mService.mSystemServiceManager.cleanupUser(userId);
464 synchronized (mService) {
465 mService.mStackSupervisor.removeUserLocked(userId);
466 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100467 // Remove the user if it is ephemeral.
468 if (getUserInfo(userId).isEphemeral()) {
469 mUserManager.removeUser(userId);
470 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700471 }
472 }
473
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700474 /**
475 * Determines the list of users that should be stopped together with the specified
476 * {@code userId}. The returned list includes {@code userId}.
477 */
478 private @NonNull int[] getUsersToStopLocked(int userId) {
479 int startedUsersSize = mStartedUsers.size();
480 IntArray userIds = new IntArray();
481 userIds.add(userId);
482 synchronized (mUserProfileGroupIdsSelfLocked) {
483 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
484 UserInfo.NO_PROFILE_GROUP_ID);
485 for (int i = 0; i < startedUsersSize; i++) {
486 UserState uss = mStartedUsers.valueAt(i);
487 int startedUserId = uss.mHandle.getIdentifier();
488 // Skip unrelated users (profileGroupId mismatch)
489 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
490 UserInfo.NO_PROFILE_GROUP_ID);
491 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
492 && (userGroupId == startedUserGroupId);
493 // userId has already been added
494 boolean sameUserId = startedUserId == userId;
495 if (!sameGroup || sameUserId) {
496 continue;
497 }
498 userIds.add(startedUserId);
499 }
500 }
501 return userIds.toArray();
502 }
503
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700504 private void forceStopUserLocked(int userId, String reason) {
505 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
506 userId, reason);
507 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
508 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
509 | Intent.FLAG_RECEIVER_FOREGROUND);
510 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
511 mService.broadcastIntentLocked(null, null, intent,
512 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700513 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700514 }
515
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700516 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100517 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700518 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100519 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700520 synchronized (mService) {
521 final int num = mUserLru.size();
522 for (int i = 0; i < num; i++) {
523 Integer oldUserId = mUserLru.get(i);
524 UserState oldUss = mStartedUsers.get(oldUserId);
525 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700526 || oldUss.state == UserState.STATE_STOPPING
527 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700528 continue;
529 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700530 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100531 if (userInfo.isEphemeral()) {
532 LocalServices.getService(UserManagerInternal.class)
533 .onEphemeralUserStop(oldUserId);
534 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100535 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700536 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700537 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700538 break;
539 }
540 }
541 }
542 }
543
544 void startProfilesLocked() {
545 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700546 List<UserInfo> profiles = getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700547 mCurrentUserId, false /* enabledOnly */);
548 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
549 for (UserInfo user : profiles) {
550 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000551 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700552 profilesToStart.add(user);
553 }
554 }
555 final int profilesToStartSize = profilesToStart.size();
556 int i = 0;
557 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
558 startUser(profilesToStart.get(i).id, /* foreground= */ false);
559 }
560 if (i < profilesToStartSize) {
561 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
562 }
563 }
564
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700565 private UserManagerService getUserManager() {
566 UserManagerService userManager = mUserManager;
567 if (userManager == null) {
568 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
569 userManager = mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
570 }
571 return userManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700572 }
573
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700574 private IMountService getMountService() {
575 return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
576 }
577
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700578 private boolean isUserKeyUnlocked(int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700579 final IMountService mountService = getMountService();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800580 if (mountService != null) {
581 try {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700582 return mountService.isUserKeyUnlocked(userId);
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800583 } catch (RemoteException e) {
584 throw e.rethrowAsRuntimeException();
585 }
586 } else {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700587 Slog.w(TAG, "Mount service not published; guessing locked state based on property");
Paul Lawrence20be5d62016-02-26 13:51:17 -0800588 return !StorageManager.isFileEncryptedNativeOrEmulated();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800589 }
590 }
591
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700592 boolean startUser(final int userId, final boolean foreground) {
593 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
594 != PackageManager.PERMISSION_GRANTED) {
595 String msg = "Permission Denial: switchUser() from pid="
596 + Binder.getCallingPid()
597 + ", uid=" + Binder.getCallingUid()
598 + " requires " + INTERACT_ACROSS_USERS_FULL;
599 Slog.w(TAG, msg);
600 throw new SecurityException(msg);
601 }
602
603 if (DEBUG_MU) Slog.i(TAG, "starting userid:" + userId + " fore:" + foreground);
604
605 final long ident = Binder.clearCallingIdentity();
606 try {
607 synchronized (mService) {
608 final int oldUserId = mCurrentUserId;
609 if (oldUserId == userId) {
610 return true;
611 }
612
613 mService.mStackSupervisor.setLockTaskModeLocked(null,
614 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
615
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700616 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700617 if (userInfo == null) {
618 Slog.w(TAG, "No user info for user #" + userId);
619 return false;
620 }
621 if (foreground && userInfo.isManagedProfile()) {
622 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
623 return false;
624 }
625
626 if (foreground) {
627 mService.mWindowManager.startFreezingScreen(
628 R.anim.screen_user_exit, R.anim.screen_user_enter);
629 }
630
631 boolean needStart = false;
632
633 // If the user we are switching to is not currently started, then
634 // we need to start it now.
635 if (mStartedUsers.get(userId) == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700636 mStartedUsers.put(userId, new UserState(UserHandle.of(userId)));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700637 updateStartedUserArrayLocked();
638 needStart = true;
639 }
640
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800641 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700642 final Integer userIdInt = userId;
643 mUserLru.remove(userIdInt);
644 mUserLru.add(userIdInt);
645
646 if (foreground) {
647 mCurrentUserId = userId;
648 mService.updateUserConfigurationLocked();
649 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
650 updateCurrentProfileIdsLocked();
651 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
652 // Once the internal notion of the active user has switched, we lock the device
653 // with the option to show the user switcher on the keyguard.
654 mService.mWindowManager.lockNow(null);
655 } else {
656 final Integer currentUserIdInt = mCurrentUserId;
657 updateCurrentProfileIdsLocked();
658 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
659 mUserLru.remove(currentUserIdInt);
660 mUserLru.add(currentUserIdInt);
661 }
662
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700663 // Make sure user is in the started state. If it is currently
664 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700665 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
667 // so we can just fairly silently bring the user back from
668 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700669 uss.setState(uss.lastState);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700670 updateStartedUserArrayLocked();
671 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700672 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700673 // This means ACTION_SHUTDOWN has been sent, so we will
674 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700675 uss.setState(UserState.STATE_BOOTING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700676 updateStartedUserArrayLocked();
677 needStart = true;
678 }
679
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700680 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700681 // Give user manager a chance to propagate user restrictions
682 // to other services and prepare app storage
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800683 getUserManager().onBeforeStartUser(userId);
684
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700685 // Booting up a new user, need to tell system services about it.
686 // Note that this is on the same handler as scheduling of broadcasts,
687 // which is important because it needs to go first.
688 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
689 }
690
691 if (foreground) {
692 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
693 oldUserId));
694 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
695 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
696 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
697 oldUserId, userId, uss));
698 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
699 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
700 }
701
702 if (needStart) {
703 // Send USER_STARTED broadcast
704 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
705 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
706 | Intent.FLAG_RECEIVER_FOREGROUND);
707 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
708 mService.broadcastIntentLocked(null, null, intent,
709 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700710 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700711 }
712
713 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
714 if (userId != UserHandle.USER_SYSTEM) {
715 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
716 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
717 mService.broadcastIntentLocked(null, null, intent, null,
718 new IIntentReceiver.Stub() {
719 public void performReceive(Intent intent, int resultCode,
720 String data, Bundle extras, boolean ordered,
721 boolean sticky, int sendingUser) {
722 onUserInitialized(uss, foreground, oldUserId, userId);
723 }
724 }, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700725 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 uss.initializing = true;
727 } else {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700728 getUserManager().makeInitialized(userInfo.id);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700729 }
730 }
731
732 if (foreground) {
733 if (!uss.initializing) {
734 moveUserToForegroundLocked(uss, oldUserId, userId);
735 }
736 } else {
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800737 mService.mUserController.finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700738 }
739
740 if (needStart) {
741 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
743 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
744 mService.broadcastIntentLocked(null, null, intent,
745 null, new IIntentReceiver.Stub() {
746 @Override
747 public void performReceive(Intent intent, int resultCode,
748 String data, Bundle extras, boolean ordered, boolean sticky,
749 int sendingUser) throws RemoteException {
750 }
751 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700752 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
753 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700754 }
755 }
756 } finally {
757 Binder.restoreCallingIdentity(ident);
758 }
759
760 return true;
761 }
762
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700763 /**
764 * Start user, if its not already running, and bring it to foreground.
765 */
766 boolean startUserInForeground(final int userId, Dialog dlg) {
767 boolean result = startUser(userId, /* foreground */ true);
768 dlg.dismiss();
769 return result;
770 }
771
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000772 boolean unlockUser(final int userId, byte[] token, byte[] secret) {
Jeff Sharkeyba512352015-11-12 20:17:45 -0800773 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
774 != PackageManager.PERMISSION_GRANTED) {
775 String msg = "Permission Denial: unlockUser() from pid="
776 + Binder.getCallingPid()
777 + ", uid=" + Binder.getCallingUid()
778 + " requires " + INTERACT_ACROSS_USERS_FULL;
779 Slog.w(TAG, msg);
780 throw new SecurityException(msg);
781 }
782
Jeff Sharkey8924e872015-11-30 12:52:10 -0700783 final long binderToken = Binder.clearCallingIdentity();
784 try {
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000785 return unlockUserCleared(userId, token, secret);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700786 } finally {
787 Binder.restoreCallingIdentity(binderToken);
788 }
789 }
790
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700791 /**
792 * Attempt to unlock user without a credential token. This typically
793 * succeeds when the device doesn't have credential-encrypted storage, or
794 * when the the credential-encrypted storage isn't tied to a user-provided
795 * PIN or pattern.
796 */
797 boolean maybeUnlockUser(final int userId) {
798 // Try unlocking storage using empty token
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000799 return unlockUserCleared(userId, null, null);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700800 }
801
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000802 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret) {
Jeff Sharkey8924e872015-11-30 12:52:10 -0700803 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700804 // Bail if already running unlocked
Jeff Sharkey8924e872015-11-30 12:52:10 -0700805 final UserState uss = mStartedUsers.get(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700806 if (uss.state == UserState.STATE_RUNNING) return true;
Jeff Sharkey8924e872015-11-30 12:52:10 -0700807 }
808
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700809 if (!isUserKeyUnlocked(userId)) {
810 final UserInfo userInfo = getUserInfo(userId);
811 final IMountService mountService = getMountService();
812 try {
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000813 mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700814 } catch (RemoteException | RuntimeException e) {
815 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
816 return false;
817 }
Jeff Sharkeyba512352015-11-12 20:17:45 -0800818 }
819
820 synchronized (mService) {
821 final UserState uss = mStartedUsers.get(userId);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700822 finishUserUnlock(uss);
Jeff Sharkeyba512352015-11-12 20:17:45 -0800823 }
824
825 return true;
826 }
827
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800828 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700829 // The dialog will show and then initiate the user switch by calling startUserInForeground
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800830 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromToUserPair.first,
831 fromToUserPair.second, true /* above system */);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700832 d.show();
833 }
834
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700835 void dispatchForegroundProfileChanged(int userId) {
836 final int observerCount = mUserSwitchObservers.beginBroadcast();
837 for (int i = 0; i < observerCount; i++) {
838 try {
839 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
840 } catch (RemoteException e) {
841 // Ignore
842 }
843 }
844 mUserSwitchObservers.finishBroadcast();
845 }
846
847 /** Called on handler thread */
848 void dispatchUserSwitchComplete(int userId) {
849 final int observerCount = mUserSwitchObservers.beginBroadcast();
850 for (int i = 0; i < observerCount; i++) {
851 try {
852 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
853 } catch (RemoteException e) {
854 }
855 }
856 mUserSwitchObservers.finishBroadcast();
857 }
858
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700859 private void stopBackgroundUsersIfEnforced(int oldUserId) {
860 // Never stop system user
861 if (oldUserId == UserHandle.USER_SYSTEM) {
862 return;
863 }
864 // For now, only check for user restriction. Additional checks can be added here
865 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
866 oldUserId);
867 if (!disallowRunInBg) {
868 return;
869 }
870 synchronized (mService) {
871 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
872 + " and related users");
873 stopUsersLocked(oldUserId, false, null);
874 }
875 }
876
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700877 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
878 synchronized (mService) {
Amith Yamasanica0ac5c2015-11-20 09:44:08 -0800879 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700880 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
881 }
882 }
883
884 void dispatchUserSwitch(final UserState uss, final int oldUserId,
885 final int newUserId) {
886 final int observerCount = mUserSwitchObservers.beginBroadcast();
887 if (observerCount > 0) {
888 final IRemoteCallback callback = new IRemoteCallback.Stub() {
889 int mCount = 0;
890 @Override
891 public void sendResult(Bundle data) throws RemoteException {
892 synchronized (mService) {
893 if (mCurUserSwitchCallback == this) {
894 mCount++;
895 if (mCount == observerCount) {
896 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
897 }
898 }
899 }
900 }
901 };
902 synchronized (mService) {
903 uss.switching = true;
904 mCurUserSwitchCallback = callback;
905 }
906 for (int i = 0; i < observerCount; i++) {
907 try {
908 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
909 newUserId, callback);
910 } catch (RemoteException e) {
911 }
912 }
913 } else {
914 synchronized (mService) {
915 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
916 }
917 }
918 mUserSwitchObservers.finishBroadcast();
919 }
920
921 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
922 mCurUserSwitchCallback = null;
923 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
924 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
925 oldUserId, newUserId, uss));
926 }
927
928 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700929 completeSwitchAndInitialize(uss, oldUserId, newUserId, false, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700930 }
931
932 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
933 synchronized (mService) {
934 if (foreground) {
935 moveUserToForegroundLocked(uss, oldUserId, newUserId);
936 }
937 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700938 completeSwitchAndInitialize(uss, oldUserId, newUserId, true, false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700939 }
940
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700941 void completeSwitchAndInitialize(UserState uss, int oldUserId, int newUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700942 boolean clearInitializing, boolean clearSwitching) {
943 boolean unfrozen = false;
944 synchronized (mService) {
945 if (clearInitializing) {
946 uss.initializing = false;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700947 getUserManager().makeInitialized(uss.mHandle.getIdentifier());
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700948 }
949 if (clearSwitching) {
950 uss.switching = false;
951 }
952 if (!uss.switching && !uss.initializing) {
953 mService.mWindowManager.stopFreezingScreen();
954 unfrozen = true;
955 }
956 }
957 if (unfrozen) {
958 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
959 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
960 newUserId, 0));
961 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100962 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700963 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700964 }
965
966 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
967 boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
968 if (homeInFront) {
969 mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
970 } else {
Wale Ogunwaled046a012015-12-24 13:05:59 -0800971 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700972 }
973 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700974 getUserManager().onUserForeground(newUserId);
975 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
976 }
977
978 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
979 long ident = Binder.clearCallingIdentity();
980 try {
981 Intent intent;
982 if (oldUserId >= 0) {
983 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
984 List<UserInfo> profiles = getUserManager().getProfiles(oldUserId, false);
985 int count = profiles.size();
986 for (int i = 0; i < count; i++) {
987 int profileUserId = profiles.get(i).id;
988 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
989 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
990 | Intent.FLAG_RECEIVER_FOREGROUND);
991 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
992 mService.broadcastIntentLocked(null, null, intent,
993 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
994 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
995 }
996 }
997 if (newUserId >= 0) {
998 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
999 List<UserInfo> profiles = getUserManager().getProfiles(newUserId, false);
1000 int count = profiles.size();
1001 for (int i = 0; i < count; i++) {
1002 int profileUserId = profiles.get(i).id;
1003 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1004 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1005 | Intent.FLAG_RECEIVER_FOREGROUND);
1006 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
1007 mService.broadcastIntentLocked(null, null, intent,
1008 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1009 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1010 }
1011 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1012 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1013 | Intent.FLAG_RECEIVER_FOREGROUND);
1014 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
1015 mService.broadcastIntentLocked(null, null, intent,
1016 null, null, 0, null, null,
1017 new String[] {android.Manifest.permission.MANAGE_USERS},
1018 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1019 UserHandle.USER_ALL);
1020 }
1021 } finally {
1022 Binder.restoreCallingIdentity(ident);
1023 }
1024 }
1025
1026
1027 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1028 int allowMode, String name, String callerPackage) {
1029 final int callingUserId = UserHandle.getUserId(callingUid);
1030 if (callingUserId == userId) {
1031 return userId;
1032 }
1033
1034 // Note that we may be accessing mCurrentUserId outside of a lock...
1035 // shouldn't be a big deal, if this is being called outside
1036 // of a locked context there is intrinsically a race with
1037 // the value the caller will receive and someone else changing it.
1038 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1039 // we will switch to the calling user if access to the current user fails.
1040 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1041
1042 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1043 final boolean allow;
1044 if (mService.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
1045 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1046 // If the caller has this permission, they always pass go. And collect $200.
1047 allow = true;
1048 } else if (allowMode == ALLOW_FULL_ONLY) {
1049 // We require full access, sucks to be you.
1050 allow = false;
1051 } else if (mService.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
1052 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1053 // If the caller does not have either permission, they are always doomed.
1054 allow = false;
1055 } else if (allowMode == ALLOW_NON_FULL) {
1056 // We are blanket allowing non-full access, you lucky caller!
1057 allow = true;
1058 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1059 // We may or may not allow this depending on whether the two users are
1060 // in the same profile.
1061 allow = isSameProfileGroup(callingUserId, targetUserId);
1062 } else {
1063 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1064 }
1065 if (!allow) {
1066 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1067 // In this case, they would like to just execute as their
1068 // owner user instead of failing.
1069 targetUserId = callingUserId;
1070 } else {
1071 StringBuilder builder = new StringBuilder(128);
1072 builder.append("Permission Denial: ");
1073 builder.append(name);
1074 if (callerPackage != null) {
1075 builder.append(" from ");
1076 builder.append(callerPackage);
1077 }
1078 builder.append(" asks to run as user ");
1079 builder.append(userId);
1080 builder.append(" but is calling from user ");
1081 builder.append(UserHandle.getUserId(callingUid));
1082 builder.append("; this requires ");
1083 builder.append(INTERACT_ACROSS_USERS_FULL);
1084 if (allowMode != ALLOW_FULL_ONLY) {
1085 builder.append(" or ");
1086 builder.append(INTERACT_ACROSS_USERS);
1087 }
1088 String msg = builder.toString();
1089 Slog.w(TAG, msg);
1090 throw new SecurityException(msg);
1091 }
1092 }
1093 }
1094 if (!allowAll && targetUserId < 0) {
1095 throw new IllegalArgumentException(
1096 "Call does not support special user #" + targetUserId);
1097 }
1098 // Check shell permission
1099 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1100 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1101 throw new SecurityException("Shell does not have permission to access user "
1102 + targetUserId + "\n " + Debug.getCallers(3));
1103 }
1104 }
1105 return targetUserId;
1106 }
1107
1108 int unsafeConvertIncomingUserLocked(int userId) {
1109 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1110 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001111 }
1112
1113 void registerUserSwitchObserver(IUserSwitchObserver observer) {
1114 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1115 != PackageManager.PERMISSION_GRANTED) {
1116 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1117 + Binder.getCallingPid()
1118 + ", uid=" + Binder.getCallingUid()
1119 + " requires " + INTERACT_ACROSS_USERS_FULL;
1120 Slog.w(TAG, msg);
1121 throw new SecurityException(msg);
1122 }
1123
1124 mUserSwitchObservers.register(observer);
1125 }
1126
1127 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1128 mUserSwitchObservers.unregister(observer);
1129 }
1130
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001131 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001132 return mStartedUsers.get(userId);
1133 }
1134
1135 boolean hasStartedUserState(int userId) {
1136 return mStartedUsers.get(userId) != null;
1137 }
1138
1139 private void updateStartedUserArrayLocked() {
1140 int num = 0;
1141 for (int i = 0; i < mStartedUsers.size(); i++) {
1142 UserState uss = mStartedUsers.valueAt(i);
1143 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001144 if (uss.state != UserState.STATE_STOPPING
1145 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001146 num++;
1147 }
1148 }
1149 mStartedUserArray = new int[num];
1150 num = 0;
1151 for (int i = 0; i < mStartedUsers.size(); i++) {
1152 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001153 if (uss.state != UserState.STATE_STOPPING
1154 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001155 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001156 }
1157 }
1158 }
1159
1160 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1161 for (int i = 0; i < mStartedUsers.size(); i++) {
1162 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001163 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001164 }
1165 }
1166
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001167 void onSystemReady() {
1168 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001169 }
1170
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001171 /**
1172 * Refreshes the list of users related to the current user when either a
1173 * user switch happens or when a new related user is started in the
1174 * background.
1175 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001176 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001177 final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001178 false /* enabledOnly */);
1179 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1180 for (int i = 0; i < currentProfileIds.length; i++) {
1181 currentProfileIds[i] = profiles.get(i).id;
1182 }
1183 mCurrentProfileIds = currentProfileIds;
1184
1185 synchronized (mUserProfileGroupIdsSelfLocked) {
1186 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001187 final List<UserInfo> users = getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001188 for (int i = 0; i < users.size(); i++) {
1189 UserInfo user = users.get(i);
1190 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1191 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1192 }
1193 }
1194 }
1195 }
1196
1197 int[] getStartedUserArrayLocked() {
1198 return mStartedUserArray;
1199 }
1200
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001201 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001202 UserState state = getStartedUserStateLocked(userId);
1203 if (state == null) {
1204 return false;
1205 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001206 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001207 return true;
1208 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001209
1210 final boolean unlocked;
1211 switch (state.state) {
1212 case UserState.STATE_STOPPING:
1213 case UserState.STATE_SHUTDOWN:
1214 default:
1215 return false;
1216
1217 case UserState.STATE_BOOTING:
1218 case UserState.STATE_RUNNING_LOCKED:
1219 unlocked = false;
1220 break;
1221
1222 case UserState.STATE_RUNNING:
1223 unlocked = true;
1224 break;
Jeff Sharkey0825ab22015-12-02 13:04:49 -07001225 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001226
1227 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
1228 return !unlocked;
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001229 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001230 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
1231 return unlocked;
1232 }
1233
1234 // One way or another, we're running!
1235 return true;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001236 }
1237
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001238 UserInfo getCurrentUser() {
1239 if ((mService.checkCallingPermission(INTERACT_ACROSS_USERS)
1240 != PackageManager.PERMISSION_GRANTED) && (
1241 mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1242 != PackageManager.PERMISSION_GRANTED)) {
1243 String msg = "Permission Denial: getCurrentUser() from pid="
1244 + Binder.getCallingPid()
1245 + ", uid=" + Binder.getCallingUid()
1246 + " requires " + INTERACT_ACROSS_USERS;
1247 Slog.w(TAG, msg);
1248 throw new SecurityException(msg);
1249 }
1250 synchronized (mService) {
1251 return getCurrentUserLocked();
1252 }
1253 }
1254
1255 UserInfo getCurrentUserLocked() {
1256 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001257 return getUserInfo(userId);
1258 }
1259
1260 int getCurrentOrTargetUserIdLocked() {
1261 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001262 }
1263
1264 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001265 return mCurrentUserId;
1266 }
1267
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001268 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001269 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001270 }
1271
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001272 int setTargetUserIdLocked(int targetUserId) {
1273 return mTargetUserId = targetUserId;
1274 }
1275
1276 int[] getUsers() {
1277 UserManagerService ums = getUserManager();
1278 return ums != null ? ums.getUserIds() : new int[] { 0 };
1279 }
1280
1281 UserInfo getUserInfo(int userId) {
1282 return getUserManager().getUserInfo(userId);
1283 }
1284
1285 int[] getUserIds() {
1286 return getUserManager().getUserIds();
1287 }
1288
1289 boolean exists(int userId) {
1290 return getUserManager().exists(userId);
1291 }
1292
1293 boolean hasUserRestriction(String restriction, int userId) {
1294 return getUserManager().hasUserRestriction(restriction, userId);
1295 }
1296
1297 Set<Integer> getProfileIds(int userId) {
1298 Set<Integer> userIds = new HashSet<>();
1299 final List<UserInfo> profiles = getUserManager().getProfiles(userId,
1300 false /* enabledOnly */);
1301 for (UserInfo user : profiles) {
1302 userIds.add(user.id);
1303 }
1304 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001305 }
1306
1307 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
1308 synchronized (mUserProfileGroupIdsSelfLocked) {
1309 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1310 UserInfo.NO_PROFILE_GROUP_ID);
1311 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1312 UserInfo.NO_PROFILE_GROUP_ID);
1313 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1314 && callingProfile == targetProfile;
1315 }
1316 }
1317
1318 boolean isCurrentProfileLocked(int userId) {
1319 return ArrayUtils.contains(mCurrentProfileIds, userId);
1320 }
1321
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001322 int[] getCurrentProfileIdsLocked() {
1323 return mCurrentProfileIds;
1324 }
1325
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001326 /**
1327 * Returns whether the given user requires credential entry at this time. This is used to
1328 * intercept activity launches for work apps when the Work Challenge is present.
1329 */
1330 boolean shouldConfirmCredentials(int userId) {
Rubin Xub93522a2016-02-23 18:21:48 +00001331 synchronized (mService) {
1332 if (mStartedUsers.get(userId) == null) {
1333 return false;
1334 }
1335 }
Clara Bayarria1771112015-12-18 16:29:18 +00001336 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001337 return false;
1338 }
1339 final KeyguardManager km = (KeyguardManager) mService.mContext
1340 .getSystemService(KEYGUARD_SERVICE);
Clara Bayarria1771112015-12-18 16:29:18 +00001341 return km.isDeviceLocked(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001342 }
1343
Tony Mak8c536f92016-03-21 12:20:41 +00001344 boolean isLockScreenDisabled(@UserIdInt int userId) {
1345 return mLockPatternUtils.isLockScreenDisabled(userId);
1346 }
1347
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001348 void dump(PrintWriter pw, boolean dumpAll) {
1349 pw.println(" mStartedUsers:");
1350 for (int i = 0; i < mStartedUsers.size(); i++) {
1351 UserState uss = mStartedUsers.valueAt(i);
1352 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1353 pw.print(": "); uss.dump("", pw);
1354 }
1355 pw.print(" mStartedUserArray: [");
1356 for (int i = 0; i < mStartedUserArray.length; i++) {
1357 if (i > 0) pw.print(", ");
1358 pw.print(mStartedUserArray[i]);
1359 }
1360 pw.println("]");
1361 pw.print(" mUserLru: [");
1362 for (int i = 0; i < mUserLru.size(); i++) {
1363 if (i > 0) pw.print(", ");
1364 pw.print(mUserLru.get(i));
1365 }
1366 pw.println("]");
1367 if (dumpAll) {
1368 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1369 }
1370 synchronized (mUserProfileGroupIdsSelfLocked) {
1371 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1372 pw.println(" mUserProfileGroupIds:");
1373 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1374 pw.print(" User #");
1375 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1376 pw.print(" -> profile #");
1377 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1378 }
1379 }
1380 }
1381 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001382}