blob: e575e10807bcfe3131b7a804d1951610f7c2f3b4 [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
kholoud mohamed67ac7c62019-12-06 16:33:48 +000019import static android.Manifest.permission.INTERACT_ACROSS_PROFILES;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070020import static android.Manifest.permission.INTERACT_ACROSS_USERS;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070022import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
23import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070024import static android.app.ActivityManager.USER_OP_IS_CURRENT;
25import static android.app.ActivityManager.USER_OP_SUCCESS;
kholoud mohamed67ac7c62019-12-06 16:33:48 +000026import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
28import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
29import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
Ng Zhi An150a6ba2018-08-13 09:08:11 -070030import static android.os.Process.SHELL_UID;
31import static android.os.Process.SYSTEM_UID;
32
33import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
34import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
35import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070036import static com.android.server.am.ActivityManagerService.MY_PID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060037import static com.android.server.am.UserState.STATE_BOOTING;
38import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
39import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
40import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070041
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070042import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000043import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000044import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070045import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080046import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070047import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070048import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070049import android.app.IStopUserCallback;
50import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000051import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080052import android.app.usage.UsageEvents;
Christopher Tate88dc93f2018-07-27 16:48:37 -070053import android.appwidget.AppWidgetManagerInternal;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070054import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.content.IIntentReceiver;
56import android.content.Intent;
kholoud mohamed79a89f02020-01-15 15:30:07 +000057import android.content.PermissionChecker;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080058import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070059import android.content.pm.PackageManager;
60import android.content.pm.UserInfo;
61import android.os.BatteryStats;
62import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060063import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070064import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070065import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070066import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070067import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060068import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070069import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070070import android.os.IUserManager;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -070071import android.os.Looper;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070072import android.os.Message;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070073import android.os.Process;
74import android.os.RemoteCallbackList;
75import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070076import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070077import android.os.SystemClock;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070078import android.os.UserHandle;
79import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010080import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080081import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080082import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070083import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070084import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070085import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080086import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070087import android.util.Slog;
88import android.util.SparseArray;
89import android.util.SparseIntArray;
Yi Jin148d7f42017-11-28 14:23:56 -080090import android.util.proto.ProtoOutputStream;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070091
92import 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;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000097import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080098import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010099import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700100import com.android.server.SystemServiceManager;
Pavel Grafov67d44262019-05-03 15:58:54 +0100101import com.android.server.am.UserState.KeyEvictedCallback;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700102import com.android.server.pm.UserManagerService;
Felipe Leme3aad1be2019-05-31 11:43:12 -0700103import com.android.server.utils.TimingsTraceAndSlog;
Ng Zhi An150a6ba2018-08-13 09:08:11 -0700104import com.android.server.wm.ActivityTaskManagerInternal;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700105import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700106
107import java.io.PrintWriter;
108import java.util.ArrayList;
109import java.util.Arrays;
Alex Chaub6ef8692018-01-09 14:16:36 +0000110import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700111import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600112import java.util.Objects;
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
Felipe Leme48a75cb2020-01-29 12:15:29 -0800133 // Amount of time we wait for observers to handle a user switch before we log a warning.
134 // Must be smaller than USER_SWITCH_TIMEOUT_MS.
135 private static final int USER_SWITCH_WARNING_TIMEOUT_MS = 500;
136
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700137 // ActivityManager thread message constants
138 static final int REPORT_USER_SWITCH_MSG = 10;
139 static final int CONTINUE_USER_SWITCH_MSG = 20;
140 static final int USER_SWITCH_TIMEOUT_MSG = 30;
141 static final int START_PROFILES_MSG = 40;
Felipe Lemec1ca4412019-09-11 09:23:26 -0700142 static final int USER_START_MSG = 50;
143 static final int USER_CURRENT_MSG = 60;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700144 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
145 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
146 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
Felipe Lemec1ca4412019-09-11 09:23:26 -0700147 static final int USER_UNLOCK_MSG = 100;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700148 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
149 static final int START_USER_SWITCH_FG_MSG = 120;
150
151 // UI thread message constants
152 static final int START_USER_SWITCH_UI_MSG = 1000;
153
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700154 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
155 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
156 // when it never calls back.
157 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700158
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700159 /**
160 * Maximum number of users we allow to be running at a time, including system user.
161 *
162 * <p>This parameter only affects how many background users will be stopped when switching to a
163 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
164 *
165 * <p>Note: Current and system user (and their related profiles) are never stopped when
166 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
167 */
Keun young Park4cb99332019-09-19 17:08:41 -0700168 @GuardedBy("mLock")
169 private int mMaxRunningUsers;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700170
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700171 // Lock for internal state.
172 private final Object mLock = new Object();
173
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700174 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700175 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700176 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700177
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700178 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700179 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700180 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
181 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
182 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700183 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700184 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700185
186 /**
187 * Which users have been started, so are allowed to run code.
188 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700189 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700190 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800191
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700192 /**
193 * LRU list of history of current users. Most recently current is at the end.
194 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700195 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700196 private final ArrayList<Integer> mUserLru = new ArrayList<>();
197
198 /**
199 * Constant array of the users that are currently started.
200 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700201 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700202 private int[] mStartedUserArray = new int[] { 0 };
203
204 // If there are multiple profiles for the current user, their ids are here
205 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700206 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700207 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700208
209 /**
210 * Mapping from each known user ID to the profile group ID it is associated with.
211 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700212 @GuardedBy("mLock")
213 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700214
215 /**
216 * Registered observers of the user switching mechanics.
217 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700218 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700219 = new RemoteCallbackList<>();
220
Keun young Park4cb99332019-09-19 17:08:41 -0700221 @GuardedBy("mLock")
222 private boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700223
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700224 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700225 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700226 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700227 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700228 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700229
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700230 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000231 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
232 */
233 @GuardedBy("mLock")
234 private String mSwitchingFromSystemUserMessage;
235
236 /**
237 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
238 */
239 @GuardedBy("mLock")
240 private String mSwitchingToSystemUserMessage;
241
242 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700243 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
244 */
245 @GuardedBy("mLock")
246 private ArraySet<String> mTimeoutUserSwitchCallbacks;
247
Clara Bayarria1771112015-12-18 16:29:18 +0000248 private final LockPatternUtils mLockPatternUtils;
249
Ng Zhi An7ff7fdb2019-01-16 15:35:51 -0800250 volatile boolean mBootCompleted;
251
Keun young Parkdf54b662019-03-13 14:06:42 -0700252 /**
253 * In this mode, user is always stopped when switched out but locking of user data is
254 * postponed until total number of unlocked users in the system reaches mMaxRunningUsers.
Keun young Park4cb99332019-09-19 17:08:41 -0700255 * Once total number of unlocked users reach mMaxRunningUsers, least recently used user
Keun young Parkdf54b662019-03-13 14:06:42 -0700256 * will be locked.
257 */
Keun young Park4cb99332019-09-19 17:08:41 -0700258 @GuardedBy("mLock")
259 private boolean mDelayUserDataLocking;
Keun young Parkdf54b662019-03-13 14:06:42 -0700260 /**
261 * Keep track of last active users for mDelayUserDataLocking.
262 * The latest stopped user is placed in front while the least recently stopped user in back.
263 */
264 @GuardedBy("mLock")
265 private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>();
266
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700267 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700268 this(new Injector(service));
269 }
270
271 @VisibleForTesting
272 UserController(Injector injector) {
273 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700274 mHandler = mInjector.getHandler(this);
275 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700276 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800277 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700278 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800279 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700280 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700281 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700282 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700283 }
284
Keun young Park4cb99332019-09-19 17:08:41 -0700285 void setInitialConfig(boolean userSwitchUiEnabled, int maxRunningUsers,
286 boolean delayUserDataLocking) {
287 synchronized (mLock) {
288 mUserSwitchUiEnabled = userSwitchUiEnabled;
289 mMaxRunningUsers = maxRunningUsers;
290 mDelayUserDataLocking = delayUserDataLocking;
291 }
292 }
293
294 private boolean isUserSwitchUiEnabled() {
295 synchronized (mLock) {
296 return mUserSwitchUiEnabled;
297 }
298 }
299
300 int getMaxRunningUsers() {
301 synchronized (mLock) {
302 return mMaxRunningUsers;
303 }
304 }
305
306 private boolean isDelayUserDataLockingEnabled() {
307 synchronized (mLock) {
308 return mDelayUserDataLocking;
309 }
310 }
311
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700312 void finishUserSwitch(UserState uss) {
Wale Ogunwale86b74462018-07-02 08:42:43 -0700313 // This call holds the AM lock so we post to the handler.
314 mHandler.post(() -> {
315 finishUserBoot(uss);
316 startProfiles();
317 synchronized (mLock) {
318 stopRunningUsersLU(mMaxRunningUsers);
319 }
320 });
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700321 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700322
Andreas Gampee7739b32018-07-20 12:55:36 -0700323 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000324 List<Integer> getRunningUsersLU() {
325 ArrayList<Integer> runningUsers = new ArrayList<>();
326 for (Integer userId : mUserLru) {
327 UserState uss = mStartedUsers.get(userId);
328 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700329 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700330 continue;
331 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000332 if (uss.state == UserState.STATE_STOPPING
333 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700334 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700335 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700336 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000337 if (userId == UserHandle.USER_SYSTEM) {
338 // We only count system user as running when it is not a pure system user.
339 if (UserInfo.isSystemOnly(userId)) {
340 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700341 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000342 }
343 runningUsers.add(userId);
344 }
345 return runningUsers;
346 }
347
Andreas Gampee7739b32018-07-20 12:55:36 -0700348 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000349 void stopRunningUsersLU(int maxRunningUsers) {
350 List<Integer> currentlyRunning = getRunningUsersLU();
351 Iterator<Integer> iterator = currentlyRunning.iterator();
352 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
353 Integer userId = iterator.next();
354 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
355 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700356 continue;
357 }
Keun young Park4cb99332019-09-19 17:08:41 -0700358 // allowDelayedLocking set here as stopping user is done without any explicit request
359 // from outside.
360 if (stopUsersLU(userId, /* force= */ false, /* allowDelayedLocking= */ true,
361 /* stopUserCallback= */ null, /* keyEvictedCallback= */ null)
362 == USER_OP_SUCCESS) {
Alex Chaub6ef8692018-01-09 14:16:36 +0000363 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700364 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000365 }
366 }
367
368 /**
369 * Returns if more users can be started without stopping currently running users.
370 */
371 boolean canStartMoreUsers() {
372 synchronized (mLock) {
373 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700374 }
375 }
376
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800377 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700378 finishUserBoot(uss, null);
379 }
380
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800381 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700382 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700383
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700384 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700385 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700386 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700387 if (mStartedUsers.get(userId) != uss) {
388 return;
389 }
390 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700391
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700392 // We always walk through all the user lifecycle states to send
393 // consistent developer events. We step into RUNNING_LOCKED here,
394 // but we might immediately step into RUNNING below if the user
395 // storage is already unlocked.
396 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
397 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
398 // Do not report secondary users, runtime restarts or first boot/upgrade
399 if (userId == UserHandle.USER_SYSTEM
400 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
401 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
402 MetricsLogger.histogram(mInjector.getContext(),
403 "framework_locked_boot_completed", uptimeSeconds);
404 final int MAX_UPTIME_SECONDS = 120;
405 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
406 Slog.wtf("SystemServerTiming",
407 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800408 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700409 }
410
Felipe Lemec1ca4412019-09-11 09:23:26 -0700411 if (!mInjector.getUserManager().isPreCreated(userId)) {
412 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
413 userId, 0));
414 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
415 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
416 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
417 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
418 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
419 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
420 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
421 Binder.getCallingUid(), Binder.getCallingPid(), userId);
422 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700423 }
424
425 // We need to delay unlocking managed profiles until the parent user
426 // is also unlocked.
Bookatz029832a2019-10-04 16:50:22 -0700427 if (mInjector.getUserManager().isProfile(userId)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700428 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
429 if (parent != null
430 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
431 Slog.d(TAG, "User " + userId + " (parent " + parent.id
432 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600433 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700434 } else {
435 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
436 Slog.d(TAG, "User " + userId + " (parent " + parentId
437 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600438 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700439 } else {
440 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700441 }
442 }
443
444 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600445 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
446 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700447 */
Rubin Xu98571a02019-02-28 16:26:06 +0000448 private boolean finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700449 final int userId = uss.mHandle.getIdentifier();
Felipe Lemeb5f0e742019-09-24 09:35:49 -0700450 Slog.d(TAG, "UserController event: finishUserUnlocking(" + userId + ")");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700451 // Only keep marching forward if user is actually unlocked
Rubin Xu98571a02019-02-28 16:26:06 +0000452 if (!StorageManager.isUserKeyUnlocked(userId)) return false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700453 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800454 // Do not proceed if unexpected state or a stale user
455 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Rubin Xu98571a02019-02-28 16:26:06 +0000456 return false;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600457 }
458 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700459 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200460
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700461 // Prepare app storage before we go any further
462 uss.mUnlockProgress.setProgress(5,
463 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200464
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800465 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
466 FgThread.getHandler().post(() -> {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100467 if (!StorageManager.isUserKeyUnlocked(userId)) {
468 Slog.w(TAG, "User key got locked unexpectedly, leaving user locked.");
469 return;
470 }
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800471 mInjector.getUserManager().onBeforeUnlockUser(userId);
472 synchronized (mLock) {
473 // Do not proceed if unexpected state
474 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
475 return;
476 }
477 }
478 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
479
480 uss.mUnlockProgress.setProgress(20);
481
482 // Dispatch unlocked to system services; when fully dispatched,
483 // that calls through to the next "unlocked" phase
Felipe Lemec1ca4412019-09-11 09:23:26 -0700484 mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800485 });
Rubin Xu98571a02019-02-28 16:26:06 +0000486 return true;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600487 }
488
489 /**
490 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
491 * {@link UserState#STATE_RUNNING_UNLOCKED}.
492 */
493 void finishUserUnlocked(final UserState uss) {
494 final int userId = uss.mHandle.getIdentifier();
Felipe Lemeb5f0e742019-09-24 09:35:49 -0700495 Slog.d(TAG, "UserController event: finishUserUnlocked(" + userId + ")");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700496 // Only keep marching forward if user is actually unlocked
497 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700498 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600499 // Bail if we ended up with a stale user
500 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
501
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700502 // Do not proceed if unexpected state
503 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
504 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600505 }
506 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700507 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
508 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700509
510 // Get unaware persistent apps running and start any unaware providers
511 // in already-running apps that are partially aware
512 if (userId == UserHandle.USER_SYSTEM) {
513 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
514 }
515 mInjector.installEncryptionUnawareProviders(userId);
516
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700517 // Dispatch unlocked to external apps
518 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
519 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
520 unlockedIntent.addFlags(
521 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
522 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
523 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000524 Binder.getCallingUid(), Binder.getCallingPid(), userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700525
526 if (getUserInfo(userId).isManagedProfile()) {
527 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
528 if (parent != null) {
529 final Intent profileUnlockedIntent = new Intent(
530 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
531 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
532 profileUnlockedIntent.addFlags(
533 Intent.FLAG_RECEIVER_REGISTERED_ONLY
534 | Intent.FLAG_RECEIVER_FOREGROUND);
535 mInjector.broadcastIntent(profileUnlockedIntent,
536 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000537 null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
538 Binder.getCallingPid(), parent.id);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700539 }
540 }
541
542 // Send PRE_BOOT broadcasts if user fingerprint changed; we
543 // purposefully block sending BOOT_COMPLETED until after all
544 // PRE_BOOT receivers are finished to avoid ANR'ing apps
545 final UserInfo info = getUserInfo(userId);
546 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
547 // Suppress double notifications for managed profiles that
548 // were unlocked automatically as part of their parent user
549 // being unlocked.
550 final boolean quiet;
551 if (info.isManagedProfile()) {
552 quiet = !uss.tokenProvided
553 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
554 } else {
555 quiet = false;
556 }
557 mInjector.sendPreBootBroadcast(userId, quiet,
558 () -> finishUserUnlockedCompleted(uss));
559 } else {
560 finishUserUnlockedCompleted(uss);
561 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600562 }
563
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600564 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600565 final int userId = uss.mHandle.getIdentifier();
Felipe Lemeb5f0e742019-09-24 09:35:49 -0700566 Slog.d(TAG, "UserController event: finishUserUnlockedCompleted(" + userId + ")");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700567 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600568 // Bail if we ended up with a stale user
569 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700570 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700571 UserInfo userInfo = getUserInfo(userId);
572 if (userInfo == null) {
573 return;
574 }
575 // Only keep marching forward if user is actually unlocked
576 if (!StorageManager.isUserKeyUnlocked(userId)) return;
577
578 // Remember that we logged in
579 mInjector.getUserManager().onUserLoggedIn(userId);
580
581 if (!userInfo.isInitialized()) {
582 if (userId != UserHandle.USER_SYSTEM) {
583 Slog.d(TAG, "Initializing user #" + userId);
584 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
585 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
586 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
587 mInjector.broadcastIntent(intent, null,
588 new IIntentReceiver.Stub() {
589 @Override
590 public void performReceive(Intent intent, int resultCode,
591 String data, Bundle extras, boolean ordered,
592 boolean sticky, int sendingUser) {
593 // Note: performReceive is called with mService lock held
594 mInjector.getUserManager().makeInitialized(userInfo.id);
595 }
596 }, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000597 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
598 Binder.getCallingPid(), userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700599 }
600 }
601
Felipe Lemec1ca4412019-09-11 09:23:26 -0700602 if (userInfo.preCreated) {
603 Slog.i(TAG, "Stopping pre-created user " + userInfo.toFullString());
604 // Pre-created user was started right after creation so services could properly
605 // intialize it; it should be stopped right away as it's not really a "real" user.
Felipe Lemec6e015d2019-10-21 12:51:08 -0700606 // TODO(b/143092698): in the long-term, it might be better to add a onCreateUser()
607 // callback on SystemService instead.
Keun young Park4cb99332019-09-19 17:08:41 -0700608 stopUser(userInfo.id, /* force= */ true, /* allowDelayedLocking= */ false,
609 /* stopUserCallback= */ null, /* keyEvictedCallback= */ null);
Felipe Lemec1ca4412019-09-11 09:23:26 -0700610 return;
611 }
612
Christopher Tate88dc93f2018-07-27 16:48:37 -0700613 // Spin up app widgets prior to boot-complete, so they can be ready promptly
614 mInjector.startUserWidgets(userId);
615
Christopher Tate74e5b7d2019-06-07 17:55:43 -0700616 Slog.i(TAG, "Posting BOOT_COMPLETED user #" + userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700617 // Do not report secondary users, runtime restarts or first boot/upgrade
618 if (userId == UserHandle.USER_SYSTEM
619 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
620 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
621 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
622 uptimeSeconds);
623 }
624 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
625 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
626 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
Ng Zhi An150a6ba2018-08-13 09:08:11 -0700627 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
628 | Intent.FLAG_RECEIVER_OFFLOAD);
Christopher Tate74e5b7d2019-06-07 17:55:43 -0700629 // Widget broadcasts are outbound via FgThread, so to guarantee sequencing
630 // we also send the boot_completed broadcast from that thread.
631 final int callingUid = Binder.getCallingUid();
632 final int callingPid = Binder.getCallingPid();
633 FgThread.getHandler().post(() -> {
634 mInjector.broadcastIntent(bootIntent, null,
635 new IIntentReceiver.Stub() {
636 @Override
637 public void performReceive(Intent intent, int resultCode, String data,
638 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
639 throws RemoteException {
640 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u"
641 + userId);
642 mBootCompleted = true;
643 }
644 }, 0, null, null,
645 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
646 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
647 callingUid, callingPid, userId);
648 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700649 }
650
Andrew Scull85a63bc2016-10-24 13:47:47 +0100651 int restartUser(final int userId, final boolean foreground) {
Keun young Park4cb99332019-09-19 17:08:41 -0700652 return stopUser(userId, /* force= */ true, /* allowDelayedLocking= */ false,
653 /* stopUserCallback= */ null, new KeyEvictedCallback() {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100654 @Override
Pavel Grafov67d44262019-05-03 15:58:54 +0100655 public void keyEvicted(@UserIdInt int userId) {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100656 // Post to the same handler that this callback is called from to ensure the user
657 // cleanup is complete before restarting.
Pavel Grafov67d44262019-05-03 15:58:54 +0100658 mHandler.post(() -> UserController.this.startUser(userId, foreground));
Andrew Scull85a63bc2016-10-24 13:47:47 +0100659 }
Andrew Scull85a63bc2016-10-24 13:47:47 +0100660 });
661 }
662
Keun young Park4cb99332019-09-19 17:08:41 -0700663 int stopUser(final int userId, final boolean force, boolean allowDelayedLocking,
664 final IStopUserCallback stopUserCallback, KeyEvictedCallback keyEvictedCallback) {
Bookatz95df5ca2019-05-30 15:58:46 -0700665 checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "stopUser");
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
667 throw new IllegalArgumentException("Can't stop system user " + userId);
668 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700669 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700670 synchronized (mLock) {
Keun young Park4cb99332019-09-19 17:08:41 -0700671 return stopUsersLU(userId, force, allowDelayedLocking, stopUserCallback,
672 keyEvictedCallback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700673 }
674 }
675
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700676 /**
677 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700678 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700679 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700680 @GuardedBy("mLock")
Keun young Park4cb99332019-09-19 17:08:41 -0700681 private int stopUsersLU(final int userId, boolean force, boolean allowDelayedLocking,
Pavel Grafov67d44262019-05-03 15:58:54 +0100682 final IStopUserCallback stopUserCallback, KeyEvictedCallback keyEvictedCallback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700683 if (userId == UserHandle.USER_SYSTEM) {
684 return USER_OP_ERROR_IS_SYSTEM;
685 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700686 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700687 return USER_OP_IS_CURRENT;
688 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700689 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700690 // If one of related users is system or current, no related users should be stopped
691 for (int i = 0; i < usersToStop.length; i++) {
692 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700693 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700694 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
695 + relatedUserId);
696 // We still need to stop the requested user if it's a force stop.
697 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800698 Slog.i(TAG,
699 "Force stop user " + userId + ". Related users will not be stopped");
Keun young Park4cb99332019-09-19 17:08:41 -0700700 stopSingleUserLU(userId, allowDelayedLocking, stopUserCallback,
701 keyEvictedCallback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800702 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700703 }
704 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
705 }
706 }
707 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
708 for (int userIdToStop : usersToStop) {
Keun young Park4cb99332019-09-19 17:08:41 -0700709 stopSingleUserLU(userIdToStop, allowDelayedLocking,
Pavel Grafov67d44262019-05-03 15:58:54 +0100710 userIdToStop == userId ? stopUserCallback : null,
711 userIdToStop == userId ? keyEvictedCallback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700712 }
713 return USER_OP_SUCCESS;
714 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700715
Keun young Park4cb99332019-09-19 17:08:41 -0700716 /**
717 * Stops a single User. This can also trigger locking user data out depending on device's
718 * config ({@code mDelayUserDataLocking}) and arguments.
719 * User will be unlocked when
720 * - {@code mDelayUserDataLocking} is not set.
721 * - {@code mDelayUserDataLocking} is set and {@code keyEvictedCallback} is non-null.
722 * -
723 *
724 * @param userId User Id to stop and lock the data.
725 * @param allowDelayedLocking When set, do not lock user after stopping. Locking can happen
726 * later when number of unlocked users reaches
727 * {@code mMaxRunnngUsers}. Note that this is respected only when
728 * {@code mDelayUserDataLocking} is set and {@keyEvictedCallback} is
729 * null. Otherwise the user will be locked.
730 * @param stopUserCallback Callback to notify that user has stopped.
731 * @param keyEvictedCallback Callback to notify that user has been unlocked.
732 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700733 @GuardedBy("mLock")
Keun young Park4cb99332019-09-19 17:08:41 -0700734 private void stopSingleUserLU(final int userId, boolean allowDelayedLocking,
735 final IStopUserCallback stopUserCallback,
Pavel Grafov67d44262019-05-03 15:58:54 +0100736 KeyEvictedCallback keyEvictedCallback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700737 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700738 final UserState uss = mStartedUsers.get(userId);
Keun young Park4cb99332019-09-19 17:08:41 -0700739 if (uss == null) { // User is not started
740 // If mDelayUserDataLocking is set and allowDelayedLocking is not set, we need to lock
741 // the requested user as the client wants to stop and lock the user. On the other hand,
742 // having keyEvictedCallback set will lead into locking user if mDelayUserDataLocking
743 // is set as that means client wants to lock the user immediately.
744 // If mDelayUserDataLocking is not set, the user was already locked when it was stopped
745 // and no further action is necessary.
746 if (mDelayUserDataLocking) {
747 if (allowDelayedLocking && keyEvictedCallback != null) {
748 Slog.wtf(TAG, "allowDelayedLocking set with KeyEvictedCallback, ignore it"
749 + " and lock user:" + userId, new RuntimeException());
750 allowDelayedLocking = false;
751 }
752 if (!allowDelayedLocking) {
753 if (mLastActiveUsers.remove(Integer.valueOf(userId))) {
754 // should lock the user, user is already gone
755 final ArrayList<KeyEvictedCallback> keyEvictedCallbacks;
756 if (keyEvictedCallback != null) {
757 keyEvictedCallbacks = new ArrayList<>(1);
758 keyEvictedCallbacks.add(keyEvictedCallback);
759 } else {
760 keyEvictedCallbacks = null;
761 }
762 dispatchUserLocking(userId, keyEvictedCallbacks);
763 }
764 }
765 }
766 // We do need to post the stopped callback even though user is already stopped.
Pavel Grafov67d44262019-05-03 15:58:54 +0100767 if (stopUserCallback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700768 mHandler.post(() -> {
769 try {
Pavel Grafov67d44262019-05-03 15:58:54 +0100770 stopUserCallback.userStopped(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700771 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700772 }
773 });
774 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700775 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700776 }
777
Pavel Grafov67d44262019-05-03 15:58:54 +0100778 if (stopUserCallback != null) {
779 uss.mStopCallbacks.add(stopUserCallback);
780 }
781 if (keyEvictedCallback != null) {
782 uss.mKeyEvictedCallbacks.add(keyEvictedCallback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700783 }
784
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700785 if (uss.state != UserState.STATE_STOPPING
786 && uss.state != UserState.STATE_SHUTDOWN) {
787 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700788 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700789 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700790
Keun young Park4cb99332019-09-19 17:08:41 -0700791 final boolean allowDelayyLockingCopied = allowDelayedLocking;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700792 // Post to handler to obtain amLock
793 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700794 // We are going to broadcast ACTION_USER_STOPPING and then
795 // once that is done send a final ACTION_SHUTDOWN and then
796 // stop the user.
797 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
798 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
799 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
800 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700801 // This is the result receiver for the initial stopping broadcast.
802 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
803 @Override
804 public void performReceive(Intent intent, int resultCode, String data,
805 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Keun young Park4cb99332019-09-19 17:08:41 -0700806 mHandler.post(() -> finishUserStopping(userId, uss,
807 allowDelayyLockingCopied));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700808 }
809 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700810
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700811 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700812 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700813 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700814 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700815 null, stoppingReceiver, 0, null, null,
816 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000817 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
818 Binder.getCallingPid(), UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700819 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700820 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700821 }
822
Keun young Park4cb99332019-09-19 17:08:41 -0700823 void finishUserStopping(final int userId, final UserState uss,
824 final boolean allowDelayedLocking) {
Felipe Lemeb5f0e742019-09-24 09:35:49 -0700825 Slog.d(TAG, "UserController event: finishUserStopping(" + userId + ")");
Amith Yamasani98c05562016-03-30 13:15:26 -0700826 // On to the next.
827 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
828 // This is the result receiver for the final shutdown broadcast.
829 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
830 @Override
831 public void performReceive(Intent intent, int resultCode, String data,
832 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
833 mHandler.post(new Runnable() {
834 @Override
835 public void run() {
Keun young Park4cb99332019-09-19 17:08:41 -0700836 finishUserStopped(uss, allowDelayedLocking);
Amith Yamasani98c05562016-03-30 13:15:26 -0700837 }
838 });
839 }
840 };
841
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700842 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700843 if (uss.state != UserState.STATE_STOPPING) {
844 // Whoops, we are being started back up. Abort, abort!
845 return;
846 }
847 uss.setState(UserState.STATE_SHUTDOWN);
848 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700849 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700850
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700851 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700852 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
853 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700854 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700855
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700856 mInjector.broadcastIntent(shutdownIntent,
857 null, shutdownReceiver, 0, null, null, null,
858 AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000859 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
860 Binder.getCallingPid(), userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700861 }
862
Keun young Park4cb99332019-09-19 17:08:41 -0700863 void finishUserStopped(UserState uss, boolean allowDelayedLocking) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700864 final int userId = uss.mHandle.getIdentifier();
Felipe Lemeb5f0e742019-09-24 09:35:49 -0700865 Slog.d(TAG, "UserController event: finishUserStopped(" + userId + ")");
Pavel Grafov634c34e2018-04-10 19:19:01 +0100866 final boolean stopped;
Keun young Parkdf54b662019-03-13 14:06:42 -0700867 boolean lockUser = true;
Pavel Grafov67d44262019-05-03 15:58:54 +0100868 final ArrayList<IStopUserCallback> stopCallbacks;
869 final ArrayList<KeyEvictedCallback> keyEvictedCallbacks;
Keun young Parkdf54b662019-03-13 14:06:42 -0700870 int userIdToLock = userId;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700871 synchronized (mLock) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100872 stopCallbacks = new ArrayList<>(uss.mStopCallbacks);
873 keyEvictedCallbacks = new ArrayList<>(uss.mKeyEvictedCallbacks);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100874 if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700875 stopped = false;
876 } else {
877 stopped = true;
878 // User can no longer run.
879 mStartedUsers.remove(userId);
880 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700881 updateStartedUserArrayLU();
Keun young Park4cb99332019-09-19 17:08:41 -0700882 if (allowDelayedLocking && !keyEvictedCallbacks.isEmpty()) {
883 Slog.wtf(TAG,
884 "Delayed locking enabled while KeyEvictedCallbacks not empty, userId:"
885 + userId + " callbacks:" + keyEvictedCallbacks);
886 allowDelayedLocking = false;
887 }
888 userIdToLock = updateUserToLockLU(userId, allowDelayedLocking);
Keun young Parkdf54b662019-03-13 14:06:42 -0700889 if (userIdToLock == UserHandle.USER_NULL) {
890 lockUser = false;
891 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700892 }
893 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100894 if (stopped) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700895 mInjector.getUserManagerInternal().removeUserState(userId);
896 mInjector.activityManagerOnUserStopped(userId);
897 // Clean up all state and processes associated with the user.
898 // Kill all the processes for the user.
899 forceStopUser(userId, "finish user");
900 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700901
Pavel Grafov67d44262019-05-03 15:58:54 +0100902 for (final IStopUserCallback callback : stopCallbacks) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700903 try {
Pavel Grafov67d44262019-05-03 15:58:54 +0100904 if (stopped) callback.userStopped(userId);
905 else callback.userStopAborted(userId);
906 } catch (RemoteException ignored) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700907 }
908 }
909
910 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700911 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700912 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100913 // Remove the user if it is ephemeral.
Felipe Lemec1ca4412019-09-11 09:23:26 -0700914 UserInfo userInfo = getUserInfo(userId);
915 if (userInfo.isEphemeral() && !userInfo.preCreated) {
Alex Chau1df89812018-02-06 14:41:47 +0000916 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100917 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100918
Keun young Parkdf54b662019-03-13 14:06:42 -0700919 if (!lockUser) {
920 return;
921 }
Keun young Park4cb99332019-09-19 17:08:41 -0700922 dispatchUserLocking(userIdToLock, keyEvictedCallbacks);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700923 }
924 }
925
Keun young Park4cb99332019-09-19 17:08:41 -0700926 private void dispatchUserLocking(@UserIdInt int userId,
927 @Nullable List<KeyEvictedCallback> keyEvictedCallbacks) {
928 // Evict the user's credential encryption key. Performed on FgThread to make it
929 // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
930 // to prevent data corruption.
931 FgThread.getHandler().post(() -> {
932 synchronized (mLock) {
933 if (mStartedUsers.get(userId) != null) {
934 Slog.w(TAG, "User was restarted, skipping key eviction");
935 return;
936 }
937 }
938 try {
939 mInjector.getStorageManager().lockUserKey(userId);
940 } catch (RemoteException re) {
941 throw re.rethrowAsRuntimeException();
942 }
943 if (keyEvictedCallbacks == null) {
944 return;
945 }
946 for (int i = 0; i < keyEvictedCallbacks.size(); i++) {
947 keyEvictedCallbacks.get(i).keyEvicted(userId);
948 }
949 });
950 }
951
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700952 /**
Keun young Parkdf54b662019-03-13 14:06:42 -0700953 * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked.
954 * Total number of unlocked user storage is limited by mMaxRunningUsers.
955 * If there are more unlocked users, evict and lock the least recently stopped user and
956 * lock that user's data. Regardless of the mode, ephemeral user is always locked
957 * immediately.
958 *
959 * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked.
960 */
961 @GuardedBy("mLock")
Keun young Park4cb99332019-09-19 17:08:41 -0700962 private int updateUserToLockLU(@UserIdInt int userId, boolean allowDelayedLocking) {
Keun young Parkdf54b662019-03-13 14:06:42 -0700963 int userIdToLock = userId;
Keun young Park4cb99332019-09-19 17:08:41 -0700964 if (mDelayUserDataLocking && allowDelayedLocking && !getUserInfo(userId).isEphemeral()
Keun young Parkdf54b662019-03-13 14:06:42 -0700965 && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) {
966 mLastActiveUsers.remove((Integer) userId); // arg should be object, not index
967 mLastActiveUsers.add(0, userId);
968 int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsers.size();
969 if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user
970 userIdToLock = mLastActiveUsers.get(mLastActiveUsers.size() - 1);
971 mLastActiveUsers.remove(mLastActiveUsers.size() - 1);
972 Slog.i(TAG, "finishUserStopped, stopping user:" + userId
973 + " lock user:" + userIdToLock);
974 } else {
975 Slog.i(TAG, "finishUserStopped, user:" + userId
976 + ",skip locking");
977 // do not lock
978 userIdToLock = UserHandle.USER_NULL;
979
980 }
981 }
982 return userIdToLock;
983 }
984
985 /**
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700986 * Determines the list of users that should be stopped together with the specified
987 * {@code userId}. The returned list includes {@code userId}.
988 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700989 @GuardedBy("mLock")
Bookatzf56f2582019-09-04 16:06:41 -0700990 private @NonNull int[] getUsersToStopLU(@UserIdInt int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700991 int startedUsersSize = mStartedUsers.size();
992 IntArray userIds = new IntArray();
993 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700994 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
995 for (int i = 0; i < startedUsersSize; i++) {
996 UserState uss = mStartedUsers.valueAt(i);
997 int startedUserId = uss.mHandle.getIdentifier();
998 // Skip unrelated users (profileGroupId mismatch)
999 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001000 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001001 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
1002 && (userGroupId == startedUserGroupId);
1003 // userId has already been added
1004 boolean sameUserId = startedUserId == userId;
1005 if (!sameGroup || sameUserId) {
1006 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001007 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001008 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001009 }
1010 return userIds.toArray();
1011 }
1012
Bookatzf56f2582019-09-04 16:06:41 -07001013 private void forceStopUser(@UserIdInt int userId, String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001014 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001015 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
1016 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1017 | Intent.FLAG_RECEIVER_FOREGROUND);
1018 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001019 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001020 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001021 null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
1022 Binder.getCallingPid(), UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001023 }
1024
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001025 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001026 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001027 */
Alex Chaub6ef8692018-01-09 14:16:36 +00001028 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
1029 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +00001030 synchronized(mLock) {
1031 UserState oldUss = mStartedUsers.get(oldUserId);
1032 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
1033 || oldUss.state == UserState.STATE_STOPPING
1034 || oldUss.state == UserState.STATE_SHUTDOWN) {
1035 return;
1036 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001037 }
Alex Chaub6ef8692018-01-09 14:16:36 +00001038
1039 UserInfo userInfo = getUserInfo(oldUserId);
1040 if (userInfo.isEphemeral()) {
1041 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
1042 }
1043 if (userInfo.isGuest() || userInfo.isEphemeral()) {
1044 // This is a user to be stopped.
1045 synchronized (mLock) {
Keun young Park4cb99332019-09-19 17:08:41 -07001046 stopUsersLU(oldUserId, /* force= */ true, /* allowDelayedLocking= */ false,
1047 null, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001048 }
1049 }
1050 }
1051
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001052 void scheduleStartProfiles() {
Pavel Grafov10c16742018-09-20 15:03:47 +01001053 // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
1054 // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
1055 // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
1056 // after the parent had chance to unlock fully.
1057 FgThread.getHandler().post(() -> {
1058 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
1059 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
1060 DateUtils.SECOND_IN_MILLIS);
1061 }
1062 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001063 }
1064
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001065 void startProfiles() {
1066 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001067 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001068 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001069 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001070 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
1071 for (UserInfo user : profiles) {
1072 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001073 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001074 profilesToStart.add(user);
1075 }
1076 }
1077 final int profilesToStartSize = profilesToStart.size();
1078 int i = 0;
Keun young Park4cb99332019-09-19 17:08:41 -07001079 for (; i < profilesToStartSize && i < (getMaxRunningUsers() - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001080 startUser(profilesToStart.get(i).id, /* foreground= */ false);
1081 }
1082 if (i < profilesToStartSize) {
1083 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
1084 }
1085 }
1086
Bookatzf56f2582019-09-04 16:06:41 -07001087 boolean startUser(final @UserIdInt int userId, final boolean foreground) {
Tony Mak64fd8c02017-12-01 19:11:59 +00001088 return startUser(userId, foreground, null);
1089 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001090
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001091 /**
1092 * Start user, if its not already running.
1093 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
1094 * When starting the user, multiple intents will be broadcast in the following order:</p>
1095 * <ul>
1096 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
1097 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
Felipe Lemed7b88382019-06-12 17:40:53 -07001098 * user and all profiles of this user. Sent only if {@code foreground} parameter is
1099 * {@code false}
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001100 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
Felipe Lemed7b88382019-06-12 17:40:53 -07001101 * user and all profiles of this user. Sent only if {@code foreground} parameter is
1102 * {@code true}
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001103 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
Felipe Lemed7b88382019-06-12 17:40:53 -07001104 * Sent only if {@code foreground} parameter is {@code true}
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001105 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
1106 * of the new fg user
1107 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
1108 * the new user
1109 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
1110 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
1111 * new user. Sent only when the user is booting after a system update.
1112 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
1113 * new user. Sent only the first time a user is starting.
1114 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
1115 * user. Indicates that the user has finished booting.
1116 * </ul>
1117 *
1118 * @param userId ID of the user to start
1119 * @param foreground true if user should be brought to the foreground
Bookatz03bfe6f2019-03-01 15:46:04 -08001120 * @param unlockListener Listener to be informed when the user has started and unlocked.
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001121 * @return true if the user has been successfully started
1122 */
Tony Mak64fd8c02017-12-01 19:11:59 +00001123 boolean startUser(
Bookatzf56f2582019-09-04 16:06:41 -07001124 final @UserIdInt int userId,
Tony Mak64fd8c02017-12-01 19:11:59 +00001125 final boolean foreground,
1126 @Nullable IProgressListener unlockListener) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001127
Bookatz95df5ca2019-05-30 15:58:46 -07001128 checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "startUser");
Felipe Leme3aad1be2019-05-31 11:43:12 -07001129
1130 TimingsTraceAndSlog t = new TimingsTraceAndSlog();
1131
1132 t.traceBegin("startUser-" + userId + "-" + (foreground ? "fg" : "bg"));
1133 try {
1134 return startUserInternal(userId, foreground, unlockListener, t);
1135 } finally {
1136 t.traceEnd();
1137 }
1138 }
1139
Bookatzf56f2582019-09-04 16:06:41 -07001140 private boolean startUserInternal(@UserIdInt int userId, boolean foreground,
Felipe Leme3aad1be2019-05-31 11:43:12 -07001141 @Nullable IProgressListener unlockListener, @NonNull TimingsTraceAndSlog t) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001142 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001143
Michal Karpinskic99d7182019-02-17 13:15:23 +00001144 final int callingUid = Binder.getCallingUid();
1145 final int callingPid = Binder.getCallingPid();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001146 final long ident = Binder.clearCallingIdentity();
1147 try {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001148 t.traceBegin("getStartedUserState");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001149 final int oldUserId = getCurrentUserId();
1150 if (oldUserId == userId) {
Bookatz03bfe6f2019-03-01 15:46:04 -08001151 final UserState state = getStartedUserState(userId);
Keun young Park0cb5ae72019-03-27 14:01:24 -07001152 if (state == null) {
1153 Slog.wtf(TAG, "Current user has no UserState");
1154 // continue starting.
1155 } else {
1156 if (userId == UserHandle.USER_SYSTEM && state.state == STATE_BOOTING) {
1157 // system user start explicitly requested. should continue starting as it
1158 // is not in running state.
1159 } else {
1160 if (state.state == STATE_RUNNING_UNLOCKED) {
1161 // We'll skip all later code, so we must tell listener it's already
1162 // unlocked.
Bookatzcecf1162019-04-10 12:52:34 -07001163 notifyFinished(userId, unlockListener);
Keun young Park0cb5ae72019-03-27 14:01:24 -07001164 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001165 t.traceEnd(); //getStartedUserState
Keun young Park0cb5ae72019-03-27 14:01:24 -07001166 return true;
Bookatz03bfe6f2019-03-01 15:46:04 -08001167 }
1168 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001169 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001170 t.traceEnd(); //getStartedUserState
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001171
1172 if (foreground) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001173 t.traceBegin("clearAllLockedTasks");
Charles Heff9b4dff2017-09-22 10:18:37 +01001174 mInjector.clearAllLockedTasks("startUser");
Felipe Leme3aad1be2019-05-31 11:43:12 -07001175 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001176 }
1177
Felipe Leme3aad1be2019-05-31 11:43:12 -07001178 t.traceBegin("getUserInfo");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001179 final UserInfo userInfo = getUserInfo(userId);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001180 t.traceEnd();
1181
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001182 if (userInfo == null) {
1183 Slog.w(TAG, "No user info for user #" + userId);
1184 return false;
1185 }
1186 if (foreground && userInfo.isManagedProfile()) {
1187 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
1188 return false;
1189 }
1190
Felipe Lemec1ca4412019-09-11 09:23:26 -07001191 if (foreground && userInfo.preCreated) {
1192 Slog.w(TAG, "Cannot start pre-created user #" + userId + " as foreground");
1193 return false;
1194 }
1195
Keun young Park4cb99332019-09-19 17:08:41 -07001196 if (foreground && isUserSwitchUiEnabled()) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001197 t.traceBegin("startFreezingScreen");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001198 mInjector.getWindowManager().startFreezingScreen(
1199 R.anim.screen_user_exit, R.anim.screen_user_enter);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001200 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001201 }
1202
1203 boolean needStart = false;
1204 boolean updateUmState = false;
1205 UserState uss;
1206
1207 // If the user we are switching to is not currently started, then
1208 // we need to start it now.
Felipe Leme3aad1be2019-05-31 11:43:12 -07001209 t.traceBegin("updateStartedUserArrayStarting");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001210 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001211 uss = mStartedUsers.get(userId);
1212 if (uss == null) {
1213 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07001214 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001215 mStartedUsers.put(userId, uss);
1216 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001217 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001218 updateUmState = true;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001219 } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
1220 Slog.i(TAG, "User #" + userId
1221 + " is shutting down - will start after full stop");
1222 mHandler.post(() -> startUser(userId, foreground, unlockListener));
Felipe Leme3aad1be2019-05-31 11:43:12 -07001223 t.traceEnd(); // updateStartedUserArrayStarting
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001224 return true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001225 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001226 final Integer userIdInt = userId;
1227 mUserLru.remove(userIdInt);
1228 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +00001229 }
1230 if (unlockListener != null) {
1231 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001232 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001233 t.traceEnd(); // updateStartedUserArrayStarting
1234
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001235 if (updateUmState) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001236 t.traceBegin("setUserState");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001237 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001238 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001239 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001240 t.traceBegin("updateConfigurationAndProfileIds");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001241 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -08001242 // Make sure the old user is no longer considering the display to be on.
1243 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Keun young Park4cb99332019-09-19 17:08:41 -07001244 boolean userSwitchUiEnabled;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001245 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001246 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001247 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Keun young Park4cb99332019-09-19 17:08:41 -07001248 userSwitchUiEnabled = mUserSwitchUiEnabled;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001249 }
1250 mInjector.updateUserConfiguration();
1251 updateCurrentProfileIds();
1252 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -08001253 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001254 // Once the internal notion of the active user has switched, we lock the device
1255 // with the option to show the user switcher on the keyguard.
Keun young Park4cb99332019-09-19 17:08:41 -07001256 if (userSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001257 mInjector.getWindowManager().setSwitchingUser(true);
1258 mInjector.getWindowManager().lockNow(null);
1259 }
1260 } else {
1261 final Integer currentUserIdInt = mCurrentUserId;
1262 updateCurrentProfileIds();
1263 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
1264 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001265 mUserLru.remove(currentUserIdInt);
1266 mUserLru.add(currentUserIdInt);
1267 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001268 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001269 t.traceEnd();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001270
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001271 // Make sure user is in the started state. If it is currently
1272 // stopping, we need to knock that off.
1273 if (uss.state == UserState.STATE_STOPPING) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001274 t.traceBegin("updateStateStopping");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001275 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
1276 // so we can just fairly silently bring the user back from
1277 // the almost-dead.
1278 uss.setState(uss.lastState);
1279 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1280 synchronized (mLock) {
1281 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001282 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001283 needStart = true;
Felipe Leme3aad1be2019-05-31 11:43:12 -07001284 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001285 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001286 t.traceBegin("updateStateShutdown");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001287 // This means ACTION_SHUTDOWN has been sent, so we will
1288 // need to treat this as a new boot of the user.
1289 uss.setState(UserState.STATE_BOOTING);
1290 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1291 synchronized (mLock) {
1292 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001293 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001294 needStart = true;
Felipe Lemed34a8952019-10-03 10:32:04 -07001295 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001296 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001297
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001298 if (uss.state == UserState.STATE_BOOTING) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001299 t.traceBegin("updateStateBooting");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001300 // Give user manager a chance to propagate user restrictions
1301 // to other services and prepare app storage
1302 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001303
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001304 // Booting up a new user, need to tell system services about it.
1305 // Note that this is on the same handler as scheduling of broadcasts,
1306 // which is important because it needs to go first.
Felipe Lemec1ca4412019-09-11 09:23:26 -07001307 mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, 0));
Felipe Leme3aad1be2019-05-31 11:43:12 -07001308 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001309 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001310
Felipe Leme3aad1be2019-05-31 11:43:12 -07001311 t.traceBegin("sendMessages");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001312 if (foreground) {
Felipe Lemec1ca4412019-09-11 09:23:26 -07001313 mHandler.sendMessage(mHandler.obtainMessage(USER_CURRENT_MSG, userId, oldUserId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001314 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1315 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1316 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1317 oldUserId, userId, uss));
1318 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1319 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1320 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001321
Felipe Lemec1ca4412019-09-11 09:23:26 -07001322 if (userInfo.preCreated) {
1323 needStart = false;
1324 }
1325
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001326 if (needStart) {
1327 // Send USER_STARTED broadcast
1328 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1329 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1330 | Intent.FLAG_RECEIVER_FOREGROUND);
1331 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1332 mInjector.broadcastIntent(intent,
1333 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001334 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001335 }
Felipe Leme3aad1be2019-05-31 11:43:12 -07001336 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001337
1338 if (foreground) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001339 t.traceBegin("moveUserToForeground");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001340 moveUserToForeground(uss, oldUserId, userId);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001341 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001342 } else {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001343 t.traceBegin("finishUserBoot");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001344 finishUserBoot(uss);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001345 t.traceEnd();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001346 }
1347
1348 if (needStart) {
Felipe Leme3aad1be2019-05-31 11:43:12 -07001349 t.traceBegin("sendRestartBroadcast");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001350 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1351 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1352 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1353 mInjector.broadcastIntent(intent,
1354 null, new IIntentReceiver.Stub() {
1355 @Override
1356 public void performReceive(Intent intent, int resultCode,
1357 String data, Bundle extras, boolean ordered,
1358 boolean sticky,
1359 int sendingUser) throws RemoteException {
1360 }
1361 }, 0, null, null,
1362 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001363 null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1364 UserHandle.USER_ALL);
Felipe Leme3aad1be2019-05-31 11:43:12 -07001365 t.traceEnd();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001366 }
1367 } finally {
1368 Binder.restoreCallingIdentity(ident);
1369 }
1370
1371 return true;
1372 }
1373
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001374 private boolean isCallingOnHandlerThread() {
1375 return Looper.myLooper() == mHandler.getLooper();
1376 }
1377
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001378 /**
1379 * Start user, if its not already running, and bring it to foreground.
1380 */
Evan Rosky18396452016-07-27 15:19:37 -07001381 void startUserInForeground(final int targetUserId) {
1382 boolean success = startUser(targetUserId, /* foreground */ true);
1383 if (!success) {
1384 mInjector.getWindowManager().setSwitchingUser(false);
1385 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001386 }
1387
Bookatzf56f2582019-09-04 16:06:41 -07001388 boolean unlockUser(final @UserIdInt int userId, byte[] token, byte[] secret,
1389 IProgressListener listener) {
Bookatz95df5ca2019-05-30 15:58:46 -07001390 checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "unlockUser");
Felipe Lemeb5f0e742019-09-24 09:35:49 -07001391 Slog.i(TAG, "unlocking user " + userId);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001392 final long binderToken = Binder.clearCallingIdentity();
1393 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001394 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001395 } finally {
1396 Binder.restoreCallingIdentity(binderToken);
1397 }
1398 }
1399
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001400 /**
1401 * Attempt to unlock user without a credential token. This typically
1402 * succeeds when the device doesn't have credential-encrypted storage, or
shafik172e1fb2018-12-05 14:52:38 +00001403 * when the credential-encrypted storage isn't tied to a user-provided
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001404 * PIN or pattern.
1405 */
Bookatzf56f2582019-09-04 16:06:41 -07001406 private boolean maybeUnlockUser(final @UserIdInt int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001407 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001408 return unlockUserCleared(userId, null, null, null);
1409 }
1410
Bookatzf56f2582019-09-04 16:06:41 -07001411 private static void notifyFinished(@UserIdInt int userId, IProgressListener listener) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001412 if (listener == null) return;
1413 try {
1414 listener.onFinished(userId, null);
1415 } catch (RemoteException ignored) {
1416 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001417 }
1418
Bookatzf56f2582019-09-04 16:06:41 -07001419 private boolean unlockUserCleared(final @UserIdInt int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001420 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001421 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001422 if (!StorageManager.isUserKeyUnlocked(userId)) {
1423 final UserInfo userInfo = getUserInfo(userId);
Keun young Parkdf54b662019-03-13 14:06:42 -07001424 final IStorageManager storageManager = mInjector.getStorageManager();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001425 try {
1426 // We always want to unlock user storage, even user is not started yet
1427 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1428 } catch (RemoteException | RuntimeException e) {
1429 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001430 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001431 }
1432 synchronized (mLock) {
1433 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001434 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001435 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001436 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001437 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001438 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001439 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001440 // Bail if user isn't actually running
1441 if (uss == null) {
1442 notifyFinished(userId, listener);
1443 return false;
1444 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001445
Rubin Xu98571a02019-02-28 16:26:06 +00001446 if (!finishUserUnlocking(uss)) {
1447 notifyFinished(userId, listener);
1448 return false;
1449 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001450
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001451 // We just unlocked a user, so let's now attempt to unlock any
1452 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001453
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001454 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1455 int[] userIds;
1456 synchronized (mLock) {
1457 userIds = new int[mStartedUsers.size()];
1458 for (int i = 0; i < userIds.length; i++) {
1459 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001460 }
1461 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001462 for (int testUserId : userIds) {
1463 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1464 if (parent != null && parent.id == userId && testUserId != userId) {
1465 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1466 + "): attempting unlock because parent was just unlocked");
1467 maybeUnlockUser(testUserId);
1468 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001469 }
1470
Jeff Sharkeyba512352015-11-12 20:17:45 -08001471 return true;
1472 }
1473
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001474 boolean switchUser(final int targetUserId) {
1475 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Felipe Lemeb5f0e742019-09-24 09:35:49 -07001476 Slog.i(TAG, "switching to user " + targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001477 int currentUserId = getCurrentUserId();
1478 UserInfo targetUserInfo = getUserInfo(targetUserId);
1479 if (targetUserId == currentUserId) {
1480 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1481 return true;
1482 }
1483 if (targetUserInfo == null) {
1484 Slog.w(TAG, "No user info for user #" + targetUserId);
1485 return false;
1486 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001487 if (!targetUserInfo.supportsSwitchTo()) {
1488 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1489 return false;
1490 }
1491 if (targetUserInfo.isManagedProfile()) {
1492 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1493 return false;
1494 }
Keun young Park4cb99332019-09-19 17:08:41 -07001495 boolean userSwitchUiEnabled;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001496 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001497 mTargetUserId = targetUserId;
Keun young Park4cb99332019-09-19 17:08:41 -07001498 userSwitchUiEnabled = mUserSwitchUiEnabled;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001499 }
Keun young Park4cb99332019-09-19 17:08:41 -07001500 if (userSwitchUiEnabled) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001501 UserInfo currentUserInfo = getUserInfo(currentUserId);
1502 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1503 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1504 mUiHandler.sendMessage(mHandler.obtainMessage(
1505 START_USER_SWITCH_UI_MSG, userNames));
1506 } else {
1507 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1508 mHandler.sendMessage(mHandler.obtainMessage(
1509 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1510 }
1511 return true;
1512 }
1513
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001514 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001515 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001516 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1517 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001518 }
1519
Bookatzf56f2582019-09-04 16:06:41 -07001520 private void dispatchForegroundProfileChanged(@UserIdInt int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001521 final int observerCount = mUserSwitchObservers.beginBroadcast();
1522 for (int i = 0; i < observerCount; i++) {
1523 try {
1524 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1525 } catch (RemoteException e) {
1526 // Ignore
1527 }
1528 }
1529 mUserSwitchObservers.finishBroadcast();
1530 }
1531
1532 /** Called on handler thread */
Bookatzf56f2582019-09-04 16:06:41 -07001533 void dispatchUserSwitchComplete(@UserIdInt int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001534 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001535 final int observerCount = mUserSwitchObservers.beginBroadcast();
1536 for (int i = 0; i < observerCount; i++) {
1537 try {
1538 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1539 } catch (RemoteException e) {
1540 }
1541 }
1542 mUserSwitchObservers.finishBroadcast();
1543 }
1544
Bookatzf56f2582019-09-04 16:06:41 -07001545 private void dispatchLockedBootComplete(@UserIdInt int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001546 final int observerCount = mUserSwitchObservers.beginBroadcast();
1547 for (int i = 0; i < observerCount; i++) {
1548 try {
1549 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1550 } catch (RemoteException e) {
1551 // Ignore
1552 }
1553 }
1554 mUserSwitchObservers.finishBroadcast();
1555 }
1556
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001557 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1558 // Never stop system user
1559 if (oldUserId == UserHandle.USER_SYSTEM) {
1560 return;
1561 }
Keun young Parkdf54b662019-03-13 14:06:42 -07001562 // If running in background is disabled or mDelayUserDataLocking mode, stop the user.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001563 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
Keun young Park4cb99332019-09-19 17:08:41 -07001564 oldUserId) || isDelayUserDataLockingEnabled();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001565 if (!disallowRunInBg) {
1566 return;
1567 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001568 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001569 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1570 + " and related users");
Keun young Park4cb99332019-09-19 17:08:41 -07001571 stopUsersLU(oldUserId, /* force= */ false, /* allowDelayedLocking= */ true,
1572 null, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001573 }
1574 }
1575
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001576 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001577 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001578 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1579 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1580 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001581 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001582 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1583 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1584 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1585 }
1586 }
1587
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001588 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001589 synchronized (mLock) {
1590 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1591 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1592 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1593 mTimeoutUserSwitchCallbacks = null;
1594 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001595 }
1596 }
1597
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001598 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1599 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001600 final int observerCount = mUserSwitchObservers.beginBroadcast();
1601 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001602 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001603 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001604 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001605 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001606 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001607 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001608 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001609 for (int i = 0; i < observerCount; i++) {
1610 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001611 // Prepend with unique prefix to guarantee that keys are unique
1612 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001613 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001614 curWaitingUserSwitchCallbacks.add(name);
1615 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001616 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1617 @Override
1618 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001619 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001620 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001621 if (delay > USER_SWITCH_TIMEOUT_MS) {
Felipe Leme48a75cb2020-01-29 12:15:29 -08001622 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001623 + " sent result after " + delay + " ms");
Felipe Leme48a75cb2020-01-29 12:15:29 -08001624 } else if (delay > USER_SWITCH_WARNING_TIMEOUT_MS) {
1625 Slog.w(TAG, "User switch slowed down by observer " + name
1626 + ": result sent after " + delay + " ms");
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001627 }
Felipe Leme48a75cb2020-01-29 12:15:29 -08001628
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001629 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001630 // Continue switching if all callbacks have been notified and
1631 // user switching session is still valid
1632 if (waitingCallbacksCount.decrementAndGet() == 0
1633 && (curWaitingUserSwitchCallbacks
1634 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001635 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001636 }
1637 }
1638 }
1639 };
1640 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001641 } catch (RemoteException e) {
1642 }
1643 }
1644 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001645 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001646 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001647 }
1648 }
1649 mUserSwitchObservers.finishBroadcast();
1650 }
1651
Andreas Gampee7739b32018-07-20 12:55:36 -07001652 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001653 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001654 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001655 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001656 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001657 oldUserId, newUserId, uss));
1658 }
1659
1660 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001661 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Keun young Park4cb99332019-09-19 17:08:41 -07001662 if (isUserSwitchUiEnabled()) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001663 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001664 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001665 uss.switching = false;
1666 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1667 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1668 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001669 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001670 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001671 }
1672
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001673 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1674 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001675 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001676 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001677 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001678 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001679 }
1680 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001681 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001682 }
1683
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001684 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Michal Karpinskic99d7182019-02-17 13:15:23 +00001685 final int callingUid = Binder.getCallingUid();
1686 final int callingPid = Binder.getCallingPid();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001687 long ident = Binder.clearCallingIdentity();
1688 try {
1689 Intent intent;
1690 if (oldUserId >= 0) {
1691 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001692 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001693 int count = profiles.size();
1694 for (int i = 0; i < count; i++) {
1695 int profileUserId = profiles.get(i).id;
1696 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1697 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1698 | Intent.FLAG_RECEIVER_FOREGROUND);
1699 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Meng Wang67ffabe2020-01-22 17:38:46 -08001700 // Also, add the UserHandle for mainline modules which can't use the @hide
1701 // EXTRA_USER_HANDLE.
1702 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(profileUserId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001703 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001704 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001705 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1706 profileUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001707 }
1708 }
1709 if (newUserId >= 0) {
1710 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001711 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001712 int count = profiles.size();
1713 for (int i = 0; i < count; i++) {
1714 int profileUserId = profiles.get(i).id;
1715 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1716 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1717 | Intent.FLAG_RECEIVER_FOREGROUND);
1718 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Meng Wang67ffabe2020-01-22 17:38:46 -08001719 // Also, add the UserHandle for mainline modules which can't use the @hide
1720 // EXTRA_USER_HANDLE.
1721 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(profileUserId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001722 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001723 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001724 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1725 profileUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001726 }
1727 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1729 | Intent.FLAG_RECEIVER_FOREGROUND);
1730 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Meng Wang67ffabe2020-01-22 17:38:46 -08001731 // Also, add the UserHandle for mainline modules which can't use the @hide
1732 // EXTRA_USER_HANDLE.
1733 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(newUserId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001734 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001735 null, null, 0, null, null,
1736 new String[] {android.Manifest.permission.MANAGE_USERS},
Michal Karpinskic99d7182019-02-17 13:15:23 +00001737 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid,
1738 callingPid, UserHandle.USER_ALL);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001739 }
1740 } finally {
1741 Binder.restoreCallingIdentity(ident);
1742 }
1743 }
1744
1745
Bookatzf56f2582019-09-04 16:06:41 -07001746 int handleIncomingUser(int callingPid, int callingUid, @UserIdInt int userId, boolean allowAll,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001747 int allowMode, String name, String callerPackage) {
1748 final int callingUserId = UserHandle.getUserId(callingUid);
1749 if (callingUserId == userId) {
1750 return userId;
1751 }
1752
1753 // Note that we may be accessing mCurrentUserId outside of a lock...
1754 // shouldn't be a big deal, if this is being called outside
1755 // of a locked context there is intrinsically a race with
1756 // the value the caller will receive and someone else changing it.
1757 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1758 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001759 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001760
1761 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1762 final boolean allow;
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001763 final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, targetUserId);
Tony Make839d702018-01-22 15:34:46 +00001764 if (mInjector.isCallerRecents(callingUid)
Vinit Nayaka6850062019-12-11 16:24:20 -08001765 && isSameProfileGroup(callingUserId, targetUserId)) {
1766 // If the caller is Recents and the caller has ownership of the profile group,
1767 // we then allow it to access its profiles.
Tony Make839d702018-01-22 15:34:46 +00001768 allow = true;
1769 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001770 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1771 // If the caller has this permission, they always pass go. And collect $200.
1772 allow = true;
1773 } else if (allowMode == ALLOW_FULL_ONLY) {
1774 // We require full access, sucks to be you.
1775 allow = false;
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001776 } else if (canInteractWithAcrossProfilesPermission(
kholoud mohamed79a89f02020-01-15 15:30:07 +00001777 allowMode, isSameProfileGroup, callingPid, callingUid, callerPackage)) {
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001778 allow = true;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001779 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001780 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1781 // If the caller does not have either permission, they are always doomed.
1782 allow = false;
1783 } else if (allowMode == ALLOW_NON_FULL) {
1784 // We are blanket allowing non-full access, you lucky caller!
1785 allow = true;
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001786 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE
1787 || allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001788 // We may or may not allow this depending on whether the two users are
1789 // in the same profile.
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001790 allow = isSameProfileGroup;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001791 } else {
1792 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1793 }
1794 if (!allow) {
1795 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1796 // In this case, they would like to just execute as their
1797 // owner user instead of failing.
1798 targetUserId = callingUserId;
1799 } else {
1800 StringBuilder builder = new StringBuilder(128);
1801 builder.append("Permission Denial: ");
1802 builder.append(name);
1803 if (callerPackage != null) {
1804 builder.append(" from ");
1805 builder.append(callerPackage);
1806 }
1807 builder.append(" asks to run as user ");
1808 builder.append(userId);
Dianne Hackborn4760f082019-03-12 11:37:19 -07001809 builder.append(" but is calling from uid ");
1810 UserHandle.formatUid(builder, callingUid);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001811 builder.append("; this requires ");
1812 builder.append(INTERACT_ACROSS_USERS_FULL);
1813 if (allowMode != ALLOW_FULL_ONLY) {
1814 builder.append(" or ");
1815 builder.append(INTERACT_ACROSS_USERS);
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001816 if (isSameProfileGroup
1817 && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
1818 builder.append(" or ");
1819 builder.append(INTERACT_ACROSS_PROFILES);
1820 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001821 }
1822 String msg = builder.toString();
1823 Slog.w(TAG, msg);
1824 throw new SecurityException(msg);
1825 }
1826 }
1827 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001828 if (!allowAll) {
1829 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001830 }
1831 // Check shell permission
1832 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1833 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1834 throw new SecurityException("Shell does not have permission to access user "
1835 + targetUserId + "\n " + Debug.getCallers(3));
1836 }
1837 }
1838 return targetUserId;
1839 }
1840
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001841 private boolean canInteractWithAcrossProfilesPermission(
kholoud mohamed79a89f02020-01-15 15:30:07 +00001842 int allowMode, boolean isSameProfileGroup, int callingPid, int callingUid,
1843 String callingPackage) {
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001844 if (allowMode != ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
1845 return false;
1846 }
1847 if (!isSameProfileGroup) {
1848 return false;
1849 }
kholoud mohamed79a89f02020-01-15 15:30:07 +00001850 return PermissionChecker.PERMISSION_GRANTED
1851 == PermissionChecker.checkPermissionForPreflight(
1852 mInjector.getContext(),
1853 INTERACT_ACROSS_PROFILES,
1854 callingPid,
1855 callingUid,
1856 callingPackage);
kholoud mohamed67ac7c62019-12-06 16:33:48 +00001857 }
1858
Bookatzf56f2582019-09-04 16:06:41 -07001859 int unsafeConvertIncomingUser(@UserIdInt int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001860 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001861 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001862 }
1863
Bookatzf56f2582019-09-04 16:06:41 -07001864 void ensureNotSpecialUser(@UserIdInt int userId) {
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001865 if (userId >= 0) {
1866 return;
1867 }
1868 throw new IllegalArgumentException("Call does not support special user #" + userId);
1869 }
1870
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001871 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
Daulet Zhanguzin44eeff32020-01-03 09:44:46 +00001872 Objects.requireNonNull(name, "Observer name cannot be null");
Bookatz95df5ca2019-05-30 15:58:46 -07001873 checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "registerUserSwitchObserver");
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001874 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001875 }
1876
Bookatzf56f2582019-09-04 16:06:41 -07001877 void sendForegroundProfileChanged(@UserIdInt int userId) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001878 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1879 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1880 }
1881
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001882 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1883 mUserSwitchObservers.unregister(observer);
1884 }
1885
Bookatzf56f2582019-09-04 16:06:41 -07001886 UserState getStartedUserState(@UserIdInt int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001887 synchronized (mLock) {
1888 return mStartedUsers.get(userId);
1889 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001890 }
1891
Bookatzf56f2582019-09-04 16:06:41 -07001892 boolean hasStartedUserState(@UserIdInt int userId) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07001893 synchronized (mLock) {
1894 return mStartedUsers.get(userId) != null;
1895 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001896 }
1897
Andreas Gampee7739b32018-07-20 12:55:36 -07001898 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001899 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001900 int num = 0;
1901 for (int i = 0; i < mStartedUsers.size(); i++) {
1902 UserState uss = mStartedUsers.valueAt(i);
1903 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001904 if (uss.state != UserState.STATE_STOPPING
1905 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001906 num++;
1907 }
1908 }
1909 mStartedUserArray = new int[num];
1910 num = 0;
1911 for (int i = 0; i < mStartedUsers.size(); i++) {
1912 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001913 if (uss.state != UserState.STATE_STOPPING
1914 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001915 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001916 }
1917 }
1918 }
1919
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001920 void sendBootCompleted(IIntentReceiver resultTo) {
Felipe Lemef13851d2019-08-22 10:51:11 -07001921 final boolean systemUserFinishedBooting;
1922
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001923 // Get a copy of mStartedUsers to use outside of lock
1924 SparseArray<UserState> startedUsers;
1925 synchronized (mLock) {
Felipe Lemef13851d2019-08-22 10:51:11 -07001926 systemUserFinishedBooting = mCurrentUserId != UserHandle.USER_SYSTEM;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001927 startedUsers = mStartedUsers.clone();
1928 }
1929 for (int i = 0; i < startedUsers.size(); i++) {
1930 UserState uss = startedUsers.valueAt(i);
Felipe Lemef13851d2019-08-22 10:51:11 -07001931 if (systemUserFinishedBooting && uss.mHandle.isSystem()) {
Felipe Leme58e751f2019-08-26 13:39:39 -07001932 // On Automotive, at this point the system user has already been started and
1933 // unlocked, and some of the tasks we do here have already been done. So skip those
1934 // in that case.
1935 // TODO(b/132262830): this workdound shouldn't be necessary once we move the
Felipe Lemef13851d2019-08-22 10:51:11 -07001936 // headless-user start logic to UserManager-land
1937 Slog.d(TAG, "sendBootCompleted(): skipping on non-current system user");
1938 continue;
1939 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001940 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001941 }
1942 }
1943
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001944 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001945 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001946 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001947 }
1948
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001949 /**
1950 * Refreshes the list of users related to the current user when either a
1951 * user switch happens or when a new related user is started in the
1952 * background.
1953 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001954 private void updateCurrentProfileIds() {
1955 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001956 false /* enabledOnly */);
1957 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1958 for (int i = 0; i < currentProfileIds.length; i++) {
1959 currentProfileIds[i] = profiles.get(i).id;
1960 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001961 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1962 synchronized (mLock) {
1963 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001964
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001965 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001966 for (int i = 0; i < users.size(); i++) {
1967 UserInfo user = users.get(i);
1968 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001969 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001970 }
1971 }
1972 }
1973 }
1974
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001975 int[] getStartedUserArray() {
1976 synchronized (mLock) {
1977 return mStartedUserArray;
1978 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001979 }
1980
Bookatzf56f2582019-09-04 16:06:41 -07001981 boolean isUserRunning(@UserIdInt int userId, int flags) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001982 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001983 if (state == null) {
1984 return false;
1985 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001986 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001987 return true;
1988 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001989 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001990 switch (state.state) {
1991 case UserState.STATE_BOOTING:
1992 case UserState.STATE_RUNNING_LOCKED:
1993 return true;
1994 default:
1995 return false;
1996 }
1997 }
1998 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1999 switch (state.state) {
2000 case UserState.STATE_RUNNING_UNLOCKING:
2001 case UserState.STATE_RUNNING_UNLOCKED:
2002 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07002003 // In the stopping/shutdown state return unlock state of the user key
2004 case UserState.STATE_STOPPING:
2005 case UserState.STATE_SHUTDOWN:
2006 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06002007 default:
2008 return false;
2009 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08002010 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07002011 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06002012 switch (state.state) {
2013 case UserState.STATE_RUNNING_UNLOCKED:
2014 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07002015 // In the stopping/shutdown state return unlock state of the user key
2016 case UserState.STATE_STOPPING:
2017 case UserState.STATE_SHUTDOWN:
2018 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06002019 default:
2020 return false;
2021 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07002022 }
2023
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07002024 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002025 }
2026
Keun young Parke339eef2019-03-27 13:20:16 -07002027 /**
2028 * Check if system user is already started. Unlike other user, system user is in STATE_BOOTING
2029 * even if it is not explicitly started. So isUserRunning cannot give the right state
2030 * to check if system user is started or not.
2031 * @return true if system user is started.
2032 */
2033 boolean isSystemUserStarted() {
2034 synchronized (mLock) {
2035 UserState uss = mStartedUsers.get(UserHandle.USER_SYSTEM);
2036 if (uss == null) {
2037 return false;
2038 }
2039 return uss.state == UserState.STATE_RUNNING_LOCKED
2040 || uss.state == UserState.STATE_RUNNING_UNLOCKING
2041 || uss.state == UserState.STATE_RUNNING_UNLOCKED;
2042 }
2043 }
2044
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002045 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002046 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002047 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002048 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002049 != PackageManager.PERMISSION_GRANTED)) {
2050 String msg = "Permission Denial: getCurrentUser() from pid="
2051 + Binder.getCallingPid()
2052 + ", uid=" + Binder.getCallingUid()
2053 + " requires " + INTERACT_ACROSS_USERS;
2054 Slog.w(TAG, msg);
2055 throw new SecurityException(msg);
2056 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07002057
2058 // Optimization - if there is no pending user switch, return current id
felipeal7f1e2f12019-11-06 06:17:28 -08002059 // (no need to acquire lock because mTargetUserId and mCurrentUserId are volatile)
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07002060 if (mTargetUserId == UserHandle.USER_NULL) {
2061 return getUserInfo(mCurrentUserId);
2062 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002063 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002064 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002065 }
2066 }
2067
Andreas Gampee7739b32018-07-20 12:55:36 -07002068 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002069 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002070 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002071 return getUserInfo(userId);
2072 }
2073
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002074 int getCurrentOrTargetUserId() {
2075 synchronized (mLock) {
felipeal7f1e2f12019-11-06 06:17:28 -08002076 return getCurrentOrTargetUserIdLU();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002077 }
2078 }
2079
Andreas Gampee7739b32018-07-20 12:55:36 -07002080 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002081 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002082 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002083 }
2084
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002085
Andreas Gampee7739b32018-07-20 12:55:36 -07002086 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002087 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002088 return mCurrentUserId;
2089 }
2090
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002091 int getCurrentUserId() {
2092 synchronized (mLock) {
2093 return mCurrentUserId;
2094 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07002095 }
2096
Andreas Gampee7739b32018-07-20 12:55:36 -07002097 @GuardedBy("mLock")
Bookatzf56f2582019-09-04 16:06:41 -07002098 private boolean isCurrentUserLU(@UserIdInt int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002099 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002100 }
2101
2102 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002103 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002104 return ums != null ? ums.getUserIds() : new int[] { 0 };
2105 }
2106
Bookatzf56f2582019-09-04 16:06:41 -07002107 private UserInfo getUserInfo(@UserIdInt int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002108 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002109 }
2110
2111 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002112 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002113 }
2114
Makoto Onuki6569c362018-02-27 15:52:01 -08002115 /**
2116 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
2117 * IDs. Otherwise return an array whose only element is the given user id.
2118 *
2119 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
2120 */
Bookatzf56f2582019-09-04 16:06:41 -07002121 int[] expandUserId(@UserIdInt int userId) {
Makoto Onuki6569c362018-02-27 15:52:01 -08002122 if (userId != UserHandle.USER_ALL) {
2123 return new int[] {userId};
2124 } else {
2125 return getUsers();
2126 }
2127 }
2128
Bookatzf56f2582019-09-04 16:06:41 -07002129 boolean exists(@UserIdInt int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002130 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002131 }
2132
Bookatz95df5ca2019-05-30 15:58:46 -07002133 private void checkCallingPermission(String permission, String methodName) {
2134 if (mInjector.checkCallingPermission(permission)
2135 != PackageManager.PERMISSION_GRANTED) {
2136 String msg = "Permission denial: " + methodName
2137 + "() from pid=" + Binder.getCallingPid()
2138 + ", uid=" + Binder.getCallingUid()
2139 + " requires " + permission;
2140 Slog.w(TAG, msg);
2141 throw new SecurityException(msg);
2142 }
2143 }
2144
Bookatzf56f2582019-09-04 16:06:41 -07002145 private void enforceShellRestriction(String restriction, @UserIdInt int userId) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002146 if (Binder.getCallingUid() == SHELL_UID) {
Bookatzf56f2582019-09-04 16:06:41 -07002147 if (userId < 0 || hasUserRestriction(restriction, userId)) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002148 throw new SecurityException("Shell does not have permission to access user "
Bookatzf56f2582019-09-04 16:06:41 -07002149 + userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002150 }
2151 }
2152 }
2153
Bookatzf56f2582019-09-04 16:06:41 -07002154 boolean hasUserRestriction(String restriction, @UserIdInt int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002155 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002156 }
2157
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002158 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07002159 if (callingUserId == targetUserId) {
2160 return true;
2161 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002162 synchronized (mLock) {
2163 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002164 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002165 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002166 UserInfo.NO_PROFILE_GROUP_ID);
2167 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
2168 && callingProfile == targetProfile;
2169 }
2170 }
2171
Bookatzf56f2582019-09-04 16:06:41 -07002172 boolean isUserOrItsParentRunning(@UserIdInt int userId) {
Tony Mak60f53e62017-12-21 20:03:29 +00002173 synchronized (mLock) {
2174 if (isUserRunning(userId, 0)) {
2175 return true;
2176 }
2177 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
2178 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
2179 return false;
2180 }
2181 return isUserRunning(parentUserId, 0);
2182 }
2183 }
2184
Bookatzf56f2582019-09-04 16:06:41 -07002185 boolean isCurrentProfile(@UserIdInt int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002186 synchronized (mLock) {
2187 return ArrayUtils.contains(mCurrentProfileIds, userId);
2188 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002189 }
2190
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002191 int[] getCurrentProfileIds() {
2192 synchronized (mLock) {
2193 return mCurrentProfileIds;
2194 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002195 }
2196
Bookatzf56f2582019-09-04 16:06:41 -07002197 void onUserRemoved(@UserIdInt int userId) {
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08002198 synchronized (mLock) {
2199 int size = mUserProfileGroupIds.size();
2200 for (int i = size - 1; i >= 0; i--) {
2201 if (mUserProfileGroupIds.keyAt(i) == userId
2202 || mUserProfileGroupIds.valueAt(i) == userId) {
2203 mUserProfileGroupIds.removeAt(i);
2204
2205 }
2206 }
2207 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
2208 }
2209 }
2210
Clara Bayarriea9b10e2015-12-04 15:36:26 +00002211 /**
2212 * Returns whether the given user requires credential entry at this time. This is used to
2213 * intercept activity launches for work apps when the Work Challenge is present.
2214 */
Bookatzf56f2582019-09-04 16:06:41 -07002215 protected boolean shouldConfirmCredentials(@UserIdInt int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002216 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00002217 if (mStartedUsers.get(userId) == null) {
2218 return false;
2219 }
2220 }
Clara Bayarria1771112015-12-18 16:29:18 +00002221 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00002222 return false;
2223 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002224 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01002225 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00002226 }
2227
Tony Mak8c536f92016-03-21 12:20:41 +00002228 boolean isLockScreenDisabled(@UserIdInt int userId) {
2229 return mLockPatternUtils.isLockScreenDisabled(userId);
2230 }
2231
Alex Chau93ae42b2018-01-11 15:10:12 +00002232 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
2233 synchronized (mLock) {
2234 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
2235 }
2236 }
2237
2238 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
2239 synchronized (mLock) {
2240 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
2241 }
2242 }
2243
2244 private String getSwitchingFromSystemUserMessage() {
2245 synchronized (mLock) {
2246 return mSwitchingFromSystemUserMessage;
2247 }
2248 }
2249
2250 private String getSwitchingToSystemUserMessage() {
2251 synchronized (mLock) {
2252 return mSwitchingToSystemUserMessage;
2253 }
2254 }
2255
Jeffrey Huangcb782852019-12-05 11:28:11 -08002256 void dumpDebug(ProtoOutputStream proto, long fieldId) {
Yi Jin148d7f42017-11-28 14:23:56 -08002257 synchronized (mLock) {
2258 long token = proto.start(fieldId);
2259 for (int i = 0; i < mStartedUsers.size(); i++) {
2260 UserState uss = mStartedUsers.valueAt(i);
2261 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
2262 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
Jeffrey Huangcb782852019-12-05 11:28:11 -08002263 uss.dumpDebug(proto, UserControllerProto.User.STATE);
Yi Jin148d7f42017-11-28 14:23:56 -08002264 proto.end(uToken);
2265 }
2266 for (int i = 0; i < mStartedUserArray.length; i++) {
2267 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
2268 }
2269 for (int i = 0; i < mUserLru.size(); i++) {
2270 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
2271 }
2272 if (mUserProfileGroupIds.size() > 0) {
2273 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
2274 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
2275 proto.write(UserControllerProto.UserProfile.USER,
2276 mUserProfileGroupIds.keyAt(i));
2277 proto.write(UserControllerProto.UserProfile.PROFILE,
2278 mUserProfileGroupIds.valueAt(i));
2279 proto.end(uToken);
2280 }
2281 }
2282 proto.end(token);
2283 }
2284 }
2285
Felipe Leme79bd6ad2019-11-20 10:51:34 -08002286 void dump(PrintWriter pw) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002287 synchronized (mLock) {
2288 pw.println(" mStartedUsers:");
2289 for (int i = 0; i < mStartedUsers.size(); i++) {
2290 UserState uss = mStartedUsers.valueAt(i);
2291 pw.print(" User #");
2292 pw.print(uss.mHandle.getIdentifier());
2293 pw.print(": ");
2294 uss.dump("", pw);
2295 }
2296 pw.print(" mStartedUserArray: [");
2297 for (int i = 0; i < mStartedUserArray.length; i++) {
2298 if (i > 0)
2299 pw.print(", ");
2300 pw.print(mStartedUserArray[i]);
2301 }
2302 pw.println("]");
2303 pw.print(" mUserLru: [");
2304 for (int i = 0; i < mUserLru.size(); i++) {
2305 if (i > 0)
2306 pw.print(", ");
2307 pw.print(mUserLru.get(i));
2308 }
2309 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002310 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002311 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002312 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002313 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002314 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002315 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002316 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002317 }
2318 }
Keun young Parkdf54b662019-03-13 14:06:42 -07002319 pw.println(" mCurrentUserId:" + mCurrentUserId);
Felipe Leme79bd6ad2019-11-20 10:51:34 -08002320 pw.println(" mTargetUserId:" + mTargetUserId);
Keun young Parkdf54b662019-03-13 14:06:42 -07002321 pw.println(" mLastActiveUsers:" + mLastActiveUsers);
Felipe Leme79bd6ad2019-11-20 10:51:34 -08002322 pw.println(" mDelayUserDataLocking:" + mDelayUserDataLocking);
2323 pw.println(" mMaxRunningUsers:" + mMaxRunningUsers);
2324 pw.println(" mUserSwitchUiEnabled:" + mUserSwitchUiEnabled);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002325 }
2326 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002327
Felipe Leme137e7812019-06-10 11:38:05 -07002328 @Override
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002329 public boolean handleMessage(Message msg) {
2330 switch (msg.what) {
2331 case START_USER_SWITCH_FG_MSG:
2332 startUserInForeground(msg.arg1);
2333 break;
2334 case REPORT_USER_SWITCH_MSG:
2335 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2336 break;
2337 case CONTINUE_USER_SWITCH_MSG:
2338 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2339 break;
2340 case USER_SWITCH_TIMEOUT_MSG:
2341 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2342 break;
2343 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
2344 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
2345 break;
2346 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002347 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002348 break;
Felipe Lemec1ca4412019-09-11 09:23:26 -07002349 case USER_START_MSG:
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002350 mInjector.batteryStatsServiceNoteEvent(
2351 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2352 Integer.toString(msg.arg1), msg.arg1);
Felipe Leme137e7812019-06-10 11:38:05 -07002353 mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
2354 msg.arg1);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002355 break;
Felipe Lemec1ca4412019-09-11 09:23:26 -07002356 case USER_UNLOCK_MSG:
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002357 final int userId = msg.arg1;
2358 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08002359 // Loads recents on a worker thread that allows disk I/O
2360 FgThread.getHandler().post(() -> {
2361 mInjector.loadUserRecents(userId);
2362 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002363 finishUserUnlocked((UserState) msg.obj);
2364 break;
Felipe Lemec1ca4412019-09-11 09:23:26 -07002365 case USER_CURRENT_MSG:
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002366 mInjector.batteryStatsServiceNoteEvent(
2367 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2368 Integer.toString(msg.arg2), msg.arg2);
2369 mInjector.batteryStatsServiceNoteEvent(
2370 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2371 Integer.toString(msg.arg1), msg.arg1);
2372
Felipe Leme501a5142019-08-15 16:23:47 -07002373 mInjector.getSystemServiceManager().switchUser(msg.arg2, msg.arg1);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002374 break;
2375 case FOREGROUND_PROFILE_CHANGED_MSG:
2376 dispatchForegroundProfileChanged(msg.arg1);
2377 break;
2378 case REPORT_USER_SWITCH_COMPLETE_MSG:
2379 dispatchUserSwitchComplete(msg.arg1);
2380 break;
2381 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
2382 dispatchLockedBootComplete(msg.arg1);
2383 break;
2384 case START_USER_SWITCH_UI_MSG:
2385 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2386 break;
2387 }
2388 return false;
2389 }
2390
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002391 private static class UserProgressListener extends IProgressListener.Stub {
2392 private volatile long mUnlockStarted;
2393 @Override
2394 public void onStarted(int id, Bundle extras) throws RemoteException {
2395 Slog.d(TAG, "Started unlocking user " + id);
2396 mUnlockStarted = SystemClock.uptimeMillis();
2397 }
2398
2399 @Override
2400 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2401 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2402 }
2403
2404 @Override
2405 public void onFinished(int id, Bundle extras) throws RemoteException {
2406 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2407
2408 // Report system user unlock time to perf dashboard
2409 if (id == UserHandle.USER_SYSTEM) {
Felipe Leme137e7812019-06-10 11:38:05 -07002410 new TimingsTraceAndSlog().logDuration("SystemUserUnlock", unlockTime);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002411 } else {
Felipe Leme137e7812019-06-10 11:38:05 -07002412 new TimingsTraceAndSlog().logDuration("User" + id + "Unlock", unlockTime);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002413 }
2414 }
Felipe Leme137e7812019-06-10 11:38:05 -07002415 }
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002416
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002417 @VisibleForTesting
2418 static class Injector {
2419 private final ActivityManagerService mService;
2420 private UserManagerService mUserManager;
2421 private UserManagerInternal mUserManagerInternal;
2422
2423 Injector(ActivityManagerService service) {
2424 mService = service;
2425 }
2426
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002427 protected Handler getHandler(Handler.Callback callback) {
2428 return new Handler(mService.mHandlerThread.getLooper(), callback);
2429 }
2430
2431 protected Handler getUiHandler(Handler.Callback callback) {
2432 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002433 }
2434
2435 protected Context getContext() {
2436 return mService.mContext;
2437 }
2438
2439 protected LockPatternUtils getLockPatternUtils() {
2440 return new LockPatternUtils(getContext());
2441 }
2442
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002443 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002444 IIntentReceiver resultTo, int resultCode, String resultData,
2445 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
Michal Karpinskic99d7182019-02-17 13:15:23 +00002446 boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
Bookatzf56f2582019-09-04 16:06:41 -07002447 int realCallingPid, @UserIdInt int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002448 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2449 synchronized (mService) {
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -08002450 return mService.broadcastIntentLocked(null, null, null, intent, resolvedType,
2451 resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp,
2452 bOptions, ordered, sticky, callingPid, callingUid, realCallingUid,
2453 realCallingPid, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002454 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002455 }
2456
2457 int checkCallingPermission(String permission) {
2458 return mService.checkCallingPermission(permission);
2459 }
2460
2461 WindowManagerService getWindowManager() {
2462 return mService.mWindowManager;
2463 }
Bookatzf56f2582019-09-04 16:06:41 -07002464 void activityManagerOnUserStopped(@UserIdInt int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002465 LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002466 }
2467
Bookatzf56f2582019-09-04 16:06:41 -07002468 void systemServiceManagerCleanupUser(@UserIdInt int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002469 mService.mSystemServiceManager.cleanupUser(userId);
2470 }
2471
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002472 protected UserManagerService getUserManager() {
2473 if (mUserManager == null) {
2474 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2475 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2476 }
2477 return mUserManager;
2478 }
2479
2480 UserManagerInternal getUserManagerInternal() {
2481 if (mUserManagerInternal == null) {
2482 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2483 }
2484 return mUserManagerInternal;
2485 }
2486
2487 KeyguardManager getKeyguardManager() {
2488 return mService.mContext.getSystemService(KeyguardManager.class);
2489 }
2490
2491 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2492 mService.mBatteryStatsService.noteEvent(code, name, uid);
2493 }
2494
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002495 boolean isRuntimeRestarted() {
2496 return mService.mSystemServiceManager.isRuntimeRestarted();
2497 }
2498
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002499 SystemServiceManager getSystemServiceManager() {
2500 return mService.mSystemServiceManager;
2501 }
2502
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002503 boolean isFirstBootOrUpgrade() {
2504 IPackageManager pm = AppGlobals.getPackageManager();
2505 try {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002506 return pm.isFirstBoot() || pm.isDeviceUpgrading();
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002507 } catch (RemoteException e) {
2508 throw e.rethrowFromSystemServer();
2509 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002510 }
2511
Bookatzf56f2582019-09-04 16:06:41 -07002512 void sendPreBootBroadcast(@UserIdInt int userId, boolean quiet, final Runnable onFinish) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002513 new PreBootBroadcaster(mService, userId, null, quiet) {
2514 @Override
2515 public void onFinished() {
2516 onFinish.run();
2517 }
2518 }.sendNext();
2519 }
2520
Bookatzf56f2582019-09-04 16:06:41 -07002521 void activityManagerForceStopPackage(@UserIdInt int userId, String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002522 synchronized (mService) {
2523 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2524 userId, reason);
2525 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002526 };
2527
2528 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2529 boolean exported) {
2530 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2531 }
2532
Bookatzf56f2582019-09-04 16:06:41 -07002533 protected void startHomeActivity(@UserIdInt int userId, String reason) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07002534 mService.mAtmInternal.startHomeActivity(userId, reason);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002535 }
2536
Bookatzf56f2582019-09-04 16:06:41 -07002537 void startUserWidgets(@UserIdInt int userId) {
Christopher Tate88dc93f2018-07-27 16:48:37 -07002538 AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
Ralph Nathan1d1e80a2018-08-13 16:08:53 -07002539 if (awm != null) {
Christopher Tate63227d92019-02-13 14:24:01 -08002540 // Out of band, because this is called during a sequence with
2541 // sensitive cross-service lock management
2542 FgThread.getHandler().post(() -> {
2543 awm.unlockUser(userId);
2544 });
Ralph Nathan1d1e80a2018-08-13 16:08:53 -07002545 }
Christopher Tate88dc93f2018-07-27 16:48:37 -07002546 }
2547
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002548 void updateUserConfiguration() {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002549 mService.mAtmInternal.updateUserConfiguration();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002550 }
2551
Bookatzf56f2582019-09-04 16:06:41 -07002552 void clearBroadcastQueueForUser(@UserIdInt int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002553 synchronized (mService) {
2554 mService.clearBroadcastQueueForUserLocked(userId);
2555 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002556 }
2557
Bookatzf56f2582019-09-04 16:06:41 -07002558 void loadUserRecents(@UserIdInt int userId) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002559 mService.mAtmInternal.loadRecentTasksForUser(userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002560 }
2561
2562 void startPersistentApps(int matchFlags) {
2563 mService.startPersistentApps(matchFlags);
2564 }
2565
Bookatzf56f2582019-09-04 16:06:41 -07002566 void installEncryptionUnawareProviders(@UserIdInt int userId) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002567 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002568 }
2569
Alex Chau93ae42b2018-01-11 15:10:12 +00002570 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2571 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002572 Dialog d;
2573 if (!mService.mContext.getPackageManager()
2574 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2575 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002576 true /* above system */, switchingFromSystemUserMessage,
2577 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002578 } else {
2579 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2580 true /* above system */, switchingFromSystemUserMessage,
2581 switchingToSystemUserMessage);
2582 }
2583
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002584 d.show();
2585 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002586
Dianne Hackbornced54392018-02-26 13:07:42 -08002587 void reportGlobalUsageEventLocked(int event) {
2588 synchronized (mService) {
2589 mService.reportGlobalUsageEventLocked(event);
2590 }
2591 }
2592
2593 void reportCurWakefulnessUsageEvent() {
2594 synchronized (mService) {
2595 mService.reportCurWakefulnessUsageEventLocked();
2596 }
2597 }
2598
Bookatzf56f2582019-09-04 16:06:41 -07002599 void stackSupervisorRemoveUser(@UserIdInt int userId) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002600 mService.mAtmInternal.removeUser(userId);
Tony Mak5c2cf032017-04-03 18:38:23 +01002601 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002602
Bookatzf56f2582019-09-04 16:06:41 -07002603 protected boolean stackSupervisorSwitchUser(@UserIdInt int userId, UserState uss) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002604 return mService.mAtmInternal.switchUser(userId, uss);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002605 }
2606
2607 protected void stackSupervisorResumeFocusedStackTopActivity() {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002608 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002609 }
2610
Charles Heff9b4dff2017-09-22 10:18:37 +01002611 protected void clearAllLockedTasks(String reason) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002612 mService.mAtmInternal.clearLockedTasks(reason);
Benjamin Franza83859f2017-07-03 16:34:14 +01002613 }
Tony Make839d702018-01-22 15:34:46 +00002614
2615 protected boolean isCallerRecents(int callingUid) {
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002616 return mService.mAtmInternal.isCallerRecents(callingUid);
Tony Make839d702018-01-22 15:34:46 +00002617 }
Keun young Parkdf54b662019-03-13 14:06:42 -07002618
2619 protected IStorageManager getStorageManager() {
2620 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
2621 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002622 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002623}