blob: 4746e12e2838f2f151a4a22801a8f99a0bd40869 [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;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070027import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
28import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
29import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070030import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
31import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
32import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
33import static com.android.server.am.ActivityManagerService.MY_PID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060034import static com.android.server.am.UserState.STATE_BOOTING;
35import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
36import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
37import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070038
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070039import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000040import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000041import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070042import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080043import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070044import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070045import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070046import android.app.IStopUserCallback;
47import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000048import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080049import android.app.usage.UsageEvents;
Christopher Tate2ec961d2018-07-27 16:48:37 -070050import android.appwidget.AppWidgetManagerInternal;
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 Kupolov3d4b5c92018-04-30 18:49:34 -070067import android.os.Looper;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070068import android.os.Message;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070069import android.os.Process;
70import android.os.RemoteCallbackList;
71import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070072import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070073import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070074import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070075import android.os.UserHandle;
76import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010077import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080078import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080079import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070080import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070081import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070082import android.util.IntArray;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070083import android.util.Log;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080084import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070085import android.util.Slog;
86import android.util.SparseArray;
87import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070088import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080089import android.util.proto.ProtoOutputStream;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070090import android.view.Window;
Christopher Tate2ec961d2018-07-27 16:48:37 -070091
Fyodor Kupolov610acda2015-10-19 18:44:07 -070092import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080093import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070094import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070095import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070096import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070097import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000098import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080099import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100100import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700101import com.android.server.SystemServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700102import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700103import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700104
105import java.io.PrintWriter;
106import java.util.ArrayList;
107import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700108import java.util.HashSet;
Alex Chaub6ef8692018-01-09 14:16:36 +0000109import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700110import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600111import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700112import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700113import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700114
115/**
116 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700117 *
118 * <p>This class use {@link #mLock} to synchronize access to internal state. Methods that require
119 * {@link #mLock} to be held should have "LU" suffix in the name.
120 *
121 * <p><strong>Important:</strong> Synchronized code, i.e. one executed inside a synchronized(mLock)
122 * block or inside LU method, should only access internal state of this class or make calls to
123 * other LU methods. Non-LU method calls or calls to external classes are discouraged as they
124 * may cause lock inversion.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700125 */
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700126class UserController implements Handler.Callback {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700127 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600128
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700129 // Amount of time we wait for observers to handle a user switch before
130 // giving up on them and unfreezing the screen.
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700131 static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
132
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700133 // ActivityManager thread message constants
134 static final int REPORT_USER_SWITCH_MSG = 10;
135 static final int CONTINUE_USER_SWITCH_MSG = 20;
136 static final int USER_SWITCH_TIMEOUT_MSG = 30;
137 static final int START_PROFILES_MSG = 40;
138 static final int SYSTEM_USER_START_MSG = 50;
139 static final int SYSTEM_USER_CURRENT_MSG = 60;
140 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
141 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
142 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
143 static final int SYSTEM_USER_UNLOCK_MSG = 100;
144 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
145 static final int START_USER_SWITCH_FG_MSG = 120;
146
147 // UI thread message constants
148 static final int START_USER_SWITCH_UI_MSG = 1000;
149
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700150 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
151 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
152 // when it never calls back.
153 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700154
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700155 /**
156 * Maximum number of users we allow to be running at a time, including system user.
157 *
158 * <p>This parameter only affects how many background users will be stopped when switching to a
159 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
160 *
161 * <p>Note: Current and system user (and their related profiles) are never stopped when
162 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
163 */
164 int mMaxRunningUsers;
165
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700166 // Lock for internal state.
167 private final Object mLock = new Object();
168
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700169 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700170 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700171 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700172
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700173 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700174 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700175 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
176 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
177 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700178 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700179 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700180
181 /**
182 * Which users have been started, so are allowed to run code.
183 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700184 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700185 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800186
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700187 /**
188 * LRU list of history of current users. Most recently current is at the end.
189 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700190 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700191 private final ArrayList<Integer> mUserLru = new ArrayList<>();
192
193 /**
194 * Constant array of the users that are currently started.
195 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700196 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700197 private int[] mStartedUserArray = new int[] { 0 };
198
199 // If there are multiple profiles for the current user, their ids are here
200 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700201 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700202 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700203
204 /**
205 * Mapping from each known user ID to the profile group ID it is associated with.
206 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700207 @GuardedBy("mLock")
208 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700209
210 /**
211 * Registered observers of the user switching mechanics.
212 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700213 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700214 = new RemoteCallbackList<>();
215
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700216 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700217
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700218 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700219 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700220 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700221 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700222 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700223
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700224 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000225 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
226 */
227 @GuardedBy("mLock")
228 private String mSwitchingFromSystemUserMessage;
229
230 /**
231 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
232 */
233 @GuardedBy("mLock")
234 private String mSwitchingToSystemUserMessage;
235
236 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700237 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
238 */
239 @GuardedBy("mLock")
240 private ArraySet<String> mTimeoutUserSwitchCallbacks;
241
Clara Bayarria1771112015-12-18 16:29:18 +0000242 private final LockPatternUtils mLockPatternUtils;
243
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700244 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700245 this(new Injector(service));
246 }
247
248 @VisibleForTesting
249 UserController(Injector injector) {
250 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700251 mHandler = mInjector.getHandler(this);
252 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700253 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800254 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700255 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800256 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700257 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700258 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700259 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700260 }
261
262 void finishUserSwitch(UserState uss) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700263 finishUserBoot(uss);
264 startProfiles();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700265 synchronized (mLock) {
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700266 stopRunningUsersLU(mMaxRunningUsers);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700267 }
268 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700269
Alex Chaub6ef8692018-01-09 14:16:36 +0000270 List<Integer> getRunningUsersLU() {
271 ArrayList<Integer> runningUsers = new ArrayList<>();
272 for (Integer userId : mUserLru) {
273 UserState uss = mStartedUsers.get(userId);
274 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700275 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700276 continue;
277 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000278 if (uss.state == UserState.STATE_STOPPING
279 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700280 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700281 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700282 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000283 if (userId == UserHandle.USER_SYSTEM) {
284 // We only count system user as running when it is not a pure system user.
285 if (UserInfo.isSystemOnly(userId)) {
286 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700287 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000288 }
289 runningUsers.add(userId);
290 }
291 return runningUsers;
292 }
293
294 void stopRunningUsersLU(int maxRunningUsers) {
295 List<Integer> currentlyRunning = getRunningUsersLU();
296 Iterator<Integer> iterator = currentlyRunning.iterator();
297 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
298 Integer userId = iterator.next();
299 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
300 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700301 continue;
302 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000303 if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
304 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700305 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000306 }
307 }
308
309 /**
310 * Returns if more users can be started without stopping currently running users.
311 */
312 boolean canStartMoreUsers() {
313 synchronized (mLock) {
314 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700315 }
316 }
317
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800318 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700319 finishUserBoot(uss, null);
320 }
321
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800322 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700323 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700324
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700325 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700326 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700327 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700328 if (mStartedUsers.get(userId) != uss) {
329 return;
330 }
331 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700332
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700333 // We always walk through all the user lifecycle states to send
334 // consistent developer events. We step into RUNNING_LOCKED here,
335 // but we might immediately step into RUNNING below if the user
336 // storage is already unlocked.
337 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
338 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
339 // Do not report secondary users, runtime restarts or first boot/upgrade
340 if (userId == UserHandle.USER_SYSTEM
341 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
342 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
343 MetricsLogger.histogram(mInjector.getContext(),
344 "framework_locked_boot_completed", uptimeSeconds);
345 final int MAX_UPTIME_SECONDS = 120;
346 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
347 Slog.wtf("SystemServerTiming",
348 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800349 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700350 }
351
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700352 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
353 userId, 0));
354 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
355 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
356 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
357 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
358 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
359 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
360 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
361 }
362
363 // We need to delay unlocking managed profiles until the parent user
364 // is also unlocked.
365 if (mInjector.getUserManager().isManagedProfile(userId)) {
366 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
367 if (parent != null
368 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
369 Slog.d(TAG, "User " + userId + " (parent " + parent.id
370 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600371 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700372 } else {
373 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
374 Slog.d(TAG, "User " + userId + " (parent " + parentId
375 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600376 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700377 } else {
378 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700379 }
380 }
381
382 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600383 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
384 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700385 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600386 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700387 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700388 // Only keep marching forward if user is actually unlocked
389 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700390 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800391 // Do not proceed if unexpected state or a stale user
392 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700393 return;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600394 }
395 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700396 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200397
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700398 // Prepare app storage before we go any further
399 uss.mUnlockProgress.setProgress(5,
400 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200401
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800402 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
403 FgThread.getHandler().post(() -> {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100404 if (!StorageManager.isUserKeyUnlocked(userId)) {
405 Slog.w(TAG, "User key got locked unexpectedly, leaving user locked.");
406 return;
407 }
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800408 mInjector.getUserManager().onBeforeUnlockUser(userId);
409 synchronized (mLock) {
410 // Do not proceed if unexpected state
411 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
412 return;
413 }
414 }
415 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
416
417 uss.mUnlockProgress.setProgress(20);
418
419 // Dispatch unlocked to system services; when fully dispatched,
420 // that calls through to the next "unlocked" phase
421 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
422 .sendToTarget();
423 });
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600424 }
425
426 /**
427 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
428 * {@link UserState#STATE_RUNNING_UNLOCKED}.
429 */
430 void finishUserUnlocked(final UserState uss) {
431 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700432 // Only keep marching forward if user is actually unlocked
433 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700434 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600435 // Bail if we ended up with a stale user
436 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
437
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700438 // Do not proceed if unexpected state
439 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
440 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600441 }
442 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700443 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
444 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700445
446 // Get unaware persistent apps running and start any unaware providers
447 // in already-running apps that are partially aware
448 if (userId == UserHandle.USER_SYSTEM) {
449 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
450 }
451 mInjector.installEncryptionUnawareProviders(userId);
452
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700453 // Dispatch unlocked to external apps
454 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
455 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
456 unlockedIntent.addFlags(
457 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
458 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
459 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
460 userId);
461
462 if (getUserInfo(userId).isManagedProfile()) {
463 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
464 if (parent != null) {
465 final Intent profileUnlockedIntent = new Intent(
466 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
467 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
468 profileUnlockedIntent.addFlags(
469 Intent.FLAG_RECEIVER_REGISTERED_ONLY
470 | Intent.FLAG_RECEIVER_FOREGROUND);
471 mInjector.broadcastIntent(profileUnlockedIntent,
472 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
473 null, false, false, MY_PID, SYSTEM_UID,
474 parent.id);
475 }
476 }
477
478 // Send PRE_BOOT broadcasts if user fingerprint changed; we
479 // purposefully block sending BOOT_COMPLETED until after all
480 // PRE_BOOT receivers are finished to avoid ANR'ing apps
481 final UserInfo info = getUserInfo(userId);
482 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
483 // Suppress double notifications for managed profiles that
484 // were unlocked automatically as part of their parent user
485 // being unlocked.
486 final boolean quiet;
487 if (info.isManagedProfile()) {
488 quiet = !uss.tokenProvided
489 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
490 } else {
491 quiet = false;
492 }
493 mInjector.sendPreBootBroadcast(userId, quiet,
494 () -> finishUserUnlockedCompleted(uss));
495 } else {
496 finishUserUnlockedCompleted(uss);
497 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600498 }
499
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600500 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600501 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700502 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600503 // Bail if we ended up with a stale user
504 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700505 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700506 UserInfo userInfo = getUserInfo(userId);
507 if (userInfo == null) {
508 return;
509 }
510 // Only keep marching forward if user is actually unlocked
511 if (!StorageManager.isUserKeyUnlocked(userId)) return;
512
513 // Remember that we logged in
514 mInjector.getUserManager().onUserLoggedIn(userId);
515
516 if (!userInfo.isInitialized()) {
517 if (userId != UserHandle.USER_SYSTEM) {
518 Slog.d(TAG, "Initializing user #" + userId);
519 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
520 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
521 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
522 mInjector.broadcastIntent(intent, null,
523 new IIntentReceiver.Stub() {
524 @Override
525 public void performReceive(Intent intent, int resultCode,
526 String data, Bundle extras, boolean ordered,
527 boolean sticky, int sendingUser) {
528 // Note: performReceive is called with mService lock held
529 mInjector.getUserManager().makeInitialized(userInfo.id);
530 }
531 }, 0, null, null, null, AppOpsManager.OP_NONE,
532 null, true, false, MY_PID, SYSTEM_UID, userId);
533 }
534 }
535
Christopher Tate2ec961d2018-07-27 16:48:37 -0700536 // Spin up app widgets prior to boot-complete, so they can be ready promptly
537 mInjector.startUserWidgets(userId);
538
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700539 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
540 // Do not report secondary users, runtime restarts or first boot/upgrade
541 if (userId == UserHandle.USER_SYSTEM
542 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
543 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
544 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
545 uptimeSeconds);
546 }
547 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
548 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
549 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
550 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
551 mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
552 @Override
553 public void performReceive(Intent intent, int resultCode, String data,
554 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
555 throws RemoteException {
556 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
557 }
558 }, 0, null, null,
559 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
560 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700561 }
562
Andrew Scull85a63bc2016-10-24 13:47:47 +0100563 int restartUser(final int userId, final boolean foreground) {
564 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
565 @Override
566 public void userStopped(final int userId) {
567 // Post to the same handler that this callback is called from to ensure the user
568 // cleanup is complete before restarting.
569 mHandler.post(() -> startUser(userId, foreground));
570 }
571 @Override
572 public void userStopAborted(final int userId) {}
573 });
574 }
575
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700576 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700577 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700578 != PackageManager.PERMISSION_GRANTED) {
579 String msg = "Permission Denial: switchUser() from pid="
580 + Binder.getCallingPid()
581 + ", uid=" + Binder.getCallingUid()
582 + " requires " + INTERACT_ACROSS_USERS_FULL;
583 Slog.w(TAG, msg);
584 throw new SecurityException(msg);
585 }
586 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
587 throw new IllegalArgumentException("Can't stop system user " + userId);
588 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700589 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700590 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700591 return stopUsersLU(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700592 }
593 }
594
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700595 /**
596 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700597 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700598 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700599 private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700600 if (userId == UserHandle.USER_SYSTEM) {
601 return USER_OP_ERROR_IS_SYSTEM;
602 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700603 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700604 return USER_OP_IS_CURRENT;
605 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700606 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700607 // If one of related users is system or current, no related users should be stopped
608 for (int i = 0; i < usersToStop.length; i++) {
609 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700610 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700611 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
612 + relatedUserId);
613 // We still need to stop the requested user if it's a force stop.
614 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800615 Slog.i(TAG,
616 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700617 stopSingleUserLU(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800618 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700619 }
620 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
621 }
622 }
623 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
624 for (int userIdToStop : usersToStop) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700625 stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700626 }
627 return USER_OP_SUCCESS;
628 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700629
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700630 private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700631 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700632 final UserState uss = mStartedUsers.get(userId);
633 if (uss == null) {
634 // User is not started, nothing to do... but we do need to
635 // callback if requested.
636 if (callback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700637 mHandler.post(() -> {
638 try {
639 callback.userStopped(userId);
640 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700641 }
642 });
643 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700644 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700645 }
646
647 if (callback != null) {
648 uss.mStopCallbacks.add(callback);
649 }
650
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700651 if (uss.state != UserState.STATE_STOPPING
652 && uss.state != UserState.STATE_SHUTDOWN) {
653 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700654 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700655 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700656
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700657 // Post to handler to obtain amLock
658 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700659 // We are going to broadcast ACTION_USER_STOPPING and then
660 // once that is done send a final ACTION_SHUTDOWN and then
661 // stop the user.
662 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
663 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
664 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
665 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666 // This is the result receiver for the initial stopping broadcast.
667 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
668 @Override
669 public void performReceive(Intent intent, int resultCode, String data,
670 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700671 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700672 }
673 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700674
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700675 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700676 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700677 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700678 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700679 null, stoppingReceiver, 0, null, null,
680 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700681 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700682 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700683 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700684 }
685
Amith Yamasani98c05562016-03-30 13:15:26 -0700686 void finishUserStopping(final int userId, final UserState uss) {
687 // On to the next.
688 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
689 // This is the result receiver for the final shutdown broadcast.
690 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
691 @Override
692 public void performReceive(Intent intent, int resultCode, String data,
693 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
694 mHandler.post(new Runnable() {
695 @Override
696 public void run() {
697 finishUserStopped(uss);
698 }
699 });
700 }
701 };
702
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700703 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700704 if (uss.state != UserState.STATE_STOPPING) {
705 // Whoops, we are being started back up. Abort, abort!
706 return;
707 }
708 uss.setState(UserState.STATE_SHUTDOWN);
709 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700710 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700711
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700712 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700713 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
714 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700715 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700716
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700717 mInjector.broadcastIntent(shutdownIntent,
718 null, shutdownReceiver, 0, null, null, null,
719 AppOpsManager.OP_NONE,
720 null, true, false, MY_PID, SYSTEM_UID, userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700721 }
722
723 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700724 final int userId = uss.mHandle.getIdentifier();
Pavel Grafov634c34e2018-04-10 19:19:01 +0100725 final boolean stopped;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700727 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700728 callbacks = new ArrayList<>(uss.mStopCallbacks);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100729 if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700730 stopped = false;
731 } else {
732 stopped = true;
733 // User can no longer run.
734 mStartedUsers.remove(userId);
735 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700736 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700737 }
738 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100739
740 if (stopped) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700741 mInjector.getUserManagerInternal().removeUserState(userId);
742 mInjector.activityManagerOnUserStopped(userId);
743 // Clean up all state and processes associated with the user.
744 // Kill all the processes for the user.
745 forceStopUser(userId, "finish user");
746 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700747
748 for (int i = 0; i < callbacks.size(); i++) {
749 try {
750 if (stopped) callbacks.get(i).userStopped(userId);
751 else callbacks.get(i).userStopAborted(userId);
752 } catch (RemoteException e) {
753 }
754 }
755
756 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700757 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700758 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100759 // Remove the user if it is ephemeral.
760 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000761 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100762 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100763
764 // Evict the user's credential encryption key. Performed on FgThread to make it
765 // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
766 // to prevent data corruption.
767 FgThread.getHandler().post(() -> {
768 synchronized (mLock) {
769 if (mStartedUsers.get(userId) != null) {
770 Slog.w(TAG, "User was restarted, skipping key eviction");
771 return;
772 }
773 }
774 try {
775 getStorageManager().lockUserKey(userId);
776 } catch (RemoteException re) {
777 throw re.rethrowAsRuntimeException();
778 }
779 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700780 }
781 }
782
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700783 /**
784 * Determines the list of users that should be stopped together with the specified
785 * {@code userId}. The returned list includes {@code userId}.
786 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700787 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700788 int startedUsersSize = mStartedUsers.size();
789 IntArray userIds = new IntArray();
790 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700791 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
792 for (int i = 0; i < startedUsersSize; i++) {
793 UserState uss = mStartedUsers.valueAt(i);
794 int startedUserId = uss.mHandle.getIdentifier();
795 // Skip unrelated users (profileGroupId mismatch)
796 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700797 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700798 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
799 && (userGroupId == startedUserGroupId);
800 // userId has already been added
801 boolean sameUserId = startedUserId == userId;
802 if (!sameGroup || sameUserId) {
803 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700804 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700805 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700806 }
807 return userIds.toArray();
808 }
809
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700810 private void forceStopUser(int userId, String reason) {
811 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700812 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
813 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
814 | Intent.FLAG_RECEIVER_FOREGROUND);
815 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700816 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700817 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700818 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700819 }
820
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700821 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100822 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700823 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000824 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
825 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000826 synchronized(mLock) {
827 UserState oldUss = mStartedUsers.get(oldUserId);
828 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
829 || oldUss.state == UserState.STATE_STOPPING
830 || oldUss.state == UserState.STATE_SHUTDOWN) {
831 return;
832 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700833 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000834
835 UserInfo userInfo = getUserInfo(oldUserId);
836 if (userInfo.isEphemeral()) {
837 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
838 }
839 if (userInfo.isGuest() || userInfo.isEphemeral()) {
840 // This is a user to be stopped.
841 synchronized (mLock) {
842 stopUsersLU(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700843 }
844 }
845 }
846
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700847 void scheduleStartProfiles() {
Pavel Grafovac7c8ae2018-09-20 15:03:47 +0100848 // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
849 // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
850 // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
851 // after the parent had chance to unlock fully.
852 FgThread.getHandler().post(() -> {
853 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
854 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
855 DateUtils.SECOND_IN_MILLIS);
856 }
857 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700858 }
859
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700860 void startProfiles() {
861 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700862 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700863 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700864 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700865 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
866 for (UserInfo user : profiles) {
867 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700868 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700869 profilesToStart.add(user);
870 }
871 }
872 final int profilesToStartSize = profilesToStart.size();
873 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700874 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700875 startUser(profilesToStart.get(i).id, /* foreground= */ false);
876 }
877 if (i < profilesToStartSize) {
878 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
879 }
880 }
881
Sudheer Shanka2250d562016-11-07 15:41:02 -0800882 private IStorageManager getStorageManager() {
883 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700884 }
Tony Mak64fd8c02017-12-01 19:11:59 +0000885 boolean startUser(final int userId, final boolean foreground) {
886 return startUser(userId, foreground, null);
887 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700888
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700889 /**
890 * Start user, if its not already running.
891 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
892 * When starting the user, multiple intents will be broadcast in the following order:</p>
893 * <ul>
894 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
895 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
896 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
897 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
898 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
899 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
900 * Sent only if {@code foreground} parameter is true
901 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
902 * of the new fg user
903 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
904 * the new user
905 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
906 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
907 * new user. Sent only when the user is booting after a system update.
908 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
909 * new user. Sent only the first time a user is starting.
910 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
911 * user. Indicates that the user has finished booting.
912 * </ul>
913 *
914 * @param userId ID of the user to start
915 * @param foreground true if user should be brought to the foreground
916 * @return true if the user has been successfully started
917 */
Tony Mak64fd8c02017-12-01 19:11:59 +0000918 boolean startUser(
919 final int userId,
920 final boolean foreground,
921 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700922 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700923 != PackageManager.PERMISSION_GRANTED) {
924 String msg = "Permission Denial: switchUser() from pid="
925 + Binder.getCallingPid()
926 + ", uid=" + Binder.getCallingUid()
927 + " requires " + INTERACT_ACROSS_USERS_FULL;
928 Slog.w(TAG, msg);
929 throw new SecurityException(msg);
930 }
931
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700932 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700933
934 final long ident = Binder.clearCallingIdentity();
935 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700936 final int oldUserId = getCurrentUserId();
937 if (oldUserId == userId) {
938 return true;
939 }
940
941 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100942 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700943 }
944
945 final UserInfo userInfo = getUserInfo(userId);
946 if (userInfo == null) {
947 Slog.w(TAG, "No user info for user #" + userId);
948 return false;
949 }
950 if (foreground && userInfo.isManagedProfile()) {
951 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
952 return false;
953 }
954
955 if (foreground && mUserSwitchUiEnabled) {
956 mInjector.getWindowManager().startFreezingScreen(
957 R.anim.screen_user_exit, R.anim.screen_user_enter);
958 }
959
960 boolean needStart = false;
961 boolean updateUmState = false;
962 UserState uss;
963
964 // If the user we are switching to is not currently started, then
965 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700966 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700967 uss = mStartedUsers.get(userId);
968 if (uss == null) {
969 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700970 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700971 mStartedUsers.put(userId, uss);
972 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700973 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700974 updateUmState = true;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -0700975 } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
976 Slog.i(TAG, "User #" + userId
977 + " is shutting down - will start after full stop");
978 mHandler.post(() -> startUser(userId, foreground, unlockListener));
979 return true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700980 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700981 final Integer userIdInt = userId;
982 mUserLru.remove(userIdInt);
983 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +0000984 }
985 if (unlockListener != null) {
986 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700987 }
988 if (updateUmState) {
989 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
990 }
991 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -0800992 // Make sure the old user is no longer considering the display to be on.
993 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700994 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700995 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700996 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700997 }
998 mInjector.updateUserConfiguration();
999 updateCurrentProfileIds();
1000 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -08001001 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001002 // Once the internal notion of the active user has switched, we lock the device
1003 // with the option to show the user switcher on the keyguard.
1004 if (mUserSwitchUiEnabled) {
1005 mInjector.getWindowManager().setSwitchingUser(true);
1006 mInjector.getWindowManager().lockNow(null);
1007 }
1008 } else {
1009 final Integer currentUserIdInt = mCurrentUserId;
1010 updateCurrentProfileIds();
1011 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
1012 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001013 mUserLru.remove(currentUserIdInt);
1014 mUserLru.add(currentUserIdInt);
1015 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001016 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001017
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001018 // Make sure user is in the started state. If it is currently
1019 // stopping, we need to knock that off.
1020 if (uss.state == UserState.STATE_STOPPING) {
1021 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
1022 // so we can just fairly silently bring the user back from
1023 // the almost-dead.
1024 uss.setState(uss.lastState);
1025 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1026 synchronized (mLock) {
1027 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001028 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001029 needStart = true;
1030 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1031 // This means ACTION_SHUTDOWN has been sent, so we will
1032 // need to treat this as a new boot of the user.
1033 uss.setState(UserState.STATE_BOOTING);
1034 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1035 synchronized (mLock) {
1036 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001037 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001038 needStart = true;
1039 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001040
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001041 if (uss.state == UserState.STATE_BOOTING) {
1042 // Give user manager a chance to propagate user restrictions
1043 // to other services and prepare app storage
1044 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001045
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001046 // Booting up a new user, need to tell system services about it.
1047 // Note that this is on the same handler as scheduling of broadcasts,
1048 // which is important because it needs to go first.
1049 mHandler.sendMessage(
1050 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1051 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001052
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001053 if (foreground) {
1054 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1055 oldUserId));
1056 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1057 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1058 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1059 oldUserId, userId, uss));
1060 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1061 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1062 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001063
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001064 if (needStart) {
1065 // Send USER_STARTED broadcast
1066 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1068 | Intent.FLAG_RECEIVER_FOREGROUND);
1069 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1070 mInjector.broadcastIntent(intent,
1071 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1072 null, false, false, MY_PID, SYSTEM_UID, userId);
1073 }
1074
1075 if (foreground) {
1076 moveUserToForeground(uss, oldUserId, userId);
1077 } else {
1078 finishUserBoot(uss);
1079 }
1080
1081 if (needStart) {
1082 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1083 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1084 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1085 mInjector.broadcastIntent(intent,
1086 null, new IIntentReceiver.Stub() {
1087 @Override
1088 public void performReceive(Intent intent, int resultCode,
1089 String data, Bundle extras, boolean ordered,
1090 boolean sticky,
1091 int sendingUser) throws RemoteException {
1092 }
1093 }, 0, null, null,
1094 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
1095 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001096 }
1097 } finally {
1098 Binder.restoreCallingIdentity(ident);
1099 }
1100
1101 return true;
1102 }
1103
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001104 private boolean isCallingOnHandlerThread() {
1105 return Looper.myLooper() == mHandler.getLooper();
1106 }
1107
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001108 /**
1109 * Start user, if its not already running, and bring it to foreground.
1110 */
Evan Rosky18396452016-07-27 15:19:37 -07001111 void startUserInForeground(final int targetUserId) {
1112 boolean success = startUser(targetUserId, /* foreground */ true);
1113 if (!success) {
1114 mInjector.getWindowManager().setSwitchingUser(false);
1115 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001116 }
1117
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001118 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001119 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001120 != PackageManager.PERMISSION_GRANTED) {
1121 String msg = "Permission Denial: unlockUser() from pid="
1122 + Binder.getCallingPid()
1123 + ", uid=" + Binder.getCallingUid()
1124 + " requires " + INTERACT_ACROSS_USERS_FULL;
1125 Slog.w(TAG, msg);
1126 throw new SecurityException(msg);
1127 }
1128
Jeff Sharkey8924e872015-11-30 12:52:10 -07001129 final long binderToken = Binder.clearCallingIdentity();
1130 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001131 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001132 } finally {
1133 Binder.restoreCallingIdentity(binderToken);
1134 }
1135 }
1136
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001137 /**
1138 * Attempt to unlock user without a credential token. This typically
1139 * succeeds when the device doesn't have credential-encrypted storage, or
1140 * when the the credential-encrypted storage isn't tied to a user-provided
1141 * PIN or pattern.
1142 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001143 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001144 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001145 return unlockUserCleared(userId, null, null, null);
1146 }
1147
1148 private static void notifyFinished(int userId, IProgressListener listener) {
1149 if (listener == null) return;
1150 try {
1151 listener.onFinished(userId, null);
1152 } catch (RemoteException ignored) {
1153 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001154 }
1155
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001156 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001157 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001158 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001159 if (!StorageManager.isUserKeyUnlocked(userId)) {
1160 final UserInfo userInfo = getUserInfo(userId);
1161 final IStorageManager storageManager = getStorageManager();
1162 try {
1163 // We always want to unlock user storage, even user is not started yet
1164 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1165 } catch (RemoteException | RuntimeException e) {
1166 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001167 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001168 }
1169 synchronized (mLock) {
1170 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001171 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001172 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001173 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001174 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001175 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001176 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001177 // Bail if user isn't actually running
1178 if (uss == null) {
1179 notifyFinished(userId, listener);
1180 return false;
1181 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001182
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001183 finishUserUnlocking(uss);
1184
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001185 // We just unlocked a user, so let's now attempt to unlock any
1186 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001187
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001188 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1189 int[] userIds;
1190 synchronized (mLock) {
1191 userIds = new int[mStartedUsers.size()];
1192 for (int i = 0; i < userIds.length; i++) {
1193 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001194 }
1195 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001196 for (int testUserId : userIds) {
1197 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1198 if (parent != null && parent.id == userId && testUserId != userId) {
1199 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1200 + "): attempting unlock because parent was just unlocked");
1201 maybeUnlockUser(testUserId);
1202 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001203 }
1204
Jeff Sharkeyba512352015-11-12 20:17:45 -08001205 return true;
1206 }
1207
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001208 boolean switchUser(final int targetUserId) {
1209 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001210 int currentUserId = getCurrentUserId();
1211 UserInfo targetUserInfo = getUserInfo(targetUserId);
1212 if (targetUserId == currentUserId) {
1213 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1214 return true;
1215 }
1216 if (targetUserInfo == null) {
1217 Slog.w(TAG, "No user info for user #" + targetUserId);
1218 return false;
1219 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001220 if (!targetUserInfo.supportsSwitchTo()) {
1221 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1222 return false;
1223 }
1224 if (targetUserInfo.isManagedProfile()) {
1225 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1226 return false;
1227 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001228 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001229 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001230 }
1231 if (mUserSwitchUiEnabled) {
1232 UserInfo currentUserInfo = getUserInfo(currentUserId);
1233 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1234 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1235 mUiHandler.sendMessage(mHandler.obtainMessage(
1236 START_USER_SWITCH_UI_MSG, userNames));
1237 } else {
1238 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1239 mHandler.sendMessage(mHandler.obtainMessage(
1240 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1241 }
1242 return true;
1243 }
1244
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001245 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001246 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001247 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1248 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001249 }
1250
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001251 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001252 final int observerCount = mUserSwitchObservers.beginBroadcast();
1253 for (int i = 0; i < observerCount; i++) {
1254 try {
1255 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1256 } catch (RemoteException e) {
1257 // Ignore
1258 }
1259 }
1260 mUserSwitchObservers.finishBroadcast();
1261 }
1262
1263 /** Called on handler thread */
1264 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001265 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001266 final int observerCount = mUserSwitchObservers.beginBroadcast();
1267 for (int i = 0; i < observerCount; i++) {
1268 try {
1269 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1270 } catch (RemoteException e) {
1271 }
1272 }
1273 mUserSwitchObservers.finishBroadcast();
1274 }
1275
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001276 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001277 final int observerCount = mUserSwitchObservers.beginBroadcast();
1278 for (int i = 0; i < observerCount; i++) {
1279 try {
1280 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1281 } catch (RemoteException e) {
1282 // Ignore
1283 }
1284 }
1285 mUserSwitchObservers.finishBroadcast();
1286 }
1287
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001288 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1289 // Never stop system user
1290 if (oldUserId == UserHandle.USER_SYSTEM) {
1291 return;
1292 }
1293 // For now, only check for user restriction. Additional checks can be added here
1294 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1295 oldUserId);
1296 if (!disallowRunInBg) {
1297 return;
1298 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001299 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001300 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1301 + " and related users");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001302 stopUsersLU(oldUserId, false, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001303 }
1304 }
1305
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001306 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001307 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001308 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1309 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1310 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001311 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001312 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1313 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1314 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1315 }
1316 }
1317
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001318 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001319 synchronized (mLock) {
1320 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1321 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1322 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1323 mTimeoutUserSwitchCallbacks = null;
1324 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001325 }
1326 }
1327
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001328 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1329 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001330 final int observerCount = mUserSwitchObservers.beginBroadcast();
1331 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001332 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001333 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001334 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001335 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001336 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001337 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001338 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001339 for (int i = 0; i < observerCount; i++) {
1340 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001341 // Prepend with unique prefix to guarantee that keys are unique
1342 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001343 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001344 curWaitingUserSwitchCallbacks.add(name);
1345 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001346 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1347 @Override
1348 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001349 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001350 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001351 if (delay > USER_SWITCH_TIMEOUT_MS) {
1352 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001353 + " sent result after " + delay + " ms");
1354 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001355 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001356 // Continue switching if all callbacks have been notified and
1357 // user switching session is still valid
1358 if (waitingCallbacksCount.decrementAndGet() == 0
1359 && (curWaitingUserSwitchCallbacks
1360 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001361 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001362 }
1363 }
1364 }
1365 };
1366 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001367 } catch (RemoteException e) {
1368 }
1369 }
1370 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001371 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001372 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001373 }
1374 }
1375 mUserSwitchObservers.finishBroadcast();
1376 }
1377
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001378 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001379 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001380 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001381 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001382 oldUserId, newUserId, uss));
1383 }
1384
1385 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001386 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001387 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001388 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001389 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001390 uss.switching = false;
1391 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1392 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1393 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001394 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001395 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001396 }
1397
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001398 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1399 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001400 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001401 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001402 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001403 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001404 }
1405 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001406 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001407 }
1408
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001409 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001410 long ident = Binder.clearCallingIdentity();
1411 try {
1412 Intent intent;
1413 if (oldUserId >= 0) {
1414 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001415 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001416 int count = profiles.size();
1417 for (int i = 0; i < count; i++) {
1418 int profileUserId = profiles.get(i).id;
1419 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1420 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1421 | Intent.FLAG_RECEIVER_FOREGROUND);
1422 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001423 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001424 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1425 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1426 }
1427 }
1428 if (newUserId >= 0) {
1429 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001430 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001431 int count = profiles.size();
1432 for (int i = 0; i < count; i++) {
1433 int profileUserId = profiles.get(i).id;
1434 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1435 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1436 | Intent.FLAG_RECEIVER_FOREGROUND);
1437 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001438 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001439 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1440 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1441 }
1442 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1444 | Intent.FLAG_RECEIVER_FOREGROUND);
1445 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001446 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001447 null, null, 0, null, null,
1448 new String[] {android.Manifest.permission.MANAGE_USERS},
1449 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1450 UserHandle.USER_ALL);
1451 }
1452 } finally {
1453 Binder.restoreCallingIdentity(ident);
1454 }
1455 }
1456
1457
1458 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1459 int allowMode, String name, String callerPackage) {
1460 final int callingUserId = UserHandle.getUserId(callingUid);
1461 if (callingUserId == userId) {
1462 return userId;
1463 }
1464
1465 // Note that we may be accessing mCurrentUserId outside of a lock...
1466 // shouldn't be a big deal, if this is being called outside
1467 // of a locked context there is intrinsically a race with
1468 // the value the caller will receive and someone else changing it.
1469 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1470 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001471 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001472
1473 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1474 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001475 if (mInjector.isCallerRecents(callingUid)
1476 && callingUserId == getCurrentUserId()
1477 && isSameProfileGroup(callingUserId, targetUserId)) {
1478 // If the caller is Recents and it is running in the current user, we then allow it
1479 // to access its profiles.
1480 allow = true;
1481 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001482 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1483 // If the caller has this permission, they always pass go. And collect $200.
1484 allow = true;
1485 } else if (allowMode == ALLOW_FULL_ONLY) {
1486 // We require full access, sucks to be you.
1487 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001488 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001489 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1490 // If the caller does not have either permission, they are always doomed.
1491 allow = false;
1492 } else if (allowMode == ALLOW_NON_FULL) {
1493 // We are blanket allowing non-full access, you lucky caller!
1494 allow = true;
1495 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1496 // We may or may not allow this depending on whether the two users are
1497 // in the same profile.
1498 allow = isSameProfileGroup(callingUserId, targetUserId);
1499 } else {
1500 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1501 }
1502 if (!allow) {
1503 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1504 // In this case, they would like to just execute as their
1505 // owner user instead of failing.
1506 targetUserId = callingUserId;
1507 } else {
1508 StringBuilder builder = new StringBuilder(128);
1509 builder.append("Permission Denial: ");
1510 builder.append(name);
1511 if (callerPackage != null) {
1512 builder.append(" from ");
1513 builder.append(callerPackage);
1514 }
1515 builder.append(" asks to run as user ");
1516 builder.append(userId);
1517 builder.append(" but is calling from user ");
1518 builder.append(UserHandle.getUserId(callingUid));
1519 builder.append("; this requires ");
1520 builder.append(INTERACT_ACROSS_USERS_FULL);
1521 if (allowMode != ALLOW_FULL_ONLY) {
1522 builder.append(" or ");
1523 builder.append(INTERACT_ACROSS_USERS);
1524 }
1525 String msg = builder.toString();
1526 Slog.w(TAG, msg);
1527 throw new SecurityException(msg);
1528 }
1529 }
1530 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001531 if (!allowAll) {
1532 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001533 }
1534 // Check shell permission
1535 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1536 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1537 throw new SecurityException("Shell does not have permission to access user "
1538 + targetUserId + "\n " + Debug.getCallers(3));
1539 }
1540 }
1541 return targetUserId;
1542 }
1543
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001544 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001545 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001546 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001547 }
1548
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001549 void ensureNotSpecialUser(int userId) {
1550 if (userId >= 0) {
1551 return;
1552 }
1553 throw new IllegalArgumentException("Call does not support special user #" + userId);
1554 }
1555
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001556 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1557 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001558 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001559 != PackageManager.PERMISSION_GRANTED) {
1560 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1561 + Binder.getCallingPid()
1562 + ", uid=" + Binder.getCallingUid()
1563 + " requires " + INTERACT_ACROSS_USERS_FULL;
1564 Slog.w(TAG, msg);
1565 throw new SecurityException(msg);
1566 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001567 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001568 }
1569
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001570 void sendForegroundProfileChanged(int userId) {
1571 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1572 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1573 }
1574
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001575 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1576 mUserSwitchObservers.unregister(observer);
1577 }
1578
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001579 UserState getStartedUserState(int userId) {
1580 synchronized (mLock) {
1581 return mStartedUsers.get(userId);
1582 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001583 }
1584
1585 boolean hasStartedUserState(int userId) {
1586 return mStartedUsers.get(userId) != null;
1587 }
1588
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001589 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001590 int num = 0;
1591 for (int i = 0; i < mStartedUsers.size(); i++) {
1592 UserState uss = mStartedUsers.valueAt(i);
1593 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001594 if (uss.state != UserState.STATE_STOPPING
1595 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001596 num++;
1597 }
1598 }
1599 mStartedUserArray = new int[num];
1600 num = 0;
1601 for (int i = 0; i < mStartedUsers.size(); i++) {
1602 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001603 if (uss.state != UserState.STATE_STOPPING
1604 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001605 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001606 }
1607 }
1608 }
1609
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001610 void sendBootCompleted(IIntentReceiver resultTo) {
1611 // Get a copy of mStartedUsers to use outside of lock
1612 SparseArray<UserState> startedUsers;
1613 synchronized (mLock) {
1614 startedUsers = mStartedUsers.clone();
1615 }
1616 for (int i = 0; i < startedUsers.size(); i++) {
1617 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001618 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001619 }
1620 }
1621
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001622 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001623 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001624 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001625 }
1626
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001627 /**
1628 * Refreshes the list of users related to the current user when either a
1629 * user switch happens or when a new related user is started in the
1630 * background.
1631 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001632 private void updateCurrentProfileIds() {
1633 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001634 false /* enabledOnly */);
1635 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1636 for (int i = 0; i < currentProfileIds.length; i++) {
1637 currentProfileIds[i] = profiles.get(i).id;
1638 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001639 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1640 synchronized (mLock) {
1641 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001642
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001643 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001644 for (int i = 0; i < users.size(); i++) {
1645 UserInfo user = users.get(i);
1646 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001647 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001648 }
1649 }
1650 }
1651 }
1652
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001653 int[] getStartedUserArray() {
1654 synchronized (mLock) {
1655 return mStartedUserArray;
1656 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001657 }
1658
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001659 boolean isUserRunning(int userId, int flags) {
1660 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001661 if (state == null) {
1662 return false;
1663 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001664 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001665 return true;
1666 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001667 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001668 switch (state.state) {
1669 case UserState.STATE_BOOTING:
1670 case UserState.STATE_RUNNING_LOCKED:
1671 return true;
1672 default:
1673 return false;
1674 }
1675 }
1676 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1677 switch (state.state) {
1678 case UserState.STATE_RUNNING_UNLOCKING:
1679 case UserState.STATE_RUNNING_UNLOCKED:
1680 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001681 // In the stopping/shutdown state return unlock state of the user key
1682 case UserState.STATE_STOPPING:
1683 case UserState.STATE_SHUTDOWN:
1684 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001685 default:
1686 return false;
1687 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001688 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001689 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001690 switch (state.state) {
1691 case UserState.STATE_RUNNING_UNLOCKED:
1692 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001693 // In the stopping/shutdown state return unlock state of the user key
1694 case UserState.STATE_STOPPING:
1695 case UserState.STATE_SHUTDOWN:
1696 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001697 default:
1698 return false;
1699 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001700 }
1701
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001702 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001703 }
1704
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001705 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001706 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001707 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001708 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001709 != PackageManager.PERMISSION_GRANTED)) {
1710 String msg = "Permission Denial: getCurrentUser() from pid="
1711 + Binder.getCallingPid()
1712 + ", uid=" + Binder.getCallingUid()
1713 + " requires " + INTERACT_ACROSS_USERS;
1714 Slog.w(TAG, msg);
1715 throw new SecurityException(msg);
1716 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001717
1718 // Optimization - if there is no pending user switch, return current id
1719 if (mTargetUserId == UserHandle.USER_NULL) {
1720 return getUserInfo(mCurrentUserId);
1721 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001722 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001723 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001724 }
1725 }
1726
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001727 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001728 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001729 return getUserInfo(userId);
1730 }
1731
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001732 int getCurrentOrTargetUserId() {
1733 synchronized (mLock) {
1734 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1735 }
1736 }
1737
1738 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001739 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001740 }
1741
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001742
1743 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001744 return mCurrentUserId;
1745 }
1746
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001747 int getCurrentUserId() {
1748 synchronized (mLock) {
1749 return mCurrentUserId;
1750 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001751 }
1752
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001753 private boolean isCurrentUserLU(int userId) {
1754 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001755 }
1756
1757 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001758 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001759 return ums != null ? ums.getUserIds() : new int[] { 0 };
1760 }
1761
1762 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001763 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001764 }
1765
1766 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001767 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001768 }
1769
Makoto Onuki6569c362018-02-27 15:52:01 -08001770 /**
1771 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1772 * IDs. Otherwise return an array whose only element is the given user id.
1773 *
1774 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1775 */
1776 int[] expandUserId(int userId) {
1777 if (userId != UserHandle.USER_ALL) {
1778 return new int[] {userId};
1779 } else {
1780 return getUsers();
1781 }
1782 }
1783
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001784 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001785 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001786 }
1787
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001788 void enforceShellRestriction(String restriction, int userHandle) {
1789 if (Binder.getCallingUid() == SHELL_UID) {
1790 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1791 throw new SecurityException("Shell does not have permission to access user "
1792 + userHandle);
1793 }
1794 }
1795 }
1796
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001797 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001798 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001799 }
1800
1801 Set<Integer> getProfileIds(int userId) {
1802 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001803 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001804 false /* enabledOnly */);
1805 for (UserInfo user : profiles) {
1806 userIds.add(user.id);
1807 }
1808 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001809 }
1810
1811 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001812 if (callingUserId == targetUserId) {
1813 return true;
1814 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001815 synchronized (mLock) {
1816 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001817 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001818 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001819 UserInfo.NO_PROFILE_GROUP_ID);
1820 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1821 && callingProfile == targetProfile;
1822 }
1823 }
1824
Tony Mak60f53e62017-12-21 20:03:29 +00001825 boolean isUserOrItsParentRunning(int userId) {
1826 synchronized (mLock) {
1827 if (isUserRunning(userId, 0)) {
1828 return true;
1829 }
1830 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1831 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1832 return false;
1833 }
1834 return isUserRunning(parentUserId, 0);
1835 }
1836 }
1837
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001838 boolean isCurrentProfile(int userId) {
1839 synchronized (mLock) {
1840 return ArrayUtils.contains(mCurrentProfileIds, userId);
1841 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001842 }
1843
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001844 int[] getCurrentProfileIds() {
1845 synchronized (mLock) {
1846 return mCurrentProfileIds;
1847 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001848 }
1849
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001850 void onUserRemoved(int userId) {
1851 synchronized (mLock) {
1852 int size = mUserProfileGroupIds.size();
1853 for (int i = size - 1; i >= 0; i--) {
1854 if (mUserProfileGroupIds.keyAt(i) == userId
1855 || mUserProfileGroupIds.valueAt(i) == userId) {
1856 mUserProfileGroupIds.removeAt(i);
1857
1858 }
1859 }
1860 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1861 }
1862 }
1863
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001864 /**
1865 * Returns whether the given user requires credential entry at this time. This is used to
1866 * intercept activity launches for work apps when the Work Challenge is present.
1867 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001868 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001869 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001870 if (mStartedUsers.get(userId) == null) {
1871 return false;
1872 }
1873 }
Clara Bayarria1771112015-12-18 16:29:18 +00001874 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001875 return false;
1876 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001877 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001878 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001879 }
1880
Tony Mak8c536f92016-03-21 12:20:41 +00001881 boolean isLockScreenDisabled(@UserIdInt int userId) {
1882 return mLockPatternUtils.isLockScreenDisabled(userId);
1883 }
1884
Alex Chau93ae42b2018-01-11 15:10:12 +00001885 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
1886 synchronized (mLock) {
1887 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
1888 }
1889 }
1890
1891 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
1892 synchronized (mLock) {
1893 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
1894 }
1895 }
1896
1897 private String getSwitchingFromSystemUserMessage() {
1898 synchronized (mLock) {
1899 return mSwitchingFromSystemUserMessage;
1900 }
1901 }
1902
1903 private String getSwitchingToSystemUserMessage() {
1904 synchronized (mLock) {
1905 return mSwitchingToSystemUserMessage;
1906 }
1907 }
1908
Yi Jin148d7f42017-11-28 14:23:56 -08001909 void writeToProto(ProtoOutputStream proto, long fieldId) {
1910 synchronized (mLock) {
1911 long token = proto.start(fieldId);
1912 for (int i = 0; i < mStartedUsers.size(); i++) {
1913 UserState uss = mStartedUsers.valueAt(i);
1914 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
1915 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
1916 uss.writeToProto(proto, UserControllerProto.User.STATE);
1917 proto.end(uToken);
1918 }
1919 for (int i = 0; i < mStartedUserArray.length; i++) {
1920 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
1921 }
1922 for (int i = 0; i < mUserLru.size(); i++) {
1923 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
1924 }
1925 if (mUserProfileGroupIds.size() > 0) {
1926 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
1927 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
1928 proto.write(UserControllerProto.UserProfile.USER,
1929 mUserProfileGroupIds.keyAt(i));
1930 proto.write(UserControllerProto.UserProfile.PROFILE,
1931 mUserProfileGroupIds.valueAt(i));
1932 proto.end(uToken);
1933 }
1934 }
1935 proto.end(token);
1936 }
1937 }
1938
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001939 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001940 synchronized (mLock) {
1941 pw.println(" mStartedUsers:");
1942 for (int i = 0; i < mStartedUsers.size(); i++) {
1943 UserState uss = mStartedUsers.valueAt(i);
1944 pw.print(" User #");
1945 pw.print(uss.mHandle.getIdentifier());
1946 pw.print(": ");
1947 uss.dump("", pw);
1948 }
1949 pw.print(" mStartedUserArray: [");
1950 for (int i = 0; i < mStartedUserArray.length; i++) {
1951 if (i > 0)
1952 pw.print(", ");
1953 pw.print(mStartedUserArray[i]);
1954 }
1955 pw.println("]");
1956 pw.print(" mUserLru: [");
1957 for (int i = 0; i < mUserLru.size(); i++) {
1958 if (i > 0)
1959 pw.print(", ");
1960 pw.print(mUserLru.get(i));
1961 }
1962 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001963 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001964 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001965 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001966 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001967 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001968 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001969 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001970 }
1971 }
1972 }
1973 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001974
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001975 public boolean handleMessage(Message msg) {
1976 switch (msg.what) {
1977 case START_USER_SWITCH_FG_MSG:
1978 startUserInForeground(msg.arg1);
1979 break;
1980 case REPORT_USER_SWITCH_MSG:
1981 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1982 break;
1983 case CONTINUE_USER_SWITCH_MSG:
1984 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1985 break;
1986 case USER_SWITCH_TIMEOUT_MSG:
1987 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1988 break;
1989 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
1990 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
1991 break;
1992 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001993 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001994 break;
1995 case SYSTEM_USER_START_MSG:
1996 mInjector.batteryStatsServiceNoteEvent(
1997 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1998 Integer.toString(msg.arg1), msg.arg1);
1999 mInjector.getSystemServiceManager().startUser(msg.arg1);
2000 break;
2001 case SYSTEM_USER_UNLOCK_MSG:
2002 final int userId = msg.arg1;
2003 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08002004 // Loads recents on a worker thread that allows disk I/O
2005 FgThread.getHandler().post(() -> {
2006 mInjector.loadUserRecents(userId);
2007 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002008 finishUserUnlocked((UserState) msg.obj);
2009 break;
2010 case SYSTEM_USER_CURRENT_MSG:
2011 mInjector.batteryStatsServiceNoteEvent(
2012 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2013 Integer.toString(msg.arg2), msg.arg2);
2014 mInjector.batteryStatsServiceNoteEvent(
2015 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2016 Integer.toString(msg.arg1), msg.arg1);
2017
2018 mInjector.getSystemServiceManager().switchUser(msg.arg1);
2019 break;
2020 case FOREGROUND_PROFILE_CHANGED_MSG:
2021 dispatchForegroundProfileChanged(msg.arg1);
2022 break;
2023 case REPORT_USER_SWITCH_COMPLETE_MSG:
2024 dispatchUserSwitchComplete(msg.arg1);
2025 break;
2026 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
2027 dispatchLockedBootComplete(msg.arg1);
2028 break;
2029 case START_USER_SWITCH_UI_MSG:
2030 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2031 break;
2032 }
2033 return false;
2034 }
2035
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002036 private static class UserProgressListener extends IProgressListener.Stub {
2037 private volatile long mUnlockStarted;
2038 @Override
2039 public void onStarted(int id, Bundle extras) throws RemoteException {
2040 Slog.d(TAG, "Started unlocking user " + id);
2041 mUnlockStarted = SystemClock.uptimeMillis();
2042 }
2043
2044 @Override
2045 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2046 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2047 }
2048
2049 @Override
2050 public void onFinished(int id, Bundle extras) throws RemoteException {
2051 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2052
2053 // Report system user unlock time to perf dashboard
2054 if (id == UserHandle.USER_SYSTEM) {
2055 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2056 .logDuration("SystemUserUnlock", unlockTime);
2057 } else {
2058 Slog.d(TAG, "Unlocking user " + id + " took " + unlockTime + " ms");
2059 }
2060 }
2061 };
2062
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002063 @VisibleForTesting
2064 static class Injector {
2065 private final ActivityManagerService mService;
2066 private UserManagerService mUserManager;
2067 private UserManagerInternal mUserManagerInternal;
2068
2069 Injector(ActivityManagerService service) {
2070 mService = service;
2071 }
2072
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002073 protected Handler getHandler(Handler.Callback callback) {
2074 return new Handler(mService.mHandlerThread.getLooper(), callback);
2075 }
2076
2077 protected Handler getUiHandler(Handler.Callback callback) {
2078 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002079 }
2080
2081 protected Context getContext() {
2082 return mService.mContext;
2083 }
2084
2085 protected LockPatternUtils getLockPatternUtils() {
2086 return new LockPatternUtils(getContext());
2087 }
2088
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002089 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002090 IIntentReceiver resultTo, int resultCode, String resultData,
2091 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
2092 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002093 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2094 synchronized (mService) {
2095 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2096 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
2097 ordered, sticky, callingPid, callingUid, userId);
2098 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002099 }
2100
2101 int checkCallingPermission(String permission) {
2102 return mService.checkCallingPermission(permission);
2103 }
2104
2105 WindowManagerService getWindowManager() {
2106 return mService.mWindowManager;
2107 }
2108 void activityManagerOnUserStopped(int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002109 synchronized (mService) {
2110 mService.onUserStoppedLocked(userId);
2111 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002112 }
2113
2114 void systemServiceManagerCleanupUser(int userId) {
2115 mService.mSystemServiceManager.cleanupUser(userId);
2116 }
2117
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002118 protected UserManagerService getUserManager() {
2119 if (mUserManager == null) {
2120 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2121 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2122 }
2123 return mUserManager;
2124 }
2125
2126 UserManagerInternal getUserManagerInternal() {
2127 if (mUserManagerInternal == null) {
2128 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2129 }
2130 return mUserManagerInternal;
2131 }
2132
2133 KeyguardManager getKeyguardManager() {
2134 return mService.mContext.getSystemService(KeyguardManager.class);
2135 }
2136
2137 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2138 mService.mBatteryStatsService.noteEvent(code, name, uid);
2139 }
2140
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002141 boolean isRuntimeRestarted() {
2142 return mService.mSystemServiceManager.isRuntimeRestarted();
2143 }
2144
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002145 SystemServiceManager getSystemServiceManager() {
2146 return mService.mSystemServiceManager;
2147 }
2148
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002149 boolean isFirstBootOrUpgrade() {
2150 IPackageManager pm = AppGlobals.getPackageManager();
2151 try {
2152 return pm.isFirstBoot() || pm.isUpgrade();
2153 } catch (RemoteException e) {
2154 throw e.rethrowFromSystemServer();
2155 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002156 }
2157
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002158 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2159 new PreBootBroadcaster(mService, userId, null, quiet) {
2160 @Override
2161 public void onFinished() {
2162 onFinish.run();
2163 }
2164 }.sendNext();
2165 }
2166
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002167 void activityManagerForceStopPackage(int userId, String reason) {
2168 synchronized (mService) {
2169 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2170 userId, reason);
2171 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002172 };
2173
2174 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2175 boolean exported) {
2176 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2177 }
2178
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002179 protected void startHomeActivity(int userId, String reason) {
2180 synchronized (mService) {
2181 mService.startHomeActivityLocked(userId, reason);
2182 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002183 }
2184
Christopher Tate2ec961d2018-07-27 16:48:37 -07002185 void startUserWidgets(int userId) {
2186 AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
2187 if (awm != null) {
2188 awm.unlockUser(userId);
2189 }
2190 }
2191
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002192 void updateUserConfiguration() {
2193 synchronized (mService) {
2194 mService.updateUserConfigurationLocked();
2195 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002196 }
2197
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002198 void clearBroadcastQueueForUser(int userId) {
2199 synchronized (mService) {
2200 mService.clearBroadcastQueueForUserLocked(userId);
2201 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002202 }
2203
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002204 void loadUserRecents(int userId) {
2205 synchronized (mService) {
Winson Chung3f0e59a2017-10-25 10:19:05 -07002206 mService.getRecentTasks().loadUserRecentsLocked(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002207 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002208 }
2209
2210 void startPersistentApps(int matchFlags) {
2211 mService.startPersistentApps(matchFlags);
2212 }
2213
2214 void installEncryptionUnawareProviders(int userId) {
2215 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002216 }
2217
Alex Chau93ae42b2018-01-11 15:10:12 +00002218 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2219 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002220 Dialog d;
2221 if (!mService.mContext.getPackageManager()
2222 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2223 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002224 true /* above system */, switchingFromSystemUserMessage,
2225 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002226 } else {
2227 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2228 true /* above system */, switchingFromSystemUserMessage,
2229 switchingToSystemUserMessage);
2230 }
2231
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002232 d.show();
2233 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002234
Dianne Hackbornced54392018-02-26 13:07:42 -08002235 void reportGlobalUsageEventLocked(int event) {
2236 synchronized (mService) {
2237 mService.reportGlobalUsageEventLocked(event);
2238 }
2239 }
2240
2241 void reportCurWakefulnessUsageEvent() {
2242 synchronized (mService) {
2243 mService.reportCurWakefulnessUsageEventLocked();
2244 }
2245 }
2246
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002247 void stackSupervisorRemoveUser(int userId) {
2248 synchronized (mService) {
2249 mService.mStackSupervisor.removeUserLocked(userId);
2250 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002251 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002252
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002253 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
2254 synchronized (mService) {
2255 return mService.mStackSupervisor.switchUserLocked(userId, uss);
2256 }
2257 }
2258
2259 protected void stackSupervisorResumeFocusedStackTopActivity() {
2260 synchronized (mService) {
2261 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
2262 }
2263 }
2264
Charles Heff9b4dff2017-09-22 10:18:37 +01002265 protected void clearAllLockedTasks(String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002266 synchronized (mService) {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002267 mService.getLockTaskController().clearLockedTasks(reason);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002268 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002269 }
Tony Make839d702018-01-22 15:34:46 +00002270
2271 protected boolean isCallerRecents(int callingUid) {
2272 return mService.getRecentTasks().isCallerRecents(callingUid);
2273 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002274 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002275}