blob: fecb93456605aece4e0c1a59f380b719629c5b8c [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;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070025import static android.os.Process.SHELL_UID;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070026import static android.os.Process.SYSTEM_UID;
Tony Mak64fd8c02017-12-01 19:11:59 +000027
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;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060035import static com.android.server.am.UserState.STATE_BOOTING;
36import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
37import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
38import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070039
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070040import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000041import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000042import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070043import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080044import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070045import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070046import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070047import android.app.IStopUserCallback;
48import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000049import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080050import android.app.usage.UsageEvents;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070051import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070052import android.content.IIntentReceiver;
53import android.content.Intent;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080054import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.content.pm.PackageManager;
56import android.content.pm.UserInfo;
57import android.os.BatteryStats;
58import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060059import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070060import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070061import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070062import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070063import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060064import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070065import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070066import android.os.IUserManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070067import android.os.Message;
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;
James Hawkins899608a2016-05-27 11:15:06 -070072import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070073import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070074import android.os.UserHandle;
75import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010076import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080077import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080078import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070079import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070080import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070081import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080082import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070083import android.util.Slog;
84import android.util.SparseArray;
85import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070086import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080087import android.util.proto.ProtoOutputStream;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070088
89import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080090import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070091import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070092import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070093import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070094import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000095import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080096import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010097import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070098import com.android.server.SystemServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070099import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700100import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700101
102import java.io.PrintWriter;
103import java.util.ArrayList;
104import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700105import java.util.HashSet;
Alex Chaub6ef8692018-01-09 14:16:36 +0000106import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700107import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600108import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700109import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700110import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700111
112/**
113 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700114 *
115 * <p>This class use {@link #mLock} to synchronize access to internal state. Methods that require
116 * {@link #mLock} to be held should have "LU" suffix in the name.
117 *
118 * <p><strong>Important:</strong> Synchronized code, i.e. one executed inside a synchronized(mLock)
119 * block or inside LU method, should only access internal state of this class or make calls to
120 * other LU methods. Non-LU method calls or calls to external classes are discouraged as they
121 * may cause lock inversion.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700122 */
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700123class UserController implements Handler.Callback {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700124 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600125
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700126 // Amount of time we wait for observers to handle a user switch before
127 // giving up on them and unfreezing the screen.
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700128 static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
129
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700130 // ActivityManager thread message constants
131 static final int REPORT_USER_SWITCH_MSG = 10;
132 static final int CONTINUE_USER_SWITCH_MSG = 20;
133 static final int USER_SWITCH_TIMEOUT_MSG = 30;
134 static final int START_PROFILES_MSG = 40;
135 static final int SYSTEM_USER_START_MSG = 50;
136 static final int SYSTEM_USER_CURRENT_MSG = 60;
137 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
138 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
139 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
140 static final int SYSTEM_USER_UNLOCK_MSG = 100;
141 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
142 static final int START_USER_SWITCH_FG_MSG = 120;
143
144 // UI thread message constants
145 static final int START_USER_SWITCH_UI_MSG = 1000;
146
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700147 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
148 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
149 // when it never calls back.
150 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700151
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700152 /**
153 * Maximum number of users we allow to be running at a time, including system user.
154 *
155 * <p>This parameter only affects how many background users will be stopped when switching to a
156 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
157 *
158 * <p>Note: Current and system user (and their related profiles) are never stopped when
159 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
160 */
161 int mMaxRunningUsers;
162
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700163 // Lock for internal state.
164 private final Object mLock = new Object();
165
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700166 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700167 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700168 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700169
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700170 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700171 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700172 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
173 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
174 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700175 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700176 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700177
178 /**
179 * Which users have been started, so are allowed to run code.
180 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700181 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700182 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800183
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700184 /**
185 * LRU list of history of current users. Most recently current is at the end.
186 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700187 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700188 private final ArrayList<Integer> mUserLru = new ArrayList<>();
189
190 /**
191 * Constant array of the users that are currently started.
192 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700193 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700194 private int[] mStartedUserArray = new int[] { 0 };
195
196 // If there are multiple profiles for the current user, their ids are here
197 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700198 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700199 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700200
201 /**
202 * Mapping from each known user ID to the profile group ID it is associated with.
203 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700204 @GuardedBy("mLock")
205 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700206
207 /**
208 * Registered observers of the user switching mechanics.
209 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700210 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700211 = new RemoteCallbackList<>();
212
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700213 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700214
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700215 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700216 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700217 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700218 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700219 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700220
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700221 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000222 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
223 */
224 @GuardedBy("mLock")
225 private String mSwitchingFromSystemUserMessage;
226
227 /**
228 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
229 */
230 @GuardedBy("mLock")
231 private String mSwitchingToSystemUserMessage;
232
233 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700234 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
235 */
236 @GuardedBy("mLock")
237 private ArraySet<String> mTimeoutUserSwitchCallbacks;
238
Clara Bayarria1771112015-12-18 16:29:18 +0000239 private final LockPatternUtils mLockPatternUtils;
240
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700241 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700242 this(new Injector(service));
243 }
244
245 @VisibleForTesting
246 UserController(Injector injector) {
247 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700248 mHandler = mInjector.getHandler(this);
249 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700250 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800251 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700252 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800253 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700254 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700255 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700256 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700257 }
258
259 void finishUserSwitch(UserState uss) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700260 finishUserBoot(uss);
261 startProfiles();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700262 synchronized (mLock) {
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700263 stopRunningUsersLU(mMaxRunningUsers);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700264 }
265 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700266
Alex Chaub6ef8692018-01-09 14:16:36 +0000267 List<Integer> getRunningUsersLU() {
268 ArrayList<Integer> runningUsers = new ArrayList<>();
269 for (Integer userId : mUserLru) {
270 UserState uss = mStartedUsers.get(userId);
271 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700272 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700273 continue;
274 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000275 if (uss.state == UserState.STATE_STOPPING
276 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700277 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700278 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700279 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000280 if (userId == UserHandle.USER_SYSTEM) {
281 // We only count system user as running when it is not a pure system user.
282 if (UserInfo.isSystemOnly(userId)) {
283 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700284 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000285 }
286 runningUsers.add(userId);
287 }
288 return runningUsers;
289 }
290
291 void stopRunningUsersLU(int maxRunningUsers) {
292 List<Integer> currentlyRunning = getRunningUsersLU();
293 Iterator<Integer> iterator = currentlyRunning.iterator();
294 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
295 Integer userId = iterator.next();
296 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
297 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700298 continue;
299 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000300 if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
301 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700302 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000303 }
304 }
305
306 /**
307 * Returns if more users can be started without stopping currently running users.
308 */
309 boolean canStartMoreUsers() {
310 synchronized (mLock) {
311 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700312 }
313 }
314
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800315 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700316 finishUserBoot(uss, null);
317 }
318
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800319 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700320 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700321
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700322 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700323 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700324 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700325 if (mStartedUsers.get(userId) != uss) {
326 return;
327 }
328 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700329
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700330 // We always walk through all the user lifecycle states to send
331 // consistent developer events. We step into RUNNING_LOCKED here,
332 // but we might immediately step into RUNNING below if the user
333 // storage is already unlocked.
334 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
335 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
336 // Do not report secondary users, runtime restarts or first boot/upgrade
337 if (userId == UserHandle.USER_SYSTEM
338 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
339 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
340 MetricsLogger.histogram(mInjector.getContext(),
341 "framework_locked_boot_completed", uptimeSeconds);
342 final int MAX_UPTIME_SECONDS = 120;
343 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
344 Slog.wtf("SystemServerTiming",
345 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800346 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700347 }
348
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700349 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
350 userId, 0));
351 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
352 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
353 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
354 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
355 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
356 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
357 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
358 }
359
360 // We need to delay unlocking managed profiles until the parent user
361 // is also unlocked.
362 if (mInjector.getUserManager().isManagedProfile(userId)) {
363 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
364 if (parent != null
365 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
366 Slog.d(TAG, "User " + userId + " (parent " + parent.id
367 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600368 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700369 } else {
370 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
371 Slog.d(TAG, "User " + userId + " (parent " + parentId
372 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600373 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700374 } else {
375 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700376 }
377 }
378
379 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600380 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
381 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700382 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600383 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700384 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700385 // Only keep marching forward if user is actually unlocked
386 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700387 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800388 // Do not proceed if unexpected state or a stale user
389 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700390 return;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600391 }
392 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700393 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200394
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700395 // Prepare app storage before we go any further
396 uss.mUnlockProgress.setProgress(5,
397 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200398
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800399 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
400 FgThread.getHandler().post(() -> {
401 mInjector.getUserManager().onBeforeUnlockUser(userId);
402 synchronized (mLock) {
403 // Do not proceed if unexpected state
404 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
405 return;
406 }
407 }
408 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
409
410 uss.mUnlockProgress.setProgress(20);
411
412 // Dispatch unlocked to system services; when fully dispatched,
413 // that calls through to the next "unlocked" phase
414 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
415 .sendToTarget();
416 });
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600417 }
418
419 /**
420 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
421 * {@link UserState#STATE_RUNNING_UNLOCKED}.
422 */
423 void finishUserUnlocked(final UserState uss) {
424 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700425 // Only keep marching forward if user is actually unlocked
426 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700427 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600428 // Bail if we ended up with a stale user
429 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
430
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700431 // Do not proceed if unexpected state
432 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
433 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600434 }
435 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700436 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
437 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700438
439 // Get unaware persistent apps running and start any unaware providers
440 // in already-running apps that are partially aware
441 if (userId == UserHandle.USER_SYSTEM) {
442 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
443 }
444 mInjector.installEncryptionUnawareProviders(userId);
445
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700446 // Dispatch unlocked to external apps
447 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
448 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
449 unlockedIntent.addFlags(
450 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
451 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
452 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
453 userId);
454
455 if (getUserInfo(userId).isManagedProfile()) {
456 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
457 if (parent != null) {
458 final Intent profileUnlockedIntent = new Intent(
459 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
460 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
461 profileUnlockedIntent.addFlags(
462 Intent.FLAG_RECEIVER_REGISTERED_ONLY
463 | Intent.FLAG_RECEIVER_FOREGROUND);
464 mInjector.broadcastIntent(profileUnlockedIntent,
465 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
466 null, false, false, MY_PID, SYSTEM_UID,
467 parent.id);
468 }
469 }
470
471 // Send PRE_BOOT broadcasts if user fingerprint changed; we
472 // purposefully block sending BOOT_COMPLETED until after all
473 // PRE_BOOT receivers are finished to avoid ANR'ing apps
474 final UserInfo info = getUserInfo(userId);
475 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
476 // Suppress double notifications for managed profiles that
477 // were unlocked automatically as part of their parent user
478 // being unlocked.
479 final boolean quiet;
480 if (info.isManagedProfile()) {
481 quiet = !uss.tokenProvided
482 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
483 } else {
484 quiet = false;
485 }
486 mInjector.sendPreBootBroadcast(userId, quiet,
487 () -> finishUserUnlockedCompleted(uss));
488 } else {
489 finishUserUnlockedCompleted(uss);
490 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600491 }
492
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600493 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600494 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700495 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600496 // Bail if we ended up with a stale user
497 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700498 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700499 UserInfo userInfo = getUserInfo(userId);
500 if (userInfo == null) {
501 return;
502 }
503 // Only keep marching forward if user is actually unlocked
504 if (!StorageManager.isUserKeyUnlocked(userId)) return;
505
506 // Remember that we logged in
507 mInjector.getUserManager().onUserLoggedIn(userId);
508
509 if (!userInfo.isInitialized()) {
510 if (userId != UserHandle.USER_SYSTEM) {
511 Slog.d(TAG, "Initializing user #" + userId);
512 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
513 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
514 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
515 mInjector.broadcastIntent(intent, null,
516 new IIntentReceiver.Stub() {
517 @Override
518 public void performReceive(Intent intent, int resultCode,
519 String data, Bundle extras, boolean ordered,
520 boolean sticky, int sendingUser) {
521 // Note: performReceive is called with mService lock held
522 mInjector.getUserManager().makeInitialized(userInfo.id);
523 }
524 }, 0, null, null, null, AppOpsManager.OP_NONE,
525 null, true, false, MY_PID, SYSTEM_UID, userId);
526 }
527 }
528
529 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
530 // Do not report secondary users, runtime restarts or first boot/upgrade
531 if (userId == UserHandle.USER_SYSTEM
532 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
533 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
534 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
535 uptimeSeconds);
536 }
537 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
538 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
539 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
540 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
541 mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
542 @Override
543 public void performReceive(Intent intent, int resultCode, String data,
544 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
545 throws RemoteException {
546 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
547 }
548 }, 0, null, null,
549 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
550 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700551 }
552
Andrew Scull85a63bc2016-10-24 13:47:47 +0100553 int restartUser(final int userId, final boolean foreground) {
554 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
555 @Override
556 public void userStopped(final int userId) {
557 // Post to the same handler that this callback is called from to ensure the user
558 // cleanup is complete before restarting.
559 mHandler.post(() -> startUser(userId, foreground));
560 }
561 @Override
562 public void userStopAborted(final int userId) {}
563 });
564 }
565
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700566 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700567 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700568 != PackageManager.PERMISSION_GRANTED) {
569 String msg = "Permission Denial: switchUser() from pid="
570 + Binder.getCallingPid()
571 + ", uid=" + Binder.getCallingUid()
572 + " requires " + INTERACT_ACROSS_USERS_FULL;
573 Slog.w(TAG, msg);
574 throw new SecurityException(msg);
575 }
576 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
577 throw new IllegalArgumentException("Can't stop system user " + userId);
578 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700579 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700580 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700581 return stopUsersLU(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700582 }
583 }
584
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700585 /**
586 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700587 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700588 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700589 private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700590 if (userId == UserHandle.USER_SYSTEM) {
591 return USER_OP_ERROR_IS_SYSTEM;
592 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700593 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700594 return USER_OP_IS_CURRENT;
595 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700596 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700597 // If one of related users is system or current, no related users should be stopped
598 for (int i = 0; i < usersToStop.length; i++) {
599 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700600 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700601 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
602 + relatedUserId);
603 // We still need to stop the requested user if it's a force stop.
604 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800605 Slog.i(TAG,
606 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700607 stopSingleUserLU(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800608 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700609 }
610 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
611 }
612 }
613 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
614 for (int userIdToStop : usersToStop) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700615 stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700616 }
617 return USER_OP_SUCCESS;
618 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700619
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700620 private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700621 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700622 final UserState uss = mStartedUsers.get(userId);
623 if (uss == null) {
624 // User is not started, nothing to do... but we do need to
625 // callback if requested.
626 if (callback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700627 mHandler.post(() -> {
628 try {
629 callback.userStopped(userId);
630 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700631 }
632 });
633 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700634 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700635 }
636
637 if (callback != null) {
638 uss.mStopCallbacks.add(callback);
639 }
640
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700641 if (uss.state != UserState.STATE_STOPPING
642 && uss.state != UserState.STATE_SHUTDOWN) {
643 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700644 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700645 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700646
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700647 // Post to handler to obtain amLock
648 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700649 // We are going to broadcast ACTION_USER_STOPPING and then
650 // once that is done send a final ACTION_SHUTDOWN and then
651 // stop the user.
652 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
653 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
654 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
655 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700656 // This is the result receiver for the initial stopping broadcast.
657 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
658 @Override
659 public void performReceive(Intent intent, int resultCode, String data,
660 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700661 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700662 }
663 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700664
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700665 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700666 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700667 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700668 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700669 null, stoppingReceiver, 0, null, null,
670 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700671 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700672 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700673 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700674 }
675
Amith Yamasani98c05562016-03-30 13:15:26 -0700676 void finishUserStopping(final int userId, final UserState uss) {
677 // On to the next.
678 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
679 // This is the result receiver for the final shutdown broadcast.
680 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
681 @Override
682 public void performReceive(Intent intent, int resultCode, String data,
683 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
684 mHandler.post(new Runnable() {
685 @Override
686 public void run() {
687 finishUserStopped(uss);
688 }
689 });
690 }
691 };
692
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700693 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700694 if (uss.state != UserState.STATE_STOPPING) {
695 // Whoops, we are being started back up. Abort, abort!
696 return;
697 }
698 uss.setState(UserState.STATE_SHUTDOWN);
699 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700700 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700701
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700702 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700703 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
704 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700705 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700706
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700707 mInjector.broadcastIntent(shutdownIntent,
708 null, shutdownReceiver, 0, null, null, null,
709 AppOpsManager.OP_NONE,
710 null, true, false, MY_PID, SYSTEM_UID, userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700711 }
712
713 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700714 final int userId = uss.mHandle.getIdentifier();
715 boolean stopped;
716 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700717 boolean forceStopUser = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700718 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700719 callbacks = new ArrayList<>(uss.mStopCallbacks);
720 if (mStartedUsers.get(userId) != uss) {
721 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700722 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700723 stopped = false;
724 } else {
725 stopped = true;
726 // User can no longer run.
727 mStartedUsers.remove(userId);
728 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700729 updateStartedUserArrayLU();
730 forceStopUser = true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700731 }
732 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700733 if (forceStopUser) {
734 mInjector.getUserManagerInternal().removeUserState(userId);
735 mInjector.activityManagerOnUserStopped(userId);
736 // Clean up all state and processes associated with the user.
737 // Kill all the processes for the user.
738 forceStopUser(userId, "finish user");
739 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700740
741 for (int i = 0; i < callbacks.size(); i++) {
742 try {
743 if (stopped) callbacks.get(i).userStopped(userId);
744 else callbacks.get(i).userStopAborted(userId);
745 } catch (RemoteException e) {
746 }
747 }
748
749 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700750 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700751 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100752 // Remove the user if it is ephemeral.
753 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000754 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100755 }
Pavel Grafov0502a4c2017-07-27 17:27:35 +0100756 // Evict the user's credential encryption key.
757 try {
758 getStorageManager().lockUserKey(userId);
759 } catch (RemoteException re) {
760 throw re.rethrowAsRuntimeException();
761 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700762 }
763 }
764
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700765 /**
766 * Determines the list of users that should be stopped together with the specified
767 * {@code userId}. The returned list includes {@code userId}.
768 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700769 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700770 int startedUsersSize = mStartedUsers.size();
771 IntArray userIds = new IntArray();
772 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700773 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
774 for (int i = 0; i < startedUsersSize; i++) {
775 UserState uss = mStartedUsers.valueAt(i);
776 int startedUserId = uss.mHandle.getIdentifier();
777 // Skip unrelated users (profileGroupId mismatch)
778 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700779 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700780 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
781 && (userGroupId == startedUserGroupId);
782 // userId has already been added
783 boolean sameUserId = startedUserId == userId;
784 if (!sameGroup || sameUserId) {
785 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700786 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700787 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700788 }
789 return userIds.toArray();
790 }
791
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700792 private void forceStopUser(int userId, String reason) {
793 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700794 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
795 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
796 | Intent.FLAG_RECEIVER_FOREGROUND);
797 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700798 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700799 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700800 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700801 }
802
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700803 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100804 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700805 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000806 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
807 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000808 synchronized(mLock) {
809 UserState oldUss = mStartedUsers.get(oldUserId);
810 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
811 || oldUss.state == UserState.STATE_STOPPING
812 || oldUss.state == UserState.STATE_SHUTDOWN) {
813 return;
814 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700815 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000816
817 UserInfo userInfo = getUserInfo(oldUserId);
818 if (userInfo.isEphemeral()) {
819 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
820 }
821 if (userInfo.isGuest() || userInfo.isEphemeral()) {
822 // This is a user to be stopped.
823 synchronized (mLock) {
824 stopUsersLU(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700825 }
826 }
827 }
828
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700829 void scheduleStartProfiles() {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700830 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
831 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
832 DateUtils.SECOND_IN_MILLIS);
833 }
834 }
835
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700836 void startProfiles() {
837 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700838 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700839 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700840 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700841 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
842 for (UserInfo user : profiles) {
843 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700844 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700845 profilesToStart.add(user);
846 }
847 }
848 final int profilesToStartSize = profilesToStart.size();
849 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700850 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700851 startUser(profilesToStart.get(i).id, /* foreground= */ false);
852 }
853 if (i < profilesToStartSize) {
854 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
855 }
856 }
857
Sudheer Shanka2250d562016-11-07 15:41:02 -0800858 private IStorageManager getStorageManager() {
859 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700860 }
Tony Mak64fd8c02017-12-01 19:11:59 +0000861 boolean startUser(final int userId, final boolean foreground) {
862 return startUser(userId, foreground, null);
863 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700864
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700865 /**
866 * Start user, if its not already running.
867 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
868 * When starting the user, multiple intents will be broadcast in the following order:</p>
869 * <ul>
870 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
871 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
872 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
873 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
874 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
875 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
876 * Sent only if {@code foreground} parameter is true
877 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
878 * of the new fg user
879 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
880 * the new user
881 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
882 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
883 * new user. Sent only when the user is booting after a system update.
884 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
885 * new user. Sent only the first time a user is starting.
886 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
887 * user. Indicates that the user has finished booting.
888 * </ul>
889 *
890 * @param userId ID of the user to start
891 * @param foreground true if user should be brought to the foreground
892 * @return true if the user has been successfully started
893 */
Tony Mak64fd8c02017-12-01 19:11:59 +0000894 boolean startUser(
895 final int userId,
896 final boolean foreground,
897 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700898 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700899 != PackageManager.PERMISSION_GRANTED) {
900 String msg = "Permission Denial: switchUser() from pid="
901 + Binder.getCallingPid()
902 + ", uid=" + Binder.getCallingUid()
903 + " requires " + INTERACT_ACROSS_USERS_FULL;
904 Slog.w(TAG, msg);
905 throw new SecurityException(msg);
906 }
907
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700908 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700909
910 final long ident = Binder.clearCallingIdentity();
911 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700912 final int oldUserId = getCurrentUserId();
913 if (oldUserId == userId) {
914 return true;
915 }
916
917 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100918 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700919 }
920
921 final UserInfo userInfo = getUserInfo(userId);
922 if (userInfo == null) {
923 Slog.w(TAG, "No user info for user #" + userId);
924 return false;
925 }
926 if (foreground && userInfo.isManagedProfile()) {
927 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
928 return false;
929 }
930
931 if (foreground && mUserSwitchUiEnabled) {
932 mInjector.getWindowManager().startFreezingScreen(
933 R.anim.screen_user_exit, R.anim.screen_user_enter);
934 }
935
936 boolean needStart = false;
937 boolean updateUmState = false;
938 UserState uss;
939
940 // If the user we are switching to is not currently started, then
941 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700942 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700943 uss = mStartedUsers.get(userId);
944 if (uss == null) {
945 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700946 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700947 mStartedUsers.put(userId, uss);
948 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700949 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700950 updateUmState = true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700951 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700952 final Integer userIdInt = userId;
953 mUserLru.remove(userIdInt);
954 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +0000955 }
956 if (unlockListener != null) {
957 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700958 }
959 if (updateUmState) {
960 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
961 }
962 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -0800963 // Make sure the old user is no longer considering the display to be on.
964 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700965 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700966 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700967 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700968 }
969 mInjector.updateUserConfiguration();
970 updateCurrentProfileIds();
971 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -0800972 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700973 // Once the internal notion of the active user has switched, we lock the device
974 // with the option to show the user switcher on the keyguard.
975 if (mUserSwitchUiEnabled) {
976 mInjector.getWindowManager().setSwitchingUser(true);
977 mInjector.getWindowManager().lockNow(null);
978 }
979 } else {
980 final Integer currentUserIdInt = mCurrentUserId;
981 updateCurrentProfileIds();
982 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
983 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700984 mUserLru.remove(currentUserIdInt);
985 mUserLru.add(currentUserIdInt);
986 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700987 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700988
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700989 // Make sure user is in the started state. If it is currently
990 // stopping, we need to knock that off.
991 if (uss.state == UserState.STATE_STOPPING) {
992 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
993 // so we can just fairly silently bring the user back from
994 // the almost-dead.
995 uss.setState(uss.lastState);
996 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
997 synchronized (mLock) {
998 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700999 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001000 needStart = true;
1001 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1002 // This means ACTION_SHUTDOWN has been sent, so we will
1003 // need to treat this as a new boot of the user.
1004 uss.setState(UserState.STATE_BOOTING);
1005 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1006 synchronized (mLock) {
1007 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001008 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001009 needStart = true;
1010 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001011
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001012 if (uss.state == UserState.STATE_BOOTING) {
1013 // Give user manager a chance to propagate user restrictions
1014 // to other services and prepare app storage
1015 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001016
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001017 // Booting up a new user, need to tell system services about it.
1018 // Note that this is on the same handler as scheduling of broadcasts,
1019 // which is important because it needs to go first.
1020 mHandler.sendMessage(
1021 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1022 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001023
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001024 if (foreground) {
1025 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1026 oldUserId));
1027 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1028 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1029 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1030 oldUserId, userId, uss));
1031 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1032 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1033 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001034
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001035 if (needStart) {
1036 // Send USER_STARTED broadcast
1037 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1038 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1039 | Intent.FLAG_RECEIVER_FOREGROUND);
1040 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1041 mInjector.broadcastIntent(intent,
1042 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1043 null, false, false, MY_PID, SYSTEM_UID, userId);
1044 }
1045
1046 if (foreground) {
1047 moveUserToForeground(uss, oldUserId, userId);
1048 } else {
1049 finishUserBoot(uss);
1050 }
1051
1052 if (needStart) {
1053 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1054 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1055 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1056 mInjector.broadcastIntent(intent,
1057 null, new IIntentReceiver.Stub() {
1058 @Override
1059 public void performReceive(Intent intent, int resultCode,
1060 String data, Bundle extras, boolean ordered,
1061 boolean sticky,
1062 int sendingUser) throws RemoteException {
1063 }
1064 }, 0, null, null,
1065 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
1066 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001067 }
1068 } finally {
1069 Binder.restoreCallingIdentity(ident);
1070 }
1071
1072 return true;
1073 }
1074
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001075 /**
1076 * Start user, if its not already running, and bring it to foreground.
1077 */
Evan Rosky18396452016-07-27 15:19:37 -07001078 void startUserInForeground(final int targetUserId) {
1079 boolean success = startUser(targetUserId, /* foreground */ true);
1080 if (!success) {
1081 mInjector.getWindowManager().setSwitchingUser(false);
1082 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001083 }
1084
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001085 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001086 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001087 != PackageManager.PERMISSION_GRANTED) {
1088 String msg = "Permission Denial: unlockUser() from pid="
1089 + Binder.getCallingPid()
1090 + ", uid=" + Binder.getCallingUid()
1091 + " requires " + INTERACT_ACROSS_USERS_FULL;
1092 Slog.w(TAG, msg);
1093 throw new SecurityException(msg);
1094 }
1095
Jeff Sharkey8924e872015-11-30 12:52:10 -07001096 final long binderToken = Binder.clearCallingIdentity();
1097 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001098 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001099 } finally {
1100 Binder.restoreCallingIdentity(binderToken);
1101 }
1102 }
1103
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001104 /**
1105 * Attempt to unlock user without a credential token. This typically
1106 * succeeds when the device doesn't have credential-encrypted storage, or
1107 * when the the credential-encrypted storage isn't tied to a user-provided
1108 * PIN or pattern.
1109 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001110 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001111 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001112 return unlockUserCleared(userId, null, null, null);
1113 }
1114
1115 private static void notifyFinished(int userId, IProgressListener listener) {
1116 if (listener == null) return;
1117 try {
1118 listener.onFinished(userId, null);
1119 } catch (RemoteException ignored) {
1120 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001121 }
1122
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001123 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001124 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001125 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001126 if (!StorageManager.isUserKeyUnlocked(userId)) {
1127 final UserInfo userInfo = getUserInfo(userId);
1128 final IStorageManager storageManager = getStorageManager();
1129 try {
1130 // We always want to unlock user storage, even user is not started yet
1131 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1132 } catch (RemoteException | RuntimeException e) {
1133 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001134 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001135 }
1136 synchronized (mLock) {
1137 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001138 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001139 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001140 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001141 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001142 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001143 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001144 // Bail if user isn't actually running
1145 if (uss == null) {
1146 notifyFinished(userId, listener);
1147 return false;
1148 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001149
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001150 finishUserUnlocking(uss);
1151
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001152 // We just unlocked a user, so let's now attempt to unlock any
1153 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001154
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001155 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1156 int[] userIds;
1157 synchronized (mLock) {
1158 userIds = new int[mStartedUsers.size()];
1159 for (int i = 0; i < userIds.length; i++) {
1160 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001161 }
1162 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001163 for (int testUserId : userIds) {
1164 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1165 if (parent != null && parent.id == userId && testUserId != userId) {
1166 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1167 + "): attempting unlock because parent was just unlocked");
1168 maybeUnlockUser(testUserId);
1169 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001170 }
1171
Jeff Sharkeyba512352015-11-12 20:17:45 -08001172 return true;
1173 }
1174
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001175 boolean switchUser(final int targetUserId) {
1176 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001177 int currentUserId = getCurrentUserId();
1178 UserInfo targetUserInfo = getUserInfo(targetUserId);
1179 if (targetUserId == currentUserId) {
1180 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1181 return true;
1182 }
1183 if (targetUserInfo == null) {
1184 Slog.w(TAG, "No user info for user #" + targetUserId);
1185 return false;
1186 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001187 if (!targetUserInfo.supportsSwitchTo()) {
1188 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1189 return false;
1190 }
1191 if (targetUserInfo.isManagedProfile()) {
1192 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1193 return false;
1194 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001195 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001196 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001197 }
1198 if (mUserSwitchUiEnabled) {
1199 UserInfo currentUserInfo = getUserInfo(currentUserId);
1200 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1201 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1202 mUiHandler.sendMessage(mHandler.obtainMessage(
1203 START_USER_SWITCH_UI_MSG, userNames));
1204 } else {
1205 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1206 mHandler.sendMessage(mHandler.obtainMessage(
1207 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1208 }
1209 return true;
1210 }
1211
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001212 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001213 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001214 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1215 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001216 }
1217
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001218 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001219 final int observerCount = mUserSwitchObservers.beginBroadcast();
1220 for (int i = 0; i < observerCount; i++) {
1221 try {
1222 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1223 } catch (RemoteException e) {
1224 // Ignore
1225 }
1226 }
1227 mUserSwitchObservers.finishBroadcast();
1228 }
1229
1230 /** Called on handler thread */
1231 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001232 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001233 final int observerCount = mUserSwitchObservers.beginBroadcast();
1234 for (int i = 0; i < observerCount; i++) {
1235 try {
1236 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1237 } catch (RemoteException e) {
1238 }
1239 }
1240 mUserSwitchObservers.finishBroadcast();
1241 }
1242
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001243 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001244 final int observerCount = mUserSwitchObservers.beginBroadcast();
1245 for (int i = 0; i < observerCount; i++) {
1246 try {
1247 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1248 } catch (RemoteException e) {
1249 // Ignore
1250 }
1251 }
1252 mUserSwitchObservers.finishBroadcast();
1253 }
1254
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001255 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1256 // Never stop system user
1257 if (oldUserId == UserHandle.USER_SYSTEM) {
1258 return;
1259 }
1260 // For now, only check for user restriction. Additional checks can be added here
1261 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1262 oldUserId);
1263 if (!disallowRunInBg) {
1264 return;
1265 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001266 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001267 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1268 + " and related users");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001269 stopUsersLU(oldUserId, false, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001270 }
1271 }
1272
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001273 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001274 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001275 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1276 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1277 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001278 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001279 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1280 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1281 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1282 }
1283 }
1284
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001285 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001286 synchronized (mLock) {
1287 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1288 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1289 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1290 mTimeoutUserSwitchCallbacks = null;
1291 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001292 }
1293 }
1294
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001295 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1296 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001297 final int observerCount = mUserSwitchObservers.beginBroadcast();
1298 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001299 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001300 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001301 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001302 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001303 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001304 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001305 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001306 for (int i = 0; i < observerCount; i++) {
1307 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001308 // Prepend with unique prefix to guarantee that keys are unique
1309 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001310 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001311 curWaitingUserSwitchCallbacks.add(name);
1312 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001313 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1314 @Override
1315 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001316 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001317 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001318 if (delay > USER_SWITCH_TIMEOUT_MS) {
1319 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001320 + " sent result after " + delay + " ms");
1321 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001322 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001323 // Continue switching if all callbacks have been notified and
1324 // user switching session is still valid
1325 if (waitingCallbacksCount.decrementAndGet() == 0
1326 && (curWaitingUserSwitchCallbacks
1327 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001328 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001329 }
1330 }
1331 }
1332 };
1333 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001334 } catch (RemoteException e) {
1335 }
1336 }
1337 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001338 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001339 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001340 }
1341 }
1342 mUserSwitchObservers.finishBroadcast();
1343 }
1344
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001345 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001346 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001347 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001348 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001349 oldUserId, newUserId, uss));
1350 }
1351
1352 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001353 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001354 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001355 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001356 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001357 uss.switching = false;
1358 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1359 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1360 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001361 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001362 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001363 }
1364
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001365 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1366 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001367 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001368 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001369 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001370 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001371 }
1372 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001373 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001374 }
1375
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001376 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001377 long ident = Binder.clearCallingIdentity();
1378 try {
1379 Intent intent;
1380 if (oldUserId >= 0) {
1381 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001382 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001383 int count = profiles.size();
1384 for (int i = 0; i < count; i++) {
1385 int profileUserId = profiles.get(i).id;
1386 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1387 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1388 | Intent.FLAG_RECEIVER_FOREGROUND);
1389 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001390 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001391 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1392 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1393 }
1394 }
1395 if (newUserId >= 0) {
1396 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001397 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001398 int count = profiles.size();
1399 for (int i = 0; i < count; i++) {
1400 int profileUserId = profiles.get(i).id;
1401 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1402 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1403 | Intent.FLAG_RECEIVER_FOREGROUND);
1404 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001405 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001406 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1407 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1408 }
1409 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1410 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1411 | Intent.FLAG_RECEIVER_FOREGROUND);
1412 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001413 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001414 null, null, 0, null, null,
1415 new String[] {android.Manifest.permission.MANAGE_USERS},
1416 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1417 UserHandle.USER_ALL);
1418 }
1419 } finally {
1420 Binder.restoreCallingIdentity(ident);
1421 }
1422 }
1423
1424
1425 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1426 int allowMode, String name, String callerPackage) {
1427 final int callingUserId = UserHandle.getUserId(callingUid);
1428 if (callingUserId == userId) {
1429 return userId;
1430 }
1431
1432 // Note that we may be accessing mCurrentUserId outside of a lock...
1433 // shouldn't be a big deal, if this is being called outside
1434 // of a locked context there is intrinsically a race with
1435 // the value the caller will receive and someone else changing it.
1436 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1437 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001438 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001439
1440 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1441 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001442 if (mInjector.isCallerRecents(callingUid)
1443 && callingUserId == getCurrentUserId()
1444 && isSameProfileGroup(callingUserId, targetUserId)) {
1445 // If the caller is Recents and it is running in the current user, we then allow it
1446 // to access its profiles.
1447 allow = true;
1448 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001449 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1450 // If the caller has this permission, they always pass go. And collect $200.
1451 allow = true;
1452 } else if (allowMode == ALLOW_FULL_ONLY) {
1453 // We require full access, sucks to be you.
1454 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001455 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001456 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1457 // If the caller does not have either permission, they are always doomed.
1458 allow = false;
1459 } else if (allowMode == ALLOW_NON_FULL) {
1460 // We are blanket allowing non-full access, you lucky caller!
1461 allow = true;
1462 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1463 // We may or may not allow this depending on whether the two users are
1464 // in the same profile.
1465 allow = isSameProfileGroup(callingUserId, targetUserId);
1466 } else {
1467 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1468 }
1469 if (!allow) {
1470 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1471 // In this case, they would like to just execute as their
1472 // owner user instead of failing.
1473 targetUserId = callingUserId;
1474 } else {
1475 StringBuilder builder = new StringBuilder(128);
1476 builder.append("Permission Denial: ");
1477 builder.append(name);
1478 if (callerPackage != null) {
1479 builder.append(" from ");
1480 builder.append(callerPackage);
1481 }
1482 builder.append(" asks to run as user ");
1483 builder.append(userId);
1484 builder.append(" but is calling from user ");
1485 builder.append(UserHandle.getUserId(callingUid));
1486 builder.append("; this requires ");
1487 builder.append(INTERACT_ACROSS_USERS_FULL);
1488 if (allowMode != ALLOW_FULL_ONLY) {
1489 builder.append(" or ");
1490 builder.append(INTERACT_ACROSS_USERS);
1491 }
1492 String msg = builder.toString();
1493 Slog.w(TAG, msg);
1494 throw new SecurityException(msg);
1495 }
1496 }
1497 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001498 if (!allowAll) {
1499 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001500 }
1501 // Check shell permission
1502 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1503 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1504 throw new SecurityException("Shell does not have permission to access user "
1505 + targetUserId + "\n " + Debug.getCallers(3));
1506 }
1507 }
1508 return targetUserId;
1509 }
1510
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001511 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001512 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001513 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001514 }
1515
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001516 void ensureNotSpecialUser(int userId) {
1517 if (userId >= 0) {
1518 return;
1519 }
1520 throw new IllegalArgumentException("Call does not support special user #" + userId);
1521 }
1522
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001523 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1524 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001525 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001526 != PackageManager.PERMISSION_GRANTED) {
1527 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1528 + Binder.getCallingPid()
1529 + ", uid=" + Binder.getCallingUid()
1530 + " requires " + INTERACT_ACROSS_USERS_FULL;
1531 Slog.w(TAG, msg);
1532 throw new SecurityException(msg);
1533 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001534 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001535 }
1536
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001537 void sendForegroundProfileChanged(int userId) {
1538 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1539 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1540 }
1541
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001542 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1543 mUserSwitchObservers.unregister(observer);
1544 }
1545
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001546 UserState getStartedUserState(int userId) {
1547 synchronized (mLock) {
1548 return mStartedUsers.get(userId);
1549 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001550 }
1551
1552 boolean hasStartedUserState(int userId) {
1553 return mStartedUsers.get(userId) != null;
1554 }
1555
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001556 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001557 int num = 0;
1558 for (int i = 0; i < mStartedUsers.size(); i++) {
1559 UserState uss = mStartedUsers.valueAt(i);
1560 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001561 if (uss.state != UserState.STATE_STOPPING
1562 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001563 num++;
1564 }
1565 }
1566 mStartedUserArray = new int[num];
1567 num = 0;
1568 for (int i = 0; i < mStartedUsers.size(); i++) {
1569 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001570 if (uss.state != UserState.STATE_STOPPING
1571 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001572 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001573 }
1574 }
1575 }
1576
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001577 void sendBootCompleted(IIntentReceiver resultTo) {
1578 // Get a copy of mStartedUsers to use outside of lock
1579 SparseArray<UserState> startedUsers;
1580 synchronized (mLock) {
1581 startedUsers = mStartedUsers.clone();
1582 }
1583 for (int i = 0; i < startedUsers.size(); i++) {
1584 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001585 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001586 }
1587 }
1588
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001589 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001590 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001591 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001592 }
1593
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001594 /**
1595 * Refreshes the list of users related to the current user when either a
1596 * user switch happens or when a new related user is started in the
1597 * background.
1598 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001599 private void updateCurrentProfileIds() {
1600 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001601 false /* enabledOnly */);
1602 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1603 for (int i = 0; i < currentProfileIds.length; i++) {
1604 currentProfileIds[i] = profiles.get(i).id;
1605 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001606 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1607 synchronized (mLock) {
1608 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001609
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001610 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001611 for (int i = 0; i < users.size(); i++) {
1612 UserInfo user = users.get(i);
1613 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001614 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001615 }
1616 }
1617 }
1618 }
1619
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001620 int[] getStartedUserArray() {
1621 synchronized (mLock) {
1622 return mStartedUserArray;
1623 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001624 }
1625
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001626 boolean isUserRunning(int userId, int flags) {
1627 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001628 if (state == null) {
1629 return false;
1630 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001631 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001632 return true;
1633 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001634 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001635 switch (state.state) {
1636 case UserState.STATE_BOOTING:
1637 case UserState.STATE_RUNNING_LOCKED:
1638 return true;
1639 default:
1640 return false;
1641 }
1642 }
1643 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1644 switch (state.state) {
1645 case UserState.STATE_RUNNING_UNLOCKING:
1646 case UserState.STATE_RUNNING_UNLOCKED:
1647 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001648 // In the stopping/shutdown state return unlock state of the user key
1649 case UserState.STATE_STOPPING:
1650 case UserState.STATE_SHUTDOWN:
1651 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001652 default:
1653 return false;
1654 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001655 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001656 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001657 switch (state.state) {
1658 case UserState.STATE_RUNNING_UNLOCKED:
1659 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001660 // In the stopping/shutdown state return unlock state of the user key
1661 case UserState.STATE_STOPPING:
1662 case UserState.STATE_SHUTDOWN:
1663 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001664 default:
1665 return false;
1666 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001667 }
1668
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001669 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001670 }
1671
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001672 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001673 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001674 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001675 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001676 != PackageManager.PERMISSION_GRANTED)) {
1677 String msg = "Permission Denial: getCurrentUser() from pid="
1678 + Binder.getCallingPid()
1679 + ", uid=" + Binder.getCallingUid()
1680 + " requires " + INTERACT_ACROSS_USERS;
1681 Slog.w(TAG, msg);
1682 throw new SecurityException(msg);
1683 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001684
1685 // Optimization - if there is no pending user switch, return current id
1686 if (mTargetUserId == UserHandle.USER_NULL) {
1687 return getUserInfo(mCurrentUserId);
1688 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001689 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001690 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001691 }
1692 }
1693
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001694 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001695 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001696 return getUserInfo(userId);
1697 }
1698
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001699 int getCurrentOrTargetUserId() {
1700 synchronized (mLock) {
1701 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1702 }
1703 }
1704
1705 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001706 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001707 }
1708
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001709
1710 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001711 return mCurrentUserId;
1712 }
1713
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001714 int getCurrentUserId() {
1715 synchronized (mLock) {
1716 return mCurrentUserId;
1717 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001718 }
1719
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001720 private boolean isCurrentUserLU(int userId) {
1721 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001722 }
1723
1724 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001725 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001726 return ums != null ? ums.getUserIds() : new int[] { 0 };
1727 }
1728
1729 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001730 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001731 }
1732
1733 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001734 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001735 }
1736
Makoto Onuki6569c362018-02-27 15:52:01 -08001737 /**
1738 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1739 * IDs. Otherwise return an array whose only element is the given user id.
1740 *
1741 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1742 */
1743 int[] expandUserId(int userId) {
1744 if (userId != UserHandle.USER_ALL) {
1745 return new int[] {userId};
1746 } else {
1747 return getUsers();
1748 }
1749 }
1750
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001751 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001752 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001753 }
1754
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001755 void enforceShellRestriction(String restriction, int userHandle) {
1756 if (Binder.getCallingUid() == SHELL_UID) {
1757 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1758 throw new SecurityException("Shell does not have permission to access user "
1759 + userHandle);
1760 }
1761 }
1762 }
1763
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001764 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001765 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001766 }
1767
1768 Set<Integer> getProfileIds(int userId) {
1769 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001770 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001771 false /* enabledOnly */);
1772 for (UserInfo user : profiles) {
1773 userIds.add(user.id);
1774 }
1775 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001776 }
1777
1778 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001779 if (callingUserId == targetUserId) {
1780 return true;
1781 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001782 synchronized (mLock) {
1783 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001784 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001785 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001786 UserInfo.NO_PROFILE_GROUP_ID);
1787 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1788 && callingProfile == targetProfile;
1789 }
1790 }
1791
Tony Mak60f53e62017-12-21 20:03:29 +00001792 boolean isUserOrItsParentRunning(int userId) {
1793 synchronized (mLock) {
1794 if (isUserRunning(userId, 0)) {
1795 return true;
1796 }
1797 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1798 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1799 return false;
1800 }
1801 return isUserRunning(parentUserId, 0);
1802 }
1803 }
1804
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001805 boolean isCurrentProfile(int userId) {
1806 synchronized (mLock) {
1807 return ArrayUtils.contains(mCurrentProfileIds, userId);
1808 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001809 }
1810
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001811 int[] getCurrentProfileIds() {
1812 synchronized (mLock) {
1813 return mCurrentProfileIds;
1814 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001815 }
1816
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001817 void onUserRemoved(int userId) {
1818 synchronized (mLock) {
1819 int size = mUserProfileGroupIds.size();
1820 for (int i = size - 1; i >= 0; i--) {
1821 if (mUserProfileGroupIds.keyAt(i) == userId
1822 || mUserProfileGroupIds.valueAt(i) == userId) {
1823 mUserProfileGroupIds.removeAt(i);
1824
1825 }
1826 }
1827 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1828 }
1829 }
1830
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001831 /**
1832 * Returns whether the given user requires credential entry at this time. This is used to
1833 * intercept activity launches for work apps when the Work Challenge is present.
1834 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001835 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001836 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001837 if (mStartedUsers.get(userId) == null) {
1838 return false;
1839 }
1840 }
Clara Bayarria1771112015-12-18 16:29:18 +00001841 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001842 return false;
1843 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001844 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001845 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001846 }
1847
Tony Mak8c536f92016-03-21 12:20:41 +00001848 boolean isLockScreenDisabled(@UserIdInt int userId) {
1849 return mLockPatternUtils.isLockScreenDisabled(userId);
1850 }
1851
Alex Chau93ae42b2018-01-11 15:10:12 +00001852 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
1853 synchronized (mLock) {
1854 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
1855 }
1856 }
1857
1858 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
1859 synchronized (mLock) {
1860 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
1861 }
1862 }
1863
1864 private String getSwitchingFromSystemUserMessage() {
1865 synchronized (mLock) {
1866 return mSwitchingFromSystemUserMessage;
1867 }
1868 }
1869
1870 private String getSwitchingToSystemUserMessage() {
1871 synchronized (mLock) {
1872 return mSwitchingToSystemUserMessage;
1873 }
1874 }
1875
Yi Jin148d7f42017-11-28 14:23:56 -08001876 void writeToProto(ProtoOutputStream proto, long fieldId) {
1877 synchronized (mLock) {
1878 long token = proto.start(fieldId);
1879 for (int i = 0; i < mStartedUsers.size(); i++) {
1880 UserState uss = mStartedUsers.valueAt(i);
1881 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
1882 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
1883 uss.writeToProto(proto, UserControllerProto.User.STATE);
1884 proto.end(uToken);
1885 }
1886 for (int i = 0; i < mStartedUserArray.length; i++) {
1887 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
1888 }
1889 for (int i = 0; i < mUserLru.size(); i++) {
1890 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
1891 }
1892 if (mUserProfileGroupIds.size() > 0) {
1893 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
1894 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
1895 proto.write(UserControllerProto.UserProfile.USER,
1896 mUserProfileGroupIds.keyAt(i));
1897 proto.write(UserControllerProto.UserProfile.PROFILE,
1898 mUserProfileGroupIds.valueAt(i));
1899 proto.end(uToken);
1900 }
1901 }
1902 proto.end(token);
1903 }
1904 }
1905
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001906 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001907 synchronized (mLock) {
1908 pw.println(" mStartedUsers:");
1909 for (int i = 0; i < mStartedUsers.size(); i++) {
1910 UserState uss = mStartedUsers.valueAt(i);
1911 pw.print(" User #");
1912 pw.print(uss.mHandle.getIdentifier());
1913 pw.print(": ");
1914 uss.dump("", pw);
1915 }
1916 pw.print(" mStartedUserArray: [");
1917 for (int i = 0; i < mStartedUserArray.length; i++) {
1918 if (i > 0)
1919 pw.print(", ");
1920 pw.print(mStartedUserArray[i]);
1921 }
1922 pw.println("]");
1923 pw.print(" mUserLru: [");
1924 for (int i = 0; i < mUserLru.size(); i++) {
1925 if (i > 0)
1926 pw.print(", ");
1927 pw.print(mUserLru.get(i));
1928 }
1929 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001930 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001931 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001932 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001933 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001934 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001935 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001936 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001937 }
1938 }
1939 }
1940 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001941
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001942 public boolean handleMessage(Message msg) {
1943 switch (msg.what) {
1944 case START_USER_SWITCH_FG_MSG:
1945 startUserInForeground(msg.arg1);
1946 break;
1947 case REPORT_USER_SWITCH_MSG:
1948 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949 break;
1950 case CONTINUE_USER_SWITCH_MSG:
1951 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1952 break;
1953 case USER_SWITCH_TIMEOUT_MSG:
1954 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1955 break;
1956 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
1957 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
1958 break;
1959 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001960 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001961 break;
1962 case SYSTEM_USER_START_MSG:
1963 mInjector.batteryStatsServiceNoteEvent(
1964 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1965 Integer.toString(msg.arg1), msg.arg1);
1966 mInjector.getSystemServiceManager().startUser(msg.arg1);
1967 break;
1968 case SYSTEM_USER_UNLOCK_MSG:
1969 final int userId = msg.arg1;
1970 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08001971 // Loads recents on a worker thread that allows disk I/O
1972 FgThread.getHandler().post(() -> {
1973 mInjector.loadUserRecents(userId);
1974 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001975 finishUserUnlocked((UserState) msg.obj);
1976 break;
1977 case SYSTEM_USER_CURRENT_MSG:
1978 mInjector.batteryStatsServiceNoteEvent(
1979 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1980 Integer.toString(msg.arg2), msg.arg2);
1981 mInjector.batteryStatsServiceNoteEvent(
1982 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1983 Integer.toString(msg.arg1), msg.arg1);
1984
1985 mInjector.getSystemServiceManager().switchUser(msg.arg1);
1986 break;
1987 case FOREGROUND_PROFILE_CHANGED_MSG:
1988 dispatchForegroundProfileChanged(msg.arg1);
1989 break;
1990 case REPORT_USER_SWITCH_COMPLETE_MSG:
1991 dispatchUserSwitchComplete(msg.arg1);
1992 break;
1993 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
1994 dispatchLockedBootComplete(msg.arg1);
1995 break;
1996 case START_USER_SWITCH_UI_MSG:
1997 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1998 break;
1999 }
2000 return false;
2001 }
2002
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002003 private static class UserProgressListener extends IProgressListener.Stub {
2004 private volatile long mUnlockStarted;
2005 @Override
2006 public void onStarted(int id, Bundle extras) throws RemoteException {
2007 Slog.d(TAG, "Started unlocking user " + id);
2008 mUnlockStarted = SystemClock.uptimeMillis();
2009 }
2010
2011 @Override
2012 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2013 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2014 }
2015
2016 @Override
2017 public void onFinished(int id, Bundle extras) throws RemoteException {
2018 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2019
2020 // Report system user unlock time to perf dashboard
2021 if (id == UserHandle.USER_SYSTEM) {
2022 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2023 .logDuration("SystemUserUnlock", unlockTime);
2024 } else {
2025 Slog.d(TAG, "Unlocking user " + id + " took " + unlockTime + " ms");
2026 }
2027 }
2028 };
2029
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002030 @VisibleForTesting
2031 static class Injector {
2032 private final ActivityManagerService mService;
2033 private UserManagerService mUserManager;
2034 private UserManagerInternal mUserManagerInternal;
2035
2036 Injector(ActivityManagerService service) {
2037 mService = service;
2038 }
2039
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002040 protected Handler getHandler(Handler.Callback callback) {
2041 return new Handler(mService.mHandlerThread.getLooper(), callback);
2042 }
2043
2044 protected Handler getUiHandler(Handler.Callback callback) {
2045 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002046 }
2047
2048 protected Context getContext() {
2049 return mService.mContext;
2050 }
2051
2052 protected LockPatternUtils getLockPatternUtils() {
2053 return new LockPatternUtils(getContext());
2054 }
2055
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002056 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002057 IIntentReceiver resultTo, int resultCode, String resultData,
2058 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
2059 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002060 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2061 synchronized (mService) {
2062 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2063 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
2064 ordered, sticky, callingPid, callingUid, userId);
2065 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002066 }
2067
2068 int checkCallingPermission(String permission) {
2069 return mService.checkCallingPermission(permission);
2070 }
2071
2072 WindowManagerService getWindowManager() {
2073 return mService.mWindowManager;
2074 }
2075 void activityManagerOnUserStopped(int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002076 synchronized (mService) {
2077 mService.onUserStoppedLocked(userId);
2078 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002079 }
2080
2081 void systemServiceManagerCleanupUser(int userId) {
2082 mService.mSystemServiceManager.cleanupUser(userId);
2083 }
2084
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002085 protected UserManagerService getUserManager() {
2086 if (mUserManager == null) {
2087 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2088 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2089 }
2090 return mUserManager;
2091 }
2092
2093 UserManagerInternal getUserManagerInternal() {
2094 if (mUserManagerInternal == null) {
2095 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2096 }
2097 return mUserManagerInternal;
2098 }
2099
2100 KeyguardManager getKeyguardManager() {
2101 return mService.mContext.getSystemService(KeyguardManager.class);
2102 }
2103
2104 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2105 mService.mBatteryStatsService.noteEvent(code, name, uid);
2106 }
2107
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002108 boolean isRuntimeRestarted() {
2109 return mService.mSystemServiceManager.isRuntimeRestarted();
2110 }
2111
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002112 SystemServiceManager getSystemServiceManager() {
2113 return mService.mSystemServiceManager;
2114 }
2115
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002116 boolean isFirstBootOrUpgrade() {
2117 IPackageManager pm = AppGlobals.getPackageManager();
2118 try {
2119 return pm.isFirstBoot() || pm.isUpgrade();
2120 } catch (RemoteException e) {
2121 throw e.rethrowFromSystemServer();
2122 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002123 }
2124
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002125 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2126 new PreBootBroadcaster(mService, userId, null, quiet) {
2127 @Override
2128 public void onFinished() {
2129 onFinish.run();
2130 }
2131 }.sendNext();
2132 }
2133
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002134 void activityManagerForceStopPackage(int userId, String reason) {
2135 synchronized (mService) {
2136 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2137 userId, reason);
2138 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002139 };
2140
2141 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2142 boolean exported) {
2143 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2144 }
2145
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002146 protected void startHomeActivity(int userId, String reason) {
2147 synchronized (mService) {
2148 mService.startHomeActivityLocked(userId, reason);
2149 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002150 }
2151
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002152 void updateUserConfiguration() {
2153 synchronized (mService) {
2154 mService.updateUserConfigurationLocked();
2155 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002156 }
2157
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002158 void clearBroadcastQueueForUser(int userId) {
2159 synchronized (mService) {
2160 mService.clearBroadcastQueueForUserLocked(userId);
2161 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002162 }
2163
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002164 void loadUserRecents(int userId) {
2165 synchronized (mService) {
Winson Chung3f0e59a2017-10-25 10:19:05 -07002166 mService.getRecentTasks().loadUserRecentsLocked(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002167 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002168 }
2169
2170 void startPersistentApps(int matchFlags) {
2171 mService.startPersistentApps(matchFlags);
2172 }
2173
2174 void installEncryptionUnawareProviders(int userId) {
2175 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002176 }
2177
Alex Chau93ae42b2018-01-11 15:10:12 +00002178 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2179 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002180 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002181 true /* above system */, switchingFromSystemUserMessage,
2182 switchingToSystemUserMessage);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002183 d.show();
2184 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002185
Dianne Hackbornced54392018-02-26 13:07:42 -08002186 void reportGlobalUsageEventLocked(int event) {
2187 synchronized (mService) {
2188 mService.reportGlobalUsageEventLocked(event);
2189 }
2190 }
2191
2192 void reportCurWakefulnessUsageEvent() {
2193 synchronized (mService) {
2194 mService.reportCurWakefulnessUsageEventLocked();
2195 }
2196 }
2197
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002198 void stackSupervisorRemoveUser(int userId) {
2199 synchronized (mService) {
2200 mService.mStackSupervisor.removeUserLocked(userId);
2201 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002202 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002203
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002204 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
2205 synchronized (mService) {
2206 return mService.mStackSupervisor.switchUserLocked(userId, uss);
2207 }
2208 }
2209
2210 protected void stackSupervisorResumeFocusedStackTopActivity() {
2211 synchronized (mService) {
2212 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
2213 }
2214 }
2215
Charles Heff9b4dff2017-09-22 10:18:37 +01002216 protected void clearAllLockedTasks(String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002217 synchronized (mService) {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002218 mService.getLockTaskController().clearLockedTasks(reason);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002219 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002220 }
Tony Make839d702018-01-22 15:34:46 +00002221
2222 protected boolean isCallerRecents(int callingUid) {
2223 return mService.getRecentTasks().isCallerRecents(callingUid);
2224 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002225 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002226}