blob: cdb68d8aeff6b30850d21104d56f721b7f741cfb [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;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060066import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070067import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070068import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070069import android.os.Process;
70import android.os.RemoteCallbackList;
71import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070072import android.os.ServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070073import android.os.UserHandle;
74import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010075import android.os.UserManagerInternal;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080076import android.os.storage.IMountService;
77import android.os.storage.StorageManager;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070078import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080079import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070080import android.util.Slog;
81import android.util.SparseArray;
82import android.util.SparseIntArray;
83
84import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080085import com.android.internal.annotations.GuardedBy;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070086import com.android.internal.util.ArrayUtils;
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;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600104
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700105 // Maximum number of users we allow to be running at a time.
106 static final int MAX_RUNNING_USERS = 3;
107
108 // Amount of time we wait for observers to handle a user switch before
109 // giving up on them and unfreezing the screen.
110 static final int USER_SWITCH_TIMEOUT = 2 * 1000;
111
112 private final ActivityManagerService mService;
113 private final Handler mHandler;
114
115 // Holds the current foreground user's id
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700116 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700117 // Holds the target user's id during a user switch
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700118 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700119
120 /**
121 * Which users have been started, so are allowed to run code.
122 */
Jeff Sharkeyba512352015-11-12 20:17:45 -0800123 @GuardedBy("mService")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700124 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800125
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700126 /**
127 * LRU list of history of current users. Most recently current is at the end.
128 */
129 private final ArrayList<Integer> mUserLru = new ArrayList<>();
130
131 /**
132 * Constant array of the users that are currently started.
133 */
134 private int[] mStartedUserArray = new int[] { 0 };
135
136 // If there are multiple profiles for the current user, their ids are here
137 // Currently only the primary user can have managed profiles
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700138 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700139
140 /**
141 * Mapping from each known user ID to the profile group ID it is associated with.
142 */
143 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
144
145 /**
146 * Registered observers of the user switching mechanics.
147 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700148 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700149 = new RemoteCallbackList<>();
150
151 /**
152 * Currently active user switch.
153 */
154 Object mCurUserSwitchCallback;
155
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700156 private volatile UserManagerService mUserManager;
157
Clara Bayarria1771112015-12-18 16:29:18 +0000158 private final LockPatternUtils mLockPatternUtils;
159
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700160 UserController(ActivityManagerService service) {
161 mService = service;
162 mHandler = mService.mHandler;
163 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800164 final UserState uss = new UserState(UserHandle.SYSTEM);
165 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700166 mUserLru.add(UserHandle.USER_SYSTEM);
Clara Bayarria1771112015-12-18 16:29:18 +0000167 mLockPatternUtils = new LockPatternUtils(mService.mContext);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700168 updateStartedUserArrayLocked();
169 }
170
171 void finishUserSwitch(UserState uss) {
172 synchronized (mService) {
173 finishUserBoot(uss);
174
175 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700176 stopRunningUsersLocked(MAX_RUNNING_USERS);
177 }
178 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700179
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700180 void stopRunningUsersLocked(int maxRunningUsers) {
181 int num = mUserLru.size();
182 int i = 0;
183 while (num > maxRunningUsers && i < mUserLru.size()) {
184 Integer oldUserId = mUserLru.get(i);
185 UserState oldUss = mStartedUsers.get(oldUserId);
186 if (oldUss == null) {
187 // Shouldn't happen, but be sane if it does.
188 mUserLru.remove(i);
189 num--;
190 continue;
191 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700192 if (oldUss.state == UserState.STATE_STOPPING
193 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700194 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700195 num--;
196 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700197 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700198 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700199 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
200 // Owner/System user and current user can't be stopped. We count it as running
201 // when it is not a pure system user.
202 if (UserInfo.isSystemOnly(oldUserId)) {
203 num--;
204 }
205 i++;
206 continue;
207 }
208 // This is a user to be stopped.
209 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
210 num--;
211 }
212 num--;
213 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700214 }
215 }
216
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800217 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700218 finishUserBoot(uss, null);
219 }
220
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800221 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700222 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700223 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700224 synchronized (mService) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700225 // Bail if we ended up with a stale user
226 if (mStartedUsers.get(userId) != uss) return;
227
228 // We always walk through all the user lifecycle states to send
229 // consistent developer events. We step into RUNNING_LOCKED here,
230 // but we might immediately step into RUNNING below if the user
231 // storage is already unlocked.
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600232 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700233 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700234 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700235 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
236 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700237 mService.broadcastIntentLocked(null, null, intent, null, resultTo, 0, null, null,
238 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
239 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
240 }
241
Jeff Sharkey7661a312016-04-07 12:39:57 -0600242 // We need to delay unlocking managed profiles until the parent user
243 // is also unlocked.
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600244 if (getUserManager().isManagedProfile(userId)) {
Jeff Sharkey7661a312016-04-07 12:39:57 -0600245 final UserInfo parent = getUserManager().getProfileParent(userId);
246 if (parent != null
247 && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
248 Slog.d(TAG, "User " + userId + " (parent " + parent.id
249 + "): attempting unlock because parent is unlocked");
250 maybeUnlockUser(userId);
251 } else {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700252 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
253 Slog.d(TAG, "User " + userId + " (parent " + parentId
Jeff Sharkey7661a312016-04-07 12:39:57 -0600254 + "): delaying unlock because parent is locked");
255 }
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600256 } else {
257 maybeUnlockUser(userId);
258 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700259 }
260 }
261
262 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600263 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
264 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700265 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600266 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700267 final int userId = uss.mHandle.getIdentifier();
268 synchronized (mService) {
269 // Bail if we ended up with a stale user
270 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
271
272 // Only keep marching forward if user is actually unlocked
273 if (!isUserKeyUnlocked(userId)) return;
274
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600275 if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600276 uss.mUnlockProgress.start();
277
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600278 // Prepare app storage before we go any further
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600279 uss.mUnlockProgress.setProgress(5,
280 mService.mContext.getString(R.string.android_start_title));
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700281 mUserManager.onBeforeUnlockUser(userId);
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600282 uss.mUnlockProgress.setProgress(20);
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700283
Jeff Sharkey083807d2016-04-06 14:07:09 -0600284 // Dispatch unlocked to system services
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600285 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss.mUnlockProgress)
286 .sendToTarget();
Jeff Sharkey083807d2016-04-06 14:07:09 -0600287
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600288 // Dispatch unlocked to external apps
289 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
290 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
291 unlockedIntent.addFlags(
292 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
293 mService.broadcastIntentLocked(null, null, unlockedIntent, null, null, 0, null,
294 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
295 userId);
296
297 if (getUserInfo(userId).isManagedProfile()) {
298 UserInfo parent = getUserManager().getProfileParent(userId);
299 if (parent != null) {
300 final Intent profileUnlockedIntent = new Intent(
301 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
302 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
303 profileUnlockedIntent.addFlags(
304 Intent.FLAG_RECEIVER_REGISTERED_ONLY
305 | Intent.FLAG_RECEIVER_FOREGROUND);
306 mService.broadcastIntentLocked(null, null, profileUnlockedIntent,
307 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
308 null, false, false, MY_PID, SYSTEM_UID,
309 parent.id);
310 }
311 }
312
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600313 // Send PRE_BOOT broadcasts if fingerprint changed
314 final UserInfo info = getUserInfo(userId);
315 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600316 new PreBootBroadcaster(mService, userId, null) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600317 @Override
318 public void onFinished() {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600319 finishUserUnlocked(uss);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600320 }
321 }.sendNext();
322 } else {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600323 finishUserUnlocked(uss);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600324 }
325 }
326 }
327 }
328
329 /**
330 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
331 * {@link UserState#STATE_RUNNING_UNLOCKED}.
332 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600333 private void finishUserUnlocked(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600334 final int userId = uss.mHandle.getIdentifier();
335 synchronized (mService) {
336 // Bail if we ended up with a stale user
337 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700338 final UserInfo userInfo = getUserInfo(userId);
339 if (userInfo == null) {
340 return;
341 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600342
343 // Only keep marching forward if user is actually unlocked
344 if (!isUserKeyUnlocked(userId)) return;
345
346 if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
347 // Remember that we logged in
348 mUserManager.onUserLoggedIn(userId);
349
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700350 if (!userInfo.isInitialized()) {
351 if (userId != UserHandle.USER_SYSTEM) {
352 Slog.d(TAG, "Initializing user #" + userId);
353 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
354 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
355 mService.broadcastIntentLocked(null, null, intent, null,
356 new IIntentReceiver.Stub() {
357 @Override
358 public void performReceive(Intent intent, int resultCode,
359 String data, Bundle extras, boolean ordered,
360 boolean sticky, int sendingUser) {
361 // Note: performReceive is called with mService lock held
362 getUserManager().makeInitialized(userInfo.id);
363 }
364 }, 0, null, null, null, AppOpsManager.OP_NONE,
365 null, true, false, MY_PID, SYSTEM_UID, userId);
366 }
367 }
368 Slog.d(TAG, "Sending BOOT_COMPLETE user #" + userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700369 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
370 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800371 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
372 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700373 mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0, null, null,
374 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700375 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700376 }
377 }
378 }
379
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700380 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700381 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
382 != PackageManager.PERMISSION_GRANTED) {
383 String msg = "Permission Denial: switchUser() from pid="
384 + Binder.getCallingPid()
385 + ", uid=" + Binder.getCallingUid()
386 + " requires " + INTERACT_ACROSS_USERS_FULL;
387 Slog.w(TAG, msg);
388 throw new SecurityException(msg);
389 }
390 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
391 throw new IllegalArgumentException("Can't stop system user " + userId);
392 }
393 mService.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
394 userId);
395 synchronized (mService) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700396 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700397 }
398 }
399
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700400 /**
401 * Stops the user along with its related users. The method calls
402 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
403 */
404 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
405 if (userId == UserHandle.USER_SYSTEM) {
406 return USER_OP_ERROR_IS_SYSTEM;
407 }
408 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700409 return USER_OP_IS_CURRENT;
410 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700411 int[] usersToStop = getUsersToStopLocked(userId);
412 // If one of related users is system or current, no related users should be stopped
413 for (int i = 0; i < usersToStop.length; i++) {
414 int relatedUserId = usersToStop[i];
415 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
416 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
417 + relatedUserId);
418 // We still need to stop the requested user if it's a force stop.
419 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800420 Slog.i(TAG,
421 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700422 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800423 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700424 }
425 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
426 }
427 }
428 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
429 for (int userIdToStop : usersToStop) {
430 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
431 }
432 return USER_OP_SUCCESS;
433 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700434
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700435 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
436 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700437 final UserState uss = mStartedUsers.get(userId);
438 if (uss == null) {
439 // User is not started, nothing to do... but we do need to
440 // callback if requested.
441 if (callback != null) {
442 mHandler.post(new Runnable() {
443 @Override
444 public void run() {
445 try {
446 callback.userStopped(userId);
447 } catch (RemoteException e) {
448 }
449 }
450 });
451 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700452 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700453 }
454
455 if (callback != null) {
456 uss.mStopCallbacks.add(callback);
457 }
458
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700459 if (uss.state != UserState.STATE_STOPPING
460 && uss.state != UserState.STATE_SHUTDOWN) {
461 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700462 updateStartedUserArrayLocked();
463
464 long ident = Binder.clearCallingIdentity();
465 try {
466 // We are going to broadcast ACTION_USER_STOPPING and then
467 // once that is done send a final ACTION_SHUTDOWN and then
468 // stop the user.
469 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
470 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
471 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
472 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700473 // This is the result receiver for the initial stopping broadcast.
474 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
475 @Override
476 public void performReceive(Intent intent, int resultCode, String data,
477 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700478 mHandler.post(new Runnable() {
479 @Override
480 public void run() {
481 finishUserStopping(userId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700482 }
Amith Yamasani98c05562016-03-30 13:15:26 -0700483 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700484 }
485 };
486 // Kick things off.
487 mService.broadcastIntentLocked(null, null, stoppingIntent,
488 null, stoppingReceiver, 0, null, null,
489 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700490 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700491 } finally {
492 Binder.restoreCallingIdentity(ident);
493 }
494 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700495 }
496
Amith Yamasani98c05562016-03-30 13:15:26 -0700497 void finishUserStopping(final int userId, final UserState uss) {
498 // On to the next.
499 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
500 // This is the result receiver for the final shutdown broadcast.
501 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
502 @Override
503 public void performReceive(Intent intent, int resultCode, String data,
504 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
505 mHandler.post(new Runnable() {
506 @Override
507 public void run() {
508 finishUserStopped(uss);
509 }
510 });
511 }
512 };
513
514 synchronized (mService) {
515 if (uss.state != UserState.STATE_STOPPING) {
516 // Whoops, we are being started back up. Abort, abort!
517 return;
518 }
519 uss.setState(UserState.STATE_SHUTDOWN);
520 }
521
522 mService.mBatteryStatsService.noteEvent(
523 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
524 Integer.toString(userId), userId);
525 mService.mSystemServiceManager.stopUser(userId);
526
527 synchronized (mService) {
528 mService.broadcastIntentLocked(null, null, shutdownIntent,
529 null, shutdownReceiver, 0, null, null, null,
530 AppOpsManager.OP_NONE,
531 null, true, false, MY_PID, SYSTEM_UID, userId);
532 }
533 }
534
535 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700536 final int userId = uss.mHandle.getIdentifier();
537 boolean stopped;
538 ArrayList<IStopUserCallback> callbacks;
539 synchronized (mService) {
540 callbacks = new ArrayList<>(uss.mStopCallbacks);
541 if (mStartedUsers.get(userId) != uss) {
542 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700543 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700544 stopped = false;
545 } else {
546 stopped = true;
547 // User can no longer run.
548 mStartedUsers.remove(userId);
549 mUserLru.remove(Integer.valueOf(userId));
550 updateStartedUserArrayLocked();
551
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800552 mService.onUserStoppedLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700553 // Clean up all state and processes associated with the user.
554 // Kill all the processes for the user.
555 forceStopUserLocked(userId, "finish user");
556 }
557 }
558
559 for (int i = 0; i < callbacks.size(); i++) {
560 try {
561 if (stopped) callbacks.get(i).userStopped(userId);
562 else callbacks.get(i).userStopAborted(userId);
563 } catch (RemoteException e) {
564 }
565 }
566
567 if (stopped) {
568 mService.mSystemServiceManager.cleanupUser(userId);
569 synchronized (mService) {
570 mService.mStackSupervisor.removeUserLocked(userId);
571 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100572 // Remove the user if it is ephemeral.
573 if (getUserInfo(userId).isEphemeral()) {
574 mUserManager.removeUser(userId);
575 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700576 }
577 }
578
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700579 /**
580 * Determines the list of users that should be stopped together with the specified
581 * {@code userId}. The returned list includes {@code userId}.
582 */
583 private @NonNull int[] getUsersToStopLocked(int userId) {
584 int startedUsersSize = mStartedUsers.size();
585 IntArray userIds = new IntArray();
586 userIds.add(userId);
587 synchronized (mUserProfileGroupIdsSelfLocked) {
588 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
589 UserInfo.NO_PROFILE_GROUP_ID);
590 for (int i = 0; i < startedUsersSize; i++) {
591 UserState uss = mStartedUsers.valueAt(i);
592 int startedUserId = uss.mHandle.getIdentifier();
593 // Skip unrelated users (profileGroupId mismatch)
594 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
595 UserInfo.NO_PROFILE_GROUP_ID);
596 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
597 && (userGroupId == startedUserGroupId);
598 // userId has already been added
599 boolean sameUserId = startedUserId == userId;
600 if (!sameGroup || sameUserId) {
601 continue;
602 }
603 userIds.add(startedUserId);
604 }
605 }
606 return userIds.toArray();
607 }
608
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700609 private void forceStopUserLocked(int userId, String reason) {
610 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
611 userId, reason);
612 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
614 | Intent.FLAG_RECEIVER_FOREGROUND);
615 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
616 mService.broadcastIntentLocked(null, null, intent,
617 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700618 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700619 }
620
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700621 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100622 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700623 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100624 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700625 synchronized (mService) {
626 final int num = mUserLru.size();
627 for (int i = 0; i < num; i++) {
628 Integer oldUserId = mUserLru.get(i);
629 UserState oldUss = mStartedUsers.get(oldUserId);
630 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700631 || oldUss.state == UserState.STATE_STOPPING
632 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700633 continue;
634 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700635 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100636 if (userInfo.isEphemeral()) {
637 LocalServices.getService(UserManagerInternal.class)
638 .onEphemeralUserStop(oldUserId);
639 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100640 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700641 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700642 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700643 break;
644 }
645 }
646 }
647 }
648
649 void startProfilesLocked() {
650 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700651 List<UserInfo> profiles = getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700652 mCurrentUserId, false /* enabledOnly */);
653 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
654 for (UserInfo user : profiles) {
655 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000656 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700657 profilesToStart.add(user);
658 }
659 }
660 final int profilesToStartSize = profilesToStart.size();
661 int i = 0;
662 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
663 startUser(profilesToStart.get(i).id, /* foreground= */ false);
664 }
665 if (i < profilesToStartSize) {
666 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
667 }
668 }
669
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700670 private UserManagerService getUserManager() {
671 UserManagerService userManager = mUserManager;
672 if (userManager == null) {
673 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
674 userManager = mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
675 }
676 return userManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700677 }
678
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700679 private IMountService getMountService() {
680 return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
681 }
682
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700683 private boolean isUserKeyUnlocked(int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700684 final IMountService mountService = getMountService();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800685 if (mountService != null) {
686 try {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700687 return mountService.isUserKeyUnlocked(userId);
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800688 } catch (RemoteException e) {
689 throw e.rethrowAsRuntimeException();
690 }
691 } else {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700692 Slog.w(TAG, "Mount service not published; guessing locked state based on property");
Paul Lawrence20be5d62016-02-26 13:51:17 -0800693 return !StorageManager.isFileEncryptedNativeOrEmulated();
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800694 }
695 }
696
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700697 /**
698 * Start user, if its not already running.
699 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
700 * When starting the user, multiple intents will be broadcast in the following order:</p>
701 * <ul>
702 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
703 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
704 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
705 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
706 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
707 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
708 * Sent only if {@code foreground} parameter is true
709 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
710 * of the new fg user
711 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
712 * the new user
713 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
714 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
715 * new user. Sent only when the user is booting after a system update.
716 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
717 * new user. Sent only the first time a user is starting.
718 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
719 * user. Indicates that the user has finished booting.
720 * </ul>
721 *
722 * @param userId ID of the user to start
723 * @param foreground true if user should be brought to the foreground
724 * @return true if the user has been successfully started
725 */
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 boolean startUser(final int userId, final boolean foreground) {
727 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
728 != PackageManager.PERMISSION_GRANTED) {
729 String msg = "Permission Denial: switchUser() from pid="
730 + Binder.getCallingPid()
731 + ", uid=" + Binder.getCallingUid()
732 + " requires " + INTERACT_ACROSS_USERS_FULL;
733 Slog.w(TAG, msg);
734 throw new SecurityException(msg);
735 }
736
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700737 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700738
739 final long ident = Binder.clearCallingIdentity();
740 try {
741 synchronized (mService) {
742 final int oldUserId = mCurrentUserId;
743 if (oldUserId == userId) {
744 return true;
745 }
746
747 mService.mStackSupervisor.setLockTaskModeLocked(null,
748 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
749
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700750 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700751 if (userInfo == null) {
752 Slog.w(TAG, "No user info for user #" + userId);
753 return false;
754 }
755 if (foreground && userInfo.isManagedProfile()) {
756 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
757 return false;
758 }
759
760 if (foreground) {
761 mService.mWindowManager.startFreezingScreen(
762 R.anim.screen_user_exit, R.anim.screen_user_enter);
763 }
764
765 boolean needStart = false;
766
767 // If the user we are switching to is not currently started, then
768 // we need to start it now.
769 if (mStartedUsers.get(userId) == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700770 mStartedUsers.put(userId, new UserState(UserHandle.of(userId)));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700771 updateStartedUserArrayLocked();
772 needStart = true;
773 }
774
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800775 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700776 final Integer userIdInt = userId;
777 mUserLru.remove(userIdInt);
778 mUserLru.add(userIdInt);
779
780 if (foreground) {
781 mCurrentUserId = userId;
782 mService.updateUserConfigurationLocked();
783 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
784 updateCurrentProfileIdsLocked();
785 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
786 // Once the internal notion of the active user has switched, we lock the device
787 // with the option to show the user switcher on the keyguard.
788 mService.mWindowManager.lockNow(null);
789 } else {
790 final Integer currentUserIdInt = mCurrentUserId;
791 updateCurrentProfileIdsLocked();
792 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
793 mUserLru.remove(currentUserIdInt);
794 mUserLru.add(currentUserIdInt);
795 }
796
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700797 // Make sure user is in the started state. If it is currently
798 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700799 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700800 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
801 // so we can just fairly silently bring the user back from
802 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700803 uss.setState(uss.lastState);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700804 updateStartedUserArrayLocked();
805 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700806 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700807 // This means ACTION_SHUTDOWN has been sent, so we will
808 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700809 uss.setState(UserState.STATE_BOOTING);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700810 updateStartedUserArrayLocked();
811 needStart = true;
812 }
813
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700814 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700815 // Give user manager a chance to propagate user restrictions
816 // to other services and prepare app storage
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800817 getUserManager().onBeforeStartUser(userId);
818
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700819 // Booting up a new user, need to tell system services about it.
820 // Note that this is on the same handler as scheduling of broadcasts,
821 // which is important because it needs to go first.
822 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
823 }
824
825 if (foreground) {
826 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
827 oldUserId));
828 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
829 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
830 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
831 oldUserId, userId, uss));
832 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
833 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
834 }
835
836 if (needStart) {
837 // Send USER_STARTED broadcast
838 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
839 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
840 | Intent.FLAG_RECEIVER_FOREGROUND);
841 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
842 mService.broadcastIntentLocked(null, null, intent,
843 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700844 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700845 }
846
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700847 if (foreground) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700848 moveUserToForegroundLocked(uss, oldUserId, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700849 } else {
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800850 mService.mUserController.finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700851 }
852
853 if (needStart) {
854 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
855 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
856 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
857 mService.broadcastIntentLocked(null, null, intent,
858 null, new IIntentReceiver.Stub() {
859 @Override
860 public void performReceive(Intent intent, int resultCode,
861 String data, Bundle extras, boolean ordered, boolean sticky,
862 int sendingUser) throws RemoteException {
863 }
864 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700865 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
866 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700867 }
868 }
869 } finally {
870 Binder.restoreCallingIdentity(ident);
871 }
872
873 return true;
874 }
875
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700876 /**
877 * Start user, if its not already running, and bring it to foreground.
878 */
879 boolean startUserInForeground(final int userId, Dialog dlg) {
880 boolean result = startUser(userId, /* foreground */ true);
881 dlg.dismiss();
882 return result;
883 }
884
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600885 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Jeff Sharkeyba512352015-11-12 20:17:45 -0800886 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
887 != PackageManager.PERMISSION_GRANTED) {
888 String msg = "Permission Denial: unlockUser() from pid="
889 + Binder.getCallingPid()
890 + ", uid=" + Binder.getCallingUid()
891 + " requires " + INTERACT_ACROSS_USERS_FULL;
892 Slog.w(TAG, msg);
893 throw new SecurityException(msg);
894 }
895
Jeff Sharkey8924e872015-11-30 12:52:10 -0700896 final long binderToken = Binder.clearCallingIdentity();
897 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600898 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700899 } finally {
900 Binder.restoreCallingIdentity(binderToken);
901 }
902 }
903
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700904 /**
905 * Attempt to unlock user without a credential token. This typically
906 * succeeds when the device doesn't have credential-encrypted storage, or
907 * when the the credential-encrypted storage isn't tied to a user-provided
908 * PIN or pattern.
909 */
910 boolean maybeUnlockUser(final int userId) {
911 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600912 return unlockUserCleared(userId, null, null, null);
913 }
914
915 private static void notifyFinished(int userId, IProgressListener listener) {
916 if (listener == null) return;
917 try {
918 listener.onFinished(userId, null);
919 } catch (RemoteException ignored) {
920 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700921 }
922
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600923 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600924 IProgressListener listener) {
925 final UserState uss;
Jeff Sharkey8924e872015-11-30 12:52:10 -0700926 synchronized (mService) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600927 // Bail if user isn't actually running, otherwise register the given
928 // listener to watch for unlock progress
929 uss = mStartedUsers.get(userId);
Ricky Waif6ef8282016-04-14 10:00:22 +0100930 if (uss == null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600931 notifyFinished(userId, listener);
Ricky Waif6ef8282016-04-14 10:00:22 +0100932 return false;
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600933 } else {
934 uss.mUnlockProgress.addListener(listener);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600935 }
Jeff Sharkey8924e872015-11-30 12:52:10 -0700936 }
937
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700938 if (!isUserKeyUnlocked(userId)) {
939 final UserInfo userInfo = getUserInfo(userId);
940 final IMountService mountService = getMountService();
941 try {
Paul Crowleyfaeb3eb2016-02-08 15:58:29 +0000942 mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700943 } catch (RemoteException | RuntimeException e) {
944 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600945 notifyFinished(userId, listener);
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700946 return false;
947 }
Jeff Sharkeyba512352015-11-12 20:17:45 -0800948 }
949
950 synchronized (mService) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600951 finishUserUnlocking(uss);
Jeff Sharkeyba512352015-11-12 20:17:45 -0800952
Jeff Sharkey7661a312016-04-07 12:39:57 -0600953 // We just unlocked a user, so let's now attempt to unlock any
954 // managed profiles under that user.
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600955 for (int i = 0; i < mStartedUsers.size(); i++) {
956 final int testUserId = mStartedUsers.keyAt(i);
957 final UserInfo parent = getUserManager().getProfileParent(testUserId);
958 if (parent != null && parent.id == userId && testUserId != userId) {
Jeff Sharkey7661a312016-04-07 12:39:57 -0600959 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
960 + "): attempting unlock because parent was just unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600961 maybeUnlockUser(testUserId);
962 }
963 }
964 }
965
Jeff Sharkeyba512352015-11-12 20:17:45 -0800966 return true;
967 }
968
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800969 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700970 // The dialog will show and then initiate the user switch by calling startUserInForeground
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800971 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromToUserPair.first,
972 fromToUserPair.second, true /* above system */);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700973 d.show();
974 }
975
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700976 void dispatchForegroundProfileChanged(int userId) {
977 final int observerCount = mUserSwitchObservers.beginBroadcast();
978 for (int i = 0; i < observerCount; i++) {
979 try {
980 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
981 } catch (RemoteException e) {
982 // Ignore
983 }
984 }
985 mUserSwitchObservers.finishBroadcast();
986 }
987
988 /** Called on handler thread */
989 void dispatchUserSwitchComplete(int userId) {
990 final int observerCount = mUserSwitchObservers.beginBroadcast();
991 for (int i = 0; i < observerCount; i++) {
992 try {
993 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
994 } catch (RemoteException e) {
995 }
996 }
997 mUserSwitchObservers.finishBroadcast();
998 }
999
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001000 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1001 // Never stop system user
1002 if (oldUserId == UserHandle.USER_SYSTEM) {
1003 return;
1004 }
1005 // For now, only check for user restriction. Additional checks can be added here
1006 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1007 oldUserId);
1008 if (!disallowRunInBg) {
1009 return;
1010 }
1011 synchronized (mService) {
1012 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1013 + " and related users");
1014 stopUsersLocked(oldUserId, false, null);
1015 }
1016 }
1017
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001018 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
1019 synchronized (mService) {
Amith Yamasanica0ac5c2015-11-20 09:44:08 -08001020 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001021 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1022 }
1023 }
1024
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001025 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1026 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001027 final int observerCount = mUserSwitchObservers.beginBroadcast();
1028 if (observerCount > 0) {
1029 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1030 int mCount = 0;
1031 @Override
1032 public void sendResult(Bundle data) throws RemoteException {
1033 synchronized (mService) {
1034 if (mCurUserSwitchCallback == this) {
1035 mCount++;
1036 if (mCount == observerCount) {
1037 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1038 }
1039 }
1040 }
1041 }
1042 };
1043 synchronized (mService) {
1044 uss.switching = true;
1045 mCurUserSwitchCallback = callback;
1046 }
1047 for (int i = 0; i < observerCount; i++) {
1048 try {
1049 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
1050 newUserId, callback);
1051 } catch (RemoteException e) {
1052 }
1053 }
1054 } else {
1055 synchronized (mService) {
1056 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1057 }
1058 }
1059 mUserSwitchObservers.finishBroadcast();
1060 }
1061
1062 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
1063 mCurUserSwitchCallback = null;
1064 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1065 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
1066 oldUserId, newUserId, uss));
1067 }
1068
1069 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001070 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001071 synchronized (mService) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001072 mService.mWindowManager.stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001073 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001074 uss.switching = false;
1075 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1076 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1077 newUserId, 0));
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001078 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001079 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001080 }
1081
1082 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
1083 boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
1084 if (homeInFront) {
1085 mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
1086 } else {
Wale Ogunwaled046a012015-12-24 13:05:59 -08001087 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001088 }
1089 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001090 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
1091 }
1092
1093 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1094 long ident = Binder.clearCallingIdentity();
1095 try {
1096 Intent intent;
1097 if (oldUserId >= 0) {
1098 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
1099 List<UserInfo> profiles = getUserManager().getProfiles(oldUserId, false);
1100 int count = profiles.size();
1101 for (int i = 0; i < count; i++) {
1102 int profileUserId = profiles.get(i).id;
1103 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1104 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1105 | Intent.FLAG_RECEIVER_FOREGROUND);
1106 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
1107 mService.broadcastIntentLocked(null, null, intent,
1108 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1109 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1110 }
1111 }
1112 if (newUserId >= 0) {
1113 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
1114 List<UserInfo> profiles = getUserManager().getProfiles(newUserId, false);
1115 int count = profiles.size();
1116 for (int i = 0; i < count; i++) {
1117 int profileUserId = profiles.get(i).id;
1118 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1120 | Intent.FLAG_RECEIVER_FOREGROUND);
1121 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
1122 mService.broadcastIntentLocked(null, null, intent,
1123 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1124 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1125 }
1126 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1127 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1128 | Intent.FLAG_RECEIVER_FOREGROUND);
1129 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
1130 mService.broadcastIntentLocked(null, null, intent,
1131 null, null, 0, null, null,
1132 new String[] {android.Manifest.permission.MANAGE_USERS},
1133 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1134 UserHandle.USER_ALL);
1135 }
1136 } finally {
1137 Binder.restoreCallingIdentity(ident);
1138 }
1139 }
1140
1141
1142 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1143 int allowMode, String name, String callerPackage) {
1144 final int callingUserId = UserHandle.getUserId(callingUid);
1145 if (callingUserId == userId) {
1146 return userId;
1147 }
1148
1149 // Note that we may be accessing mCurrentUserId outside of a lock...
1150 // shouldn't be a big deal, if this is being called outside
1151 // of a locked context there is intrinsically a race with
1152 // the value the caller will receive and someone else changing it.
1153 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1154 // we will switch to the calling user if access to the current user fails.
1155 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1156
1157 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1158 final boolean allow;
1159 if (mService.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
1160 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1161 // If the caller has this permission, they always pass go. And collect $200.
1162 allow = true;
1163 } else if (allowMode == ALLOW_FULL_ONLY) {
1164 // We require full access, sucks to be you.
1165 allow = false;
1166 } else if (mService.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
1167 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1168 // If the caller does not have either permission, they are always doomed.
1169 allow = false;
1170 } else if (allowMode == ALLOW_NON_FULL) {
1171 // We are blanket allowing non-full access, you lucky caller!
1172 allow = true;
1173 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1174 // We may or may not allow this depending on whether the two users are
1175 // in the same profile.
1176 allow = isSameProfileGroup(callingUserId, targetUserId);
1177 } else {
1178 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1179 }
1180 if (!allow) {
1181 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1182 // In this case, they would like to just execute as their
1183 // owner user instead of failing.
1184 targetUserId = callingUserId;
1185 } else {
1186 StringBuilder builder = new StringBuilder(128);
1187 builder.append("Permission Denial: ");
1188 builder.append(name);
1189 if (callerPackage != null) {
1190 builder.append(" from ");
1191 builder.append(callerPackage);
1192 }
1193 builder.append(" asks to run as user ");
1194 builder.append(userId);
1195 builder.append(" but is calling from user ");
1196 builder.append(UserHandle.getUserId(callingUid));
1197 builder.append("; this requires ");
1198 builder.append(INTERACT_ACROSS_USERS_FULL);
1199 if (allowMode != ALLOW_FULL_ONLY) {
1200 builder.append(" or ");
1201 builder.append(INTERACT_ACROSS_USERS);
1202 }
1203 String msg = builder.toString();
1204 Slog.w(TAG, msg);
1205 throw new SecurityException(msg);
1206 }
1207 }
1208 }
1209 if (!allowAll && targetUserId < 0) {
1210 throw new IllegalArgumentException(
1211 "Call does not support special user #" + targetUserId);
1212 }
1213 // Check shell permission
1214 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1215 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1216 throw new SecurityException("Shell does not have permission to access user "
1217 + targetUserId + "\n " + Debug.getCallers(3));
1218 }
1219 }
1220 return targetUserId;
1221 }
1222
1223 int unsafeConvertIncomingUserLocked(int userId) {
1224 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1225 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001226 }
1227
1228 void registerUserSwitchObserver(IUserSwitchObserver observer) {
1229 if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1230 != PackageManager.PERMISSION_GRANTED) {
1231 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1232 + Binder.getCallingPid()
1233 + ", uid=" + Binder.getCallingUid()
1234 + " requires " + INTERACT_ACROSS_USERS_FULL;
1235 Slog.w(TAG, msg);
1236 throw new SecurityException(msg);
1237 }
1238
1239 mUserSwitchObservers.register(observer);
1240 }
1241
1242 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1243 mUserSwitchObservers.unregister(observer);
1244 }
1245
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001246 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001247 return mStartedUsers.get(userId);
1248 }
1249
1250 boolean hasStartedUserState(int userId) {
1251 return mStartedUsers.get(userId) != null;
1252 }
1253
1254 private void updateStartedUserArrayLocked() {
1255 int num = 0;
1256 for (int i = 0; i < mStartedUsers.size(); i++) {
1257 UserState uss = mStartedUsers.valueAt(i);
1258 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001259 if (uss.state != UserState.STATE_STOPPING
1260 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001261 num++;
1262 }
1263 }
1264 mStartedUserArray = new int[num];
1265 num = 0;
1266 for (int i = 0; i < mStartedUsers.size(); i++) {
1267 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001268 if (uss.state != UserState.STATE_STOPPING
1269 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001270 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001271 }
1272 }
1273 }
1274
1275 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1276 for (int i = 0; i < mStartedUsers.size(); i++) {
1277 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001278 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001279 }
1280 }
1281
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001282 void onSystemReady() {
1283 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001284 }
1285
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001286 /**
1287 * Refreshes the list of users related to the current user when either a
1288 * user switch happens or when a new related user is started in the
1289 * background.
1290 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001291 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001292 final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001293 false /* enabledOnly */);
1294 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1295 for (int i = 0; i < currentProfileIds.length; i++) {
1296 currentProfileIds[i] = profiles.get(i).id;
1297 }
1298 mCurrentProfileIds = currentProfileIds;
1299
1300 synchronized (mUserProfileGroupIdsSelfLocked) {
1301 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001302 final List<UserInfo> users = getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001303 for (int i = 0; i < users.size(); i++) {
1304 UserInfo user = users.get(i);
1305 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1306 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1307 }
1308 }
1309 }
1310 }
1311
1312 int[] getStartedUserArrayLocked() {
1313 return mStartedUserArray;
1314 }
1315
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001316 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001317 UserState state = getStartedUserStateLocked(userId);
1318 if (state == null) {
1319 return false;
1320 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001321 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001322 return true;
1323 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001324
1325 final boolean unlocked;
1326 switch (state.state) {
1327 case UserState.STATE_STOPPING:
1328 case UserState.STATE_SHUTDOWN:
1329 default:
1330 return false;
1331
1332 case UserState.STATE_BOOTING:
1333 case UserState.STATE_RUNNING_LOCKED:
1334 unlocked = false;
1335 break;
1336
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001337 case UserState.STATE_RUNNING_UNLOCKING:
1338 case UserState.STATE_RUNNING_UNLOCKED:
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001339 unlocked = true;
1340 break;
Jeff Sharkey0825ab22015-12-02 13:04:49 -07001341 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001342
1343 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
1344 return !unlocked;
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001345 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001346 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
1347 return unlocked;
1348 }
1349
1350 // One way or another, we're running!
1351 return true;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001352 }
1353
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001354 UserInfo getCurrentUser() {
1355 if ((mService.checkCallingPermission(INTERACT_ACROSS_USERS)
1356 != PackageManager.PERMISSION_GRANTED) && (
1357 mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
1358 != PackageManager.PERMISSION_GRANTED)) {
1359 String msg = "Permission Denial: getCurrentUser() from pid="
1360 + Binder.getCallingPid()
1361 + ", uid=" + Binder.getCallingUid()
1362 + " requires " + INTERACT_ACROSS_USERS;
1363 Slog.w(TAG, msg);
1364 throw new SecurityException(msg);
1365 }
1366 synchronized (mService) {
1367 return getCurrentUserLocked();
1368 }
1369 }
1370
1371 UserInfo getCurrentUserLocked() {
1372 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001373 return getUserInfo(userId);
1374 }
1375
1376 int getCurrentOrTargetUserIdLocked() {
1377 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001378 }
1379
1380 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001381 return mCurrentUserId;
1382 }
1383
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001384 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001385 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001386 }
1387
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001388 int setTargetUserIdLocked(int targetUserId) {
1389 return mTargetUserId = targetUserId;
1390 }
1391
1392 int[] getUsers() {
1393 UserManagerService ums = getUserManager();
1394 return ums != null ? ums.getUserIds() : new int[] { 0 };
1395 }
1396
1397 UserInfo getUserInfo(int userId) {
1398 return getUserManager().getUserInfo(userId);
1399 }
1400
1401 int[] getUserIds() {
1402 return getUserManager().getUserIds();
1403 }
1404
1405 boolean exists(int userId) {
1406 return getUserManager().exists(userId);
1407 }
1408
1409 boolean hasUserRestriction(String restriction, int userId) {
1410 return getUserManager().hasUserRestriction(restriction, userId);
1411 }
1412
1413 Set<Integer> getProfileIds(int userId) {
1414 Set<Integer> userIds = new HashSet<>();
1415 final List<UserInfo> profiles = getUserManager().getProfiles(userId,
1416 false /* enabledOnly */);
1417 for (UserInfo user : profiles) {
1418 userIds.add(user.id);
1419 }
1420 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001421 }
1422
1423 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
1424 synchronized (mUserProfileGroupIdsSelfLocked) {
1425 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1426 UserInfo.NO_PROFILE_GROUP_ID);
1427 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1428 UserInfo.NO_PROFILE_GROUP_ID);
1429 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1430 && callingProfile == targetProfile;
1431 }
1432 }
1433
1434 boolean isCurrentProfileLocked(int userId) {
1435 return ArrayUtils.contains(mCurrentProfileIds, userId);
1436 }
1437
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001438 int[] getCurrentProfileIdsLocked() {
1439 return mCurrentProfileIds;
1440 }
1441
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001442 /**
1443 * Returns whether the given user requires credential entry at this time. This is used to
1444 * intercept activity launches for work apps when the Work Challenge is present.
1445 */
1446 boolean shouldConfirmCredentials(int userId) {
Rubin Xub93522a2016-02-23 18:21:48 +00001447 synchronized (mService) {
1448 if (mStartedUsers.get(userId) == null) {
1449 return false;
1450 }
1451 }
Clara Bayarria1771112015-12-18 16:29:18 +00001452 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001453 return false;
1454 }
1455 final KeyguardManager km = (KeyguardManager) mService.mContext
1456 .getSystemService(KEYGUARD_SERVICE);
Clara Bayarria1771112015-12-18 16:29:18 +00001457 return km.isDeviceLocked(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001458 }
1459
Tony Mak8c536f92016-03-21 12:20:41 +00001460 boolean isLockScreenDisabled(@UserIdInt int userId) {
1461 return mLockPatternUtils.isLockScreenDisabled(userId);
1462 }
1463
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001464 void dump(PrintWriter pw, boolean dumpAll) {
1465 pw.println(" mStartedUsers:");
1466 for (int i = 0; i < mStartedUsers.size(); i++) {
1467 UserState uss = mStartedUsers.valueAt(i);
1468 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1469 pw.print(": "); uss.dump("", pw);
1470 }
1471 pw.print(" mStartedUserArray: [");
1472 for (int i = 0; i < mStartedUserArray.length; i++) {
1473 if (i > 0) pw.print(", ");
1474 pw.print(mStartedUserArray[i]);
1475 }
1476 pw.println("]");
1477 pw.print(" mUserLru: [");
1478 for (int i = 0; i < mUserLru.size(); i++) {
1479 if (i > 0) pw.print(", ");
1480 pw.print(mUserLru.get(i));
1481 }
1482 pw.println("]");
1483 if (dumpAll) {
1484 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1485 }
1486 synchronized (mUserProfileGroupIdsSelfLocked) {
1487 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1488 pw.println(" mUserProfileGroupIds:");
1489 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1490 pw.print(" User #");
1491 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1492 pw.print(" -> profile #");
1493 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1494 }
1495 }
1496 }
1497 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001498}