blob: c59591e9920e90677f621bc67a5a55103cace3a1 [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;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060027
Fyodor Kupolov610acda2015-10-19 18:44:07 -070028import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
29import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
30import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070031import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
32import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
33import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
34import static com.android.server.am.ActivityManagerService.MY_PID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070035import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
36import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
37import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
38import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -070039import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070040import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060041import static com.android.server.am.UserState.STATE_BOOTING;
42import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
43import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
44import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070045
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070046import android.annotation.NonNull;
Tony Mak8c536f92016-03-21 12:20:41 +000047import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070048import android.app.ActivityManager;
49import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070050import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070051import android.app.IStopUserCallback;
52import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000053import android.app.KeyguardManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070054import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.content.IIntentReceiver;
56import android.content.Intent;
57import android.content.pm.PackageManager;
58import android.content.pm.UserInfo;
59import android.os.BatteryStats;
60import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060061import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070062import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070063import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070064import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070065import android.os.IBinder;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070066import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070067import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070068import android.os.Process;
69import android.os.RemoteCallbackList;
70import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070071import android.os.ServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070072import android.os.UserHandle;
73import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010074import android.os.UserManagerInternal;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080075import android.os.storage.IMountService;
76import android.os.storage.StorageManager;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070077import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080078import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070079import android.util.Slog;
80import android.util.SparseArray;
81import android.util.SparseIntArray;
82
83import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080084import com.android.internal.annotations.GuardedBy;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070085import com.android.internal.util.ArrayUtils;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060086import com.android.internal.util.ProgressReporter;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000087import com.android.internal.widget.LockPatternUtils;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010088import com.android.server.LocalServices;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070089import com.android.server.pm.UserManagerService;
90
91import java.io.PrintWriter;
92import java.util.ArrayList;
93import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070094import java.util.HashSet;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070095import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060096import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070097import java.util.Set;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070098
99/**
100 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
101 */
102final class UserController {
103 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
104 // Maximum number of users we allow to be running at a time.
105 static final int MAX_RUNNING_USERS = 3;
106
107 // Amount of time we wait for observers to handle a user switch before
108 // giving up on them and unfreezing the screen.
109 static final int USER_SWITCH_TIMEOUT = 2 * 1000;
110
111 private final ActivityManagerService mService;
112 private final Handler mHandler;
113
114 // Holds the current foreground user's id
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700115 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700116 // Holds the target user's id during a user switch
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700117 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700118
119 /**
120 * Which users have been started, so are allowed to run code.
121 */
Jeff Sharkeyba512352015-11-12 20:17:45 -0800122 @GuardedBy("mService")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700123 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800124
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700125 /**
126 * LRU list of history of current users. Most recently current is at the end.
127 */
128 private final ArrayList<Integer> mUserLru = new ArrayList<>();
129
130 /**
131 * Constant array of the users that are currently started.
132 */
133 private int[] mStartedUserArray = new int[] { 0 };
134
135 // If there are multiple profiles for the current user, their ids are here
136 // Currently only the primary user can have managed profiles
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700137 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700138
139 /**
140 * Mapping from each known user ID to the profile group ID it is associated with.
141 */
142 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
143
144 /**
145 * Registered observers of the user switching mechanics.
146 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700147 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700148 = new RemoteCallbackList<>();
149
150 /**
151 * Currently active user switch.
152 */
153 Object mCurUserSwitchCallback;
154
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700155 private volatile UserManagerService mUserManager;
156
Clara Bayarria1771112015-12-18 16:29:18 +0000157 private final LockPatternUtils mLockPatternUtils;
158
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700159 UserController(ActivityManagerService service) {
160 mService = service;
161 mHandler = mService.mHandler;
162 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800163 final UserState uss = new UserState(UserHandle.SYSTEM);
164 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700165 mUserLru.add(UserHandle.USER_SYSTEM);
Clara Bayarria1771112015-12-18 16:29:18 +0000166 mLockPatternUtils = new LockPatternUtils(mService.mContext);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700167 updateStartedUserArrayLocked();
168 }
169
170 void finishUserSwitch(UserState uss) {
171 synchronized (mService) {
172 finishUserBoot(uss);
173
174 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700175 stopRunningUsersLocked(MAX_RUNNING_USERS);
176 }
177 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700178
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700179 void stopRunningUsersLocked(int maxRunningUsers) {
180 int num = mUserLru.size();
181 int i = 0;
182 while (num > maxRunningUsers && i < mUserLru.size()) {
183 Integer oldUserId = mUserLru.get(i);
184 UserState oldUss = mStartedUsers.get(oldUserId);
185 if (oldUss == null) {
186 // Shouldn't happen, but be sane if it does.
187 mUserLru.remove(i);
188 num--;
189 continue;
190 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700191 if (oldUss.state == UserState.STATE_STOPPING
192 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700193 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700194 num--;
195 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700196 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700197 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700198 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
199 // Owner/System user and current user can't be stopped. We count it as running
200 // when it is not a pure system user.
201 if (UserInfo.isSystemOnly(oldUserId)) {
202 num--;
203 }
204 i++;
205 continue;
206 }
207 // This is a user to be stopped.
208 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
209 num--;
210 }
211 num--;
212 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700213 }
214 }
215
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800216 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700217 finishUserBoot(uss, null);
218 }
219
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800220 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700221 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700222 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700223 // Bail if we ended up with a stale user
224 if (mStartedUsers.get(userId) != uss) return;
225
226 // We always walk through all the user lifecycle states to send
227 // consistent developer events. We step into RUNNING_LOCKED here,
228 // but we might immediately step into RUNNING below if the user
229 // storage is already unlocked.
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600230 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700231 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700232 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700233 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
234 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700235 mService.broadcastIntentLocked(null, null, intent, null, resultTo, 0, null, null,
236 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
237 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
238 }
239
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700240 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700241 }
242 }
243
244 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600245 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
246 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700247 */
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600248 void finishUserUnlocking(final UserState uss, final ProgressReporter progress) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700249 final int userId = uss.mHandle.getIdentifier();
250 synchronized (mService) {
251 // Bail if we ended up with a stale user
252 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
253
254 // Only keep marching forward if user is actually unlocked
255 if (!isUserKeyUnlocked(userId)) return;
256
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600257 if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
258 // Prepare app storage before we go any further
259 progress.setProgress(5, mService.mContext.getString(R.string.android_start_title));
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700260 mUserManager.onBeforeUnlockUser(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600261 progress.setProgress(20);
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700262
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600263 // Send PRE_BOOT broadcasts if fingerprint changed
264 final UserInfo info = getUserInfo(userId);
265 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
266 progress.startSegment(80);
267 new PreBootBroadcaster(mService, userId, progress) {
268 @Override
269 public void onFinished() {
270 finishUserUnlocked(uss, progress);
271 }
272 }.sendNext();
273 } else {
274 finishUserUnlocked(uss, progress);
275 }
276 }
277 }
278 }
279
280 /**
281 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
282 * {@link UserState#STATE_RUNNING_UNLOCKED}.
283 */
284 void finishUserUnlocked(UserState uss, ProgressReporter progress) {
285 try {
286 finishUserUnlockedInternal(uss);
287 } finally {
288 progress.finish();
289 }
290 }
291
292 void finishUserUnlockedInternal(UserState uss) {
293 final int userId = uss.mHandle.getIdentifier();
294 synchronized (mService) {
295 // Bail if we ended up with a stale user
296 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
297
298 // Only keep marching forward if user is actually unlocked
299 if (!isUserKeyUnlocked(userId)) return;
300
301 if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
302 // Remember that we logged in
303 mUserManager.onUserLoggedIn(userId);
304
305 // Dispatch unlocked to system services
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700306 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
307
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600308 // Dispatch unlocked to external apps
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700309 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
Jeff Sharkeyaf6ec292015-12-17 11:19:00 -0700310 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700311 unlockedIntent.addFlags(
312 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
313 mService.broadcastIntentLocked(null, null, unlockedIntent, null, null, 0, null,
314 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
315 userId);
316
Kenny Guyb1b30262016-02-09 16:02:35 +0000317 if (getUserInfo(userId).isManagedProfile()) {
318 UserInfo parent = getUserManager().getProfileParent(userId);
319 if (parent != null) {
320 final Intent profileUnlockedIntent = new Intent(
321 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
Rubin Xub5f00492016-02-15 13:50:18 +0000322 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
323 profileUnlockedIntent.addFlags(
Kenny Guyb1b30262016-02-09 16:02:35 +0000324 Intent.FLAG_RECEIVER_REGISTERED_ONLY
325 | Intent.FLAG_RECEIVER_FOREGROUND);
326 mService.broadcastIntentLocked(null, null, profileUnlockedIntent,
327 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
328 null, false, false, MY_PID, SYSTEM_UID,
329 parent.id);
330 }
331 }
332
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700333 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
334 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800335 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
336 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700337 mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0, null, null,
338 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700339 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700340 }
341 }
342 }
343
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700344 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700345 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
346 != PackageManager.PERMISSION_GRANTED) {
347 String msg = "Permission Denial: switchUser() from pid="
348 + Binder.getCallingPid()
349 + ", uid=" + Binder.getCallingUid()
350 + " requires " + INTERACT_ACROSS_USERS_FULL;
351 Slog.w(TAG, msg);
352 throw new SecurityException(msg);
353 }
354 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
355 throw new IllegalArgumentException("Can't stop system user " + userId);
356 }
357 mService.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
358 userId);
359 synchronized (mService) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700360 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700361 }
362 }
363
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700364 /**
365 * Stops the user along with its related users. The method calls
366 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
367 */
368 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
369 if (userId == UserHandle.USER_SYSTEM) {
370 return USER_OP_ERROR_IS_SYSTEM;
371 }
372 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700373 return USER_OP_IS_CURRENT;
374 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700375 int[] usersToStop = getUsersToStopLocked(userId);
376 // If one of related users is system or current, no related users should be stopped
377 for (int i = 0; i < usersToStop.length; i++) {
378 int relatedUserId = usersToStop[i];
379 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
380 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
381 + relatedUserId);
382 // We still need to stop the requested user if it's a force stop.
383 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800384 Slog.i(TAG,
385 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700386 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800387 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700388 }
389 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
390 }
391 }
392 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
393 for (int userIdToStop : usersToStop) {
394 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
395 }
396 return USER_OP_SUCCESS;
397 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700398
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700399 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
400 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700401 final UserState uss = mStartedUsers.get(userId);
402 if (uss == null) {
403 // User is not started, nothing to do... but we do need to
404 // callback if requested.
405 if (callback != null) {
406 mHandler.post(new Runnable() {
407 @Override
408 public void run() {
409 try {
410 callback.userStopped(userId);
411 } catch (RemoteException e) {
412 }
413 }
414 });
415 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700416 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700417 }
418
419 if (callback != null) {
420 uss.mStopCallbacks.add(callback);
421 }
422
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700423 if (uss.state != UserState.STATE_STOPPING
424 && uss.state != UserState.STATE_SHUTDOWN) {
425 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700426 updateStartedUserArrayLocked();
427
428 long ident = Binder.clearCallingIdentity();
429 try {
430 // We are going to broadcast ACTION_USER_STOPPING and then
431 // once that is done send a final ACTION_SHUTDOWN and then
432 // stop the user.
433 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
434 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
435 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
436 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
437 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
438 // This is the result receiver for the final shutdown broadcast.
439 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
440 @Override
441 public void performReceive(Intent intent, int resultCode, String data,
442 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
443 finishUserStop(uss);
444 }
445 };
446 // This is the result receiver for the initial stopping broadcast.
447 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
448 @Override
449 public void performReceive(Intent intent, int resultCode, String data,
450 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
451 // On to the next.
452 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700453 if (uss.state != UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700454 // Whoops, we are being started back up. Abort, abort!
455 return;
456 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700457 uss.setState(UserState.STATE_SHUTDOWN);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700458 }
459 mService.mBatteryStatsService.noteEvent(
460 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
461 Integer.toString(userId), userId);
462 mService.mSystemServiceManager.stopUser(userId);
463 mService.broadcastIntentLocked(null, null, shutdownIntent,
464 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700465 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700466 }
467 };
468 // Kick things off.
469 mService.broadcastIntentLocked(null, null, stoppingIntent,
470 null, stoppingReceiver, 0, null, null,
471 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700472 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700473 } finally {
474 Binder.restoreCallingIdentity(ident);
475 }
476 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700477 }
478
479 void finishUserStop(UserState uss) {
480 final int userId = uss.mHandle.getIdentifier();
481 boolean stopped;
482 ArrayList<IStopUserCallback> callbacks;
483 synchronized (mService) {
484 callbacks = new ArrayList<>(uss.mStopCallbacks);
485 if (mStartedUsers.get(userId) != uss) {
486 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700487 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700488 stopped = false;
489 } else {
490 stopped = true;
491 // User can no longer run.
492 mStartedUsers.remove(userId);
493 mUserLru.remove(Integer.valueOf(userId));
494 updateStartedUserArrayLocked();
495
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800496 mService.onUserStoppedLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700497 // Clean up all state and processes associated with the user.
498 // Kill all the processes for the user.
499 forceStopUserLocked(userId, "finish user");
500 }
501 }
502
503 for (int i = 0; i < callbacks.size(); i++) {
504 try {
505 if (stopped) callbacks.get(i).userStopped(userId);
506 else callbacks.get(i).userStopAborted(userId);
507 } catch (RemoteException e) {
508 }
509 }
510
511 if (stopped) {
512 mService.mSystemServiceManager.cleanupUser(userId);
513 synchronized (mService) {
514 mService.mStackSupervisor.removeUserLocked(userId);
515 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100516 // Remove the user if it is ephemeral.
517 if (getUserInfo(userId).isEphemeral()) {
518 mUserManager.removeUser(userId);
519 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700520 }
521 }
522
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700523 /**
524 * Determines the list of users that should be stopped together with the specified
525 * {@code userId}. The returned list includes {@code userId}.
526 */
527 private @NonNull int[] getUsersToStopLocked(int userId) {
528 int startedUsersSize = mStartedUsers.size();
529 IntArray userIds = new IntArray();
530 userIds.add(userId);
531 synchronized (mUserProfileGroupIdsSelfLocked) {
532 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
533 UserInfo.NO_PROFILE_GROUP_ID);
534 for (int i = 0; i < startedUsersSize; i++) {
535 UserState uss = mStartedUsers.valueAt(i);
536 int startedUserId = uss.mHandle.getIdentifier();
537 // Skip unrelated users (profileGroupId mismatch)
538 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
539 UserInfo.NO_PROFILE_GROUP_ID);
540 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
541 && (userGroupId == startedUserGroupId);
542 // userId has already been added
543 boolean sameUserId = startedUserId == userId;
544 if (!sameGroup || sameUserId) {
545 continue;
546 }
547 userIds.add(startedUserId);
548 }
549 }
550 return userIds.toArray();
551 }
552
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700553 private void forceStopUserLocked(int userId, String reason) {
554 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
555 userId, reason);
556 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
557 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
558 | Intent.FLAG_RECEIVER_FOREGROUND);
559 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
560 mService.broadcastIntentLocked(null, null, intent,
561 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700562 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700563 }
564
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700565 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100566 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700567 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100568 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700569 synchronized (mService) {
570 final int num = mUserLru.size();
571 for (int i = 0; i < num; i++) {
572 Integer oldUserId = mUserLru.get(i);
573 UserState oldUss = mStartedUsers.get(oldUserId);
574 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700575 || oldUss.state == UserState.STATE_STOPPING
576 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700577 continue;
578 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700579 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100580 if (userInfo.isEphemeral()) {
581 LocalServices.getService(UserManagerInternal.class)
582 .onEphemeralUserStop(oldUserId);
583 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100584 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700585 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700586 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700587 break;
588 }
589 }
590 }
591 }
592
593 void startProfilesLocked() {
594 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700595 List<UserInfo> profiles = getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700596 mCurrentUserId, false /* enabledOnly */);
597 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
598 for (UserInfo user : profiles) {
599 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000600 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700601 profilesToStart.add(user);
602 }
603 }
604 final int profilesToStartSize = profilesToStart.size();
605 int i = 0;
606 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
607 startUser(profilesToStart.get(i).id, /* foreground= */ false);
608 }
609 if (i < profilesToStartSize) {
610 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
611 }
612 }
613
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700614 private UserManagerService getUserManager() {
615 UserManagerService userManager = mUserManager;
616 if (userManager == null) {
617 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
618 userManager = mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
619 }
620 return userManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700621 }
622
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700623 private IMountService getMountService() {
624 return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
625 }
626
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700627 private boolean isUserKeyUnlocked(int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700628 final IMountService mountService = getMountService();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800629 if (mountService != null) {
630 try {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700631 return mountService.isUserKeyUnlocked(userId);
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800632 } catch (RemoteException e) {
633 throw e.rethrowAsRuntimeException();
634 }
635 } else {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700636 Slog.w(TAG, "Mount service not published; guessing locked state based on property");
Paul Lawrence20be5d62016-02-26 13:51:17 -0800637 return !StorageManager.isFileEncryptedNativeOrEmulated();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800638 }
639 }
640
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700641 boolean startUser(final int userId, final boolean foreground) {
642 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
643 != PackageManager.PERMISSION_GRANTED) {
644 String msg = "Permission Denial: switchUser() from pid="
645 + Binder.getCallingPid()
646 + ", uid=" + Binder.getCallingUid()
647 + " requires " + INTERACT_ACROSS_USERS_FULL;
648 Slog.w(TAG, msg);
649 throw new SecurityException(msg);
650 }
651
652 if (DEBUG_MU) Slog.i(TAG, "starting userid:" + userId + " fore:" + foreground);
653
654 final long ident = Binder.clearCallingIdentity();
655 try {
656 synchronized (mService) {
657 final int oldUserId = mCurrentUserId;
658 if (oldUserId == userId) {
659 return true;
660 }
661
662 mService.mStackSupervisor.setLockTaskModeLocked(null,
663 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
664
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700665 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666 if (userInfo == null) {
667 Slog.w(TAG, "No user info for user #" + userId);
668 return false;
669 }
670 if (foreground && userInfo.isManagedProfile()) {
671 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
672 return false;
673 }
674
675 if (foreground) {
676 mService.mWindowManager.startFreezingScreen(
677 R.anim.screen_user_exit, R.anim.screen_user_enter);
678 }
679
680 boolean needStart = false;
681
682 // If the user we are switching to is not currently started, then
683 // we need to start it now.
684 if (mStartedUsers.get(userId) == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700685 mStartedUsers.put(userId, new UserState(UserHandle.of(userId)));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700686 updateStartedUserArrayLocked();
687 needStart = true;
688 }
689
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800690 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700691 final Integer userIdInt = userId;
692 mUserLru.remove(userIdInt);
693 mUserLru.add(userIdInt);
694
695 if (foreground) {
696 mCurrentUserId = userId;
697 mService.updateUserConfigurationLocked();
698 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
699 updateCurrentProfileIdsLocked();
700 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
701 // Once the internal notion of the active user has switched, we lock the device
702 // with the option to show the user switcher on the keyguard.
703 mService.mWindowManager.lockNow(null);
704 } else {
705 final Integer currentUserIdInt = mCurrentUserId;
706 updateCurrentProfileIdsLocked();
707 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
708 mUserLru.remove(currentUserIdInt);
709 mUserLru.add(currentUserIdInt);
710 }
711
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700712 // Make sure user is in the started state. If it is currently
713 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700714 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700715 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
716 // so we can just fairly silently bring the user back from
717 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700718 uss.setState(uss.lastState);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700719 updateStartedUserArrayLocked();
720 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700721 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700722 // This means ACTION_SHUTDOWN has been sent, so we will
723 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700724 uss.setState(UserState.STATE_BOOTING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700725 updateStartedUserArrayLocked();
726 needStart = true;
727 }
728
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700729 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700730 // Give user manager a chance to propagate user restrictions
731 // to other services and prepare app storage
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800732 getUserManager().onBeforeStartUser(userId);
733
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700734 // Booting up a new user, need to tell system services about it.
735 // Note that this is on the same handler as scheduling of broadcasts,
736 // which is important because it needs to go first.
737 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
738 }
739
740 if (foreground) {
741 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
742 oldUserId));
743 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
744 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
745 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
746 oldUserId, userId, uss));
747 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
748 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
749 }
750
751 if (needStart) {
752 // Send USER_STARTED broadcast
753 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
754 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
755 | Intent.FLAG_RECEIVER_FOREGROUND);
756 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
757 mService.broadcastIntentLocked(null, null, intent,
758 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700759 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700760 }
761
762 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
763 if (userId != UserHandle.USER_SYSTEM) {
764 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
765 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
766 mService.broadcastIntentLocked(null, null, intent, null,
767 new IIntentReceiver.Stub() {
768 public void performReceive(Intent intent, int resultCode,
769 String data, Bundle extras, boolean ordered,
770 boolean sticky, int sendingUser) {
771 onUserInitialized(uss, foreground, oldUserId, userId);
772 }
773 }, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700774 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700775 uss.initializing = true;
776 } else {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700777 getUserManager().makeInitialized(userInfo.id);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700778 }
779 }
780
781 if (foreground) {
782 if (!uss.initializing) {
783 moveUserToForegroundLocked(uss, oldUserId, userId);
784 }
785 } else {
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800786 mService.mUserController.finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700787 }
788
789 if (needStart) {
790 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
791 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
792 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
793 mService.broadcastIntentLocked(null, null, intent,
794 null, new IIntentReceiver.Stub() {
795 @Override
796 public void performReceive(Intent intent, int resultCode,
797 String data, Bundle extras, boolean ordered, boolean sticky,
798 int sendingUser) throws RemoteException {
799 }
800 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700801 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
802 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700803 }
804 }
805 } finally {
806 Binder.restoreCallingIdentity(ident);
807 }
808
809 return true;
810 }
811
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700812 /**
813 * Start user, if its not already running, and bring it to foreground.
814 */
815 boolean startUserInForeground(final int userId, Dialog dlg) {
816 boolean result = startUser(userId, /* foreground */ true);
817 dlg.dismiss();
818 return result;
819 }
820
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600821 boolean unlockUser(final int userId, byte[] token, byte[] secret, ProgressReporter progress) {
Jeff Sharkeyba512352015-11-12 20:17:45 -0800822 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
823 != PackageManager.PERMISSION_GRANTED) {
824 String msg = "Permission Denial: unlockUser() from pid="
825 + Binder.getCallingPid()
826 + ", uid=" + Binder.getCallingUid()
827 + " requires " + INTERACT_ACROSS_USERS_FULL;
828 Slog.w(TAG, msg);
829 throw new SecurityException(msg);
830 }
831
Jeff Sharkey8924e872015-11-30 12:52:10 -0700832 final long binderToken = Binder.clearCallingIdentity();
833 try {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600834 return unlockUserCleared(userId, token, secret, progress);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700835 } finally {
836 Binder.restoreCallingIdentity(binderToken);
837 }
838 }
839
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700840 /**
841 * Attempt to unlock user without a credential token. This typically
842 * succeeds when the device doesn't have credential-encrypted storage, or
843 * when the the credential-encrypted storage isn't tied to a user-provided
844 * PIN or pattern.
845 */
846 boolean maybeUnlockUser(final int userId) {
847 // Try unlocking storage using empty token
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600848 return unlockUserCleared(userId, null, null, ProgressReporter.NO_OP);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700849 }
850
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600851 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
852 ProgressReporter progress) {
Jeff Sharkey8924e872015-11-30 12:52:10 -0700853 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700854 // Bail if already running unlocked
Jeff Sharkey8924e872015-11-30 12:52:10 -0700855 final UserState uss = mStartedUsers.get(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600856 switch (uss.state) {
857 case STATE_RUNNING_UNLOCKING:
858 case STATE_RUNNING_UNLOCKED:
859 progress.finish();
860 return true;
861 }
Jeff Sharkey8924e872015-11-30 12:52:10 -0700862 }
863
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700864 if (!isUserKeyUnlocked(userId)) {
865 final UserInfo userInfo = getUserInfo(userId);
866 final IMountService mountService = getMountService();
867 try {
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000868 mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700869 } catch (RemoteException | RuntimeException e) {
870 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600871 progress.finish();
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700872 return false;
873 }
Jeff Sharkeyba512352015-11-12 20:17:45 -0800874 }
875
876 synchronized (mService) {
877 final UserState uss = mStartedUsers.get(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600878 finishUserUnlocking(uss, progress);
Jeff Sharkeyba512352015-11-12 20:17:45 -0800879 }
880
881 return true;
882 }
883
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800884 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700885 // The dialog will show and then initiate the user switch by calling startUserInForeground
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800886 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromToUserPair.first,
887 fromToUserPair.second, true /* above system */);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700888 d.show();
889 }
890
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700891 void dispatchForegroundProfileChanged(int userId) {
892 final int observerCount = mUserSwitchObservers.beginBroadcast();
893 for (int i = 0; i < observerCount; i++) {
894 try {
895 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
896 } catch (RemoteException e) {
897 // Ignore
898 }
899 }
900 mUserSwitchObservers.finishBroadcast();
901 }
902
903 /** Called on handler thread */
904 void dispatchUserSwitchComplete(int userId) {
905 final int observerCount = mUserSwitchObservers.beginBroadcast();
906 for (int i = 0; i < observerCount; i++) {
907 try {
908 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
909 } catch (RemoteException e) {
910 }
911 }
912 mUserSwitchObservers.finishBroadcast();
913 }
914
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700915 private void stopBackgroundUsersIfEnforced(int oldUserId) {
916 // Never stop system user
917 if (oldUserId == UserHandle.USER_SYSTEM) {
918 return;
919 }
920 // For now, only check for user restriction. Additional checks can be added here
921 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
922 oldUserId);
923 if (!disallowRunInBg) {
924 return;
925 }
926 synchronized (mService) {
927 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
928 + " and related users");
929 stopUsersLocked(oldUserId, false, null);
930 }
931 }
932
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700933 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
934 synchronized (mService) {
Amith Yamasanica0ac5c2015-11-20 09:44:08 -0800935 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700936 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
937 }
938 }
939
940 void dispatchUserSwitch(final UserState uss, final int oldUserId,
941 final int newUserId) {
942 final int observerCount = mUserSwitchObservers.beginBroadcast();
943 if (observerCount > 0) {
944 final IRemoteCallback callback = new IRemoteCallback.Stub() {
945 int mCount = 0;
946 @Override
947 public void sendResult(Bundle data) throws RemoteException {
948 synchronized (mService) {
949 if (mCurUserSwitchCallback == this) {
950 mCount++;
951 if (mCount == observerCount) {
952 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
953 }
954 }
955 }
956 }
957 };
958 synchronized (mService) {
959 uss.switching = true;
960 mCurUserSwitchCallback = callback;
961 }
962 for (int i = 0; i < observerCount; i++) {
963 try {
964 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
965 newUserId, callback);
966 } catch (RemoteException e) {
967 }
968 }
969 } else {
970 synchronized (mService) {
971 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
972 }
973 }
974 mUserSwitchObservers.finishBroadcast();
975 }
976
977 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
978 mCurUserSwitchCallback = null;
979 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
980 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
981 oldUserId, newUserId, uss));
982 }
983
984 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700985 completeSwitchAndInitialize(uss, oldUserId, newUserId, false, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700986 }
987
988 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
989 synchronized (mService) {
990 if (foreground) {
991 moveUserToForegroundLocked(uss, oldUserId, newUserId);
992 }
993 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700994 completeSwitchAndInitialize(uss, oldUserId, newUserId, true, false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700995 }
996
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700997 void completeSwitchAndInitialize(UserState uss, int oldUserId, int newUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700998 boolean clearInitializing, boolean clearSwitching) {
999 boolean unfrozen = false;
1000 synchronized (mService) {
1001 if (clearInitializing) {
1002 uss.initializing = false;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001003 getUserManager().makeInitialized(uss.mHandle.getIdentifier());
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001004 }
1005 if (clearSwitching) {
1006 uss.switching = false;
1007 }
1008 if (!uss.switching && !uss.initializing) {
1009 mService.mWindowManager.stopFreezingScreen();
1010 unfrozen = true;
1011 }
1012 }
1013 if (unfrozen) {
1014 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1015 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1016 newUserId, 0));
1017 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001018 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001019 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001020 }
1021
1022 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
1023 boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
1024 if (homeInFront) {
1025 mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
1026 } else {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001027 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001028 }
1029 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001030 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
1031 }
1032
1033 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1034 long ident = Binder.clearCallingIdentity();
1035 try {
1036 Intent intent;
1037 if (oldUserId >= 0) {
1038 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
1039 List<UserInfo> profiles = getUserManager().getProfiles(oldUserId, false);
1040 int count = profiles.size();
1041 for (int i = 0; i < count; i++) {
1042 int profileUserId = profiles.get(i).id;
1043 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1044 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1045 | Intent.FLAG_RECEIVER_FOREGROUND);
1046 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
1047 mService.broadcastIntentLocked(null, null, intent,
1048 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1049 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1050 }
1051 }
1052 if (newUserId >= 0) {
1053 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
1054 List<UserInfo> profiles = getUserManager().getProfiles(newUserId, false);
1055 int count = profiles.size();
1056 for (int i = 0; i < count; i++) {
1057 int profileUserId = profiles.get(i).id;
1058 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1059 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1060 | Intent.FLAG_RECEIVER_FOREGROUND);
1061 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
1062 mService.broadcastIntentLocked(null, null, intent,
1063 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1064 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1065 }
1066 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1068 | Intent.FLAG_RECEIVER_FOREGROUND);
1069 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
1070 mService.broadcastIntentLocked(null, null, intent,
1071 null, null, 0, null, null,
1072 new String[] {android.Manifest.permission.MANAGE_USERS},
1073 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1074 UserHandle.USER_ALL);
1075 }
1076 } finally {
1077 Binder.restoreCallingIdentity(ident);
1078 }
1079 }
1080
1081
1082 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1083 int allowMode, String name, String callerPackage) {
1084 final int callingUserId = UserHandle.getUserId(callingUid);
1085 if (callingUserId == userId) {
1086 return userId;
1087 }
1088
1089 // Note that we may be accessing mCurrentUserId outside of a lock...
1090 // shouldn't be a big deal, if this is being called outside
1091 // of a locked context there is intrinsically a race with
1092 // the value the caller will receive and someone else changing it.
1093 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1094 // we will switch to the calling user if access to the current user fails.
1095 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1096
1097 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1098 final boolean allow;
1099 if (mService.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
1100 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1101 // If the caller has this permission, they always pass go. And collect $200.
1102 allow = true;
1103 } else if (allowMode == ALLOW_FULL_ONLY) {
1104 // We require full access, sucks to be you.
1105 allow = false;
1106 } else if (mService.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
1107 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1108 // If the caller does not have either permission, they are always doomed.
1109 allow = false;
1110 } else if (allowMode == ALLOW_NON_FULL) {
1111 // We are blanket allowing non-full access, you lucky caller!
1112 allow = true;
1113 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1114 // We may or may not allow this depending on whether the two users are
1115 // in the same profile.
1116 allow = isSameProfileGroup(callingUserId, targetUserId);
1117 } else {
1118 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1119 }
1120 if (!allow) {
1121 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1122 // In this case, they would like to just execute as their
1123 // owner user instead of failing.
1124 targetUserId = callingUserId;
1125 } else {
1126 StringBuilder builder = new StringBuilder(128);
1127 builder.append("Permission Denial: ");
1128 builder.append(name);
1129 if (callerPackage != null) {
1130 builder.append(" from ");
1131 builder.append(callerPackage);
1132 }
1133 builder.append(" asks to run as user ");
1134 builder.append(userId);
1135 builder.append(" but is calling from user ");
1136 builder.append(UserHandle.getUserId(callingUid));
1137 builder.append("; this requires ");
1138 builder.append(INTERACT_ACROSS_USERS_FULL);
1139 if (allowMode != ALLOW_FULL_ONLY) {
1140 builder.append(" or ");
1141 builder.append(INTERACT_ACROSS_USERS);
1142 }
1143 String msg = builder.toString();
1144 Slog.w(TAG, msg);
1145 throw new SecurityException(msg);
1146 }
1147 }
1148 }
1149 if (!allowAll && targetUserId < 0) {
1150 throw new IllegalArgumentException(
1151 "Call does not support special user #" + targetUserId);
1152 }
1153 // Check shell permission
1154 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1155 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1156 throw new SecurityException("Shell does not have permission to access user "
1157 + targetUserId + "\n " + Debug.getCallers(3));
1158 }
1159 }
1160 return targetUserId;
1161 }
1162
1163 int unsafeConvertIncomingUserLocked(int userId) {
1164 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1165 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001166 }
1167
1168 void registerUserSwitchObserver(IUserSwitchObserver observer) {
1169 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1170 != PackageManager.PERMISSION_GRANTED) {
1171 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1172 + Binder.getCallingPid()
1173 + ", uid=" + Binder.getCallingUid()
1174 + " requires " + INTERACT_ACROSS_USERS_FULL;
1175 Slog.w(TAG, msg);
1176 throw new SecurityException(msg);
1177 }
1178
1179 mUserSwitchObservers.register(observer);
1180 }
1181
1182 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1183 mUserSwitchObservers.unregister(observer);
1184 }
1185
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001186 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001187 return mStartedUsers.get(userId);
1188 }
1189
1190 boolean hasStartedUserState(int userId) {
1191 return mStartedUsers.get(userId) != null;
1192 }
1193
1194 private void updateStartedUserArrayLocked() {
1195 int num = 0;
1196 for (int i = 0; i < mStartedUsers.size(); i++) {
1197 UserState uss = mStartedUsers.valueAt(i);
1198 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001199 if (uss.state != UserState.STATE_STOPPING
1200 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001201 num++;
1202 }
1203 }
1204 mStartedUserArray = new int[num];
1205 num = 0;
1206 for (int i = 0; i < mStartedUsers.size(); i++) {
1207 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001208 if (uss.state != UserState.STATE_STOPPING
1209 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001210 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001211 }
1212 }
1213 }
1214
1215 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1216 for (int i = 0; i < mStartedUsers.size(); i++) {
1217 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001218 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001219 }
1220 }
1221
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001222 void onSystemReady() {
1223 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001224 }
1225
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001226 /**
1227 * Refreshes the list of users related to the current user when either a
1228 * user switch happens or when a new related user is started in the
1229 * background.
1230 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001231 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001232 final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001233 false /* enabledOnly */);
1234 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1235 for (int i = 0; i < currentProfileIds.length; i++) {
1236 currentProfileIds[i] = profiles.get(i).id;
1237 }
1238 mCurrentProfileIds = currentProfileIds;
1239
1240 synchronized (mUserProfileGroupIdsSelfLocked) {
1241 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001242 final List<UserInfo> users = getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001243 for (int i = 0; i < users.size(); i++) {
1244 UserInfo user = users.get(i);
1245 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1246 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1247 }
1248 }
1249 }
1250 }
1251
1252 int[] getStartedUserArrayLocked() {
1253 return mStartedUserArray;
1254 }
1255
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001256 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001257 UserState state = getStartedUserStateLocked(userId);
1258 if (state == null) {
1259 return false;
1260 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001261 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001262 return true;
1263 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001264
1265 final boolean unlocked;
1266 switch (state.state) {
1267 case UserState.STATE_STOPPING:
1268 case UserState.STATE_SHUTDOWN:
1269 default:
1270 return false;
1271
1272 case UserState.STATE_BOOTING:
1273 case UserState.STATE_RUNNING_LOCKED:
1274 unlocked = false;
1275 break;
1276
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001277 case UserState.STATE_RUNNING_UNLOCKING:
1278 case UserState.STATE_RUNNING_UNLOCKED:
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001279 unlocked = true;
1280 break;
Jeff Sharkey0825ab22015-12-02 13:04:49 -07001281 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001282
1283 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
1284 return !unlocked;
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001285 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001286 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
1287 return unlocked;
1288 }
1289
1290 // One way or another, we're running!
1291 return true;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001292 }
1293
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001294 UserInfo getCurrentUser() {
1295 if ((mService.checkCallingPermission(INTERACT_ACROSS_USERS)
1296 != PackageManager.PERMISSION_GRANTED) && (
1297 mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1298 != PackageManager.PERMISSION_GRANTED)) {
1299 String msg = "Permission Denial: getCurrentUser() from pid="
1300 + Binder.getCallingPid()
1301 + ", uid=" + Binder.getCallingUid()
1302 + " requires " + INTERACT_ACROSS_USERS;
1303 Slog.w(TAG, msg);
1304 throw new SecurityException(msg);
1305 }
1306 synchronized (mService) {
1307 return getCurrentUserLocked();
1308 }
1309 }
1310
1311 UserInfo getCurrentUserLocked() {
1312 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001313 return getUserInfo(userId);
1314 }
1315
1316 int getCurrentOrTargetUserIdLocked() {
1317 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001318 }
1319
1320 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001321 return mCurrentUserId;
1322 }
1323
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001324 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001325 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001326 }
1327
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001328 int setTargetUserIdLocked(int targetUserId) {
1329 return mTargetUserId = targetUserId;
1330 }
1331
1332 int[] getUsers() {
1333 UserManagerService ums = getUserManager();
1334 return ums != null ? ums.getUserIds() : new int[] { 0 };
1335 }
1336
1337 UserInfo getUserInfo(int userId) {
1338 return getUserManager().getUserInfo(userId);
1339 }
1340
1341 int[] getUserIds() {
1342 return getUserManager().getUserIds();
1343 }
1344
1345 boolean exists(int userId) {
1346 return getUserManager().exists(userId);
1347 }
1348
1349 boolean hasUserRestriction(String restriction, int userId) {
1350 return getUserManager().hasUserRestriction(restriction, userId);
1351 }
1352
1353 Set<Integer> getProfileIds(int userId) {
1354 Set<Integer> userIds = new HashSet<>();
1355 final List<UserInfo> profiles = getUserManager().getProfiles(userId,
1356 false /* enabledOnly */);
1357 for (UserInfo user : profiles) {
1358 userIds.add(user.id);
1359 }
1360 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001361 }
1362
1363 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
1364 synchronized (mUserProfileGroupIdsSelfLocked) {
1365 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1366 UserInfo.NO_PROFILE_GROUP_ID);
1367 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1368 UserInfo.NO_PROFILE_GROUP_ID);
1369 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1370 && callingProfile == targetProfile;
1371 }
1372 }
1373
1374 boolean isCurrentProfileLocked(int userId) {
1375 return ArrayUtils.contains(mCurrentProfileIds, userId);
1376 }
1377
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001378 int[] getCurrentProfileIdsLocked() {
1379 return mCurrentProfileIds;
1380 }
1381
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001382 /**
1383 * Returns whether the given user requires credential entry at this time. This is used to
1384 * intercept activity launches for work apps when the Work Challenge is present.
1385 */
1386 boolean shouldConfirmCredentials(int userId) {
Rubin Xub93522a2016-02-23 18:21:48 +00001387 synchronized (mService) {
1388 if (mStartedUsers.get(userId) == null) {
1389 return false;
1390 }
1391 }
Clara Bayarria1771112015-12-18 16:29:18 +00001392 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001393 return false;
1394 }
1395 final KeyguardManager km = (KeyguardManager) mService.mContext
1396 .getSystemService(KEYGUARD_SERVICE);
Clara Bayarria1771112015-12-18 16:29:18 +00001397 return km.isDeviceLocked(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001398 }
1399
Tony Mak8c536f92016-03-21 12:20:41 +00001400 boolean isLockScreenDisabled(@UserIdInt int userId) {
1401 return mLockPatternUtils.isLockScreenDisabled(userId);
1402 }
1403
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001404 void dump(PrintWriter pw, boolean dumpAll) {
1405 pw.println(" mStartedUsers:");
1406 for (int i = 0; i < mStartedUsers.size(); i++) {
1407 UserState uss = mStartedUsers.valueAt(i);
1408 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1409 pw.print(": "); uss.dump("", pw);
1410 }
1411 pw.print(" mStartedUserArray: [");
1412 for (int i = 0; i < mStartedUserArray.length; i++) {
1413 if (i > 0) pw.print(", ");
1414 pw.print(mStartedUserArray[i]);
1415 }
1416 pw.println("]");
1417 pw.print(" mUserLru: [");
1418 for (int i = 0; i < mUserLru.size(); i++) {
1419 if (i > 0) pw.print(", ");
1420 pw.print(mUserLru.get(i));
1421 }
1422 pw.println("]");
1423 if (dumpAll) {
1424 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1425 }
1426 synchronized (mUserProfileGroupIdsSelfLocked) {
1427 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1428 pw.println(" mUserProfileGroupIds:");
1429 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1430 pw.print(" User #");
1431 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1432 pw.print(" -> profile #");
1433 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1434 }
1435 }
1436 }
1437 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001438}