blob: b311233694ce3b339ec18a0bf15f8828f0c5595e [file] [log] [blame]
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070021import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
22import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070023import static android.app.ActivityManager.USER_OP_IS_CURRENT;
24import static android.app.ActivityManager.USER_OP_SUCCESS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070025import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
26import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
27import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
Ng Zhi An150a6ba2018-08-13 09:08:11 -070028import static android.os.Process.SHELL_UID;
29import static android.os.Process.SYSTEM_UID;
30
31import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
32import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
33import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070034import static com.android.server.am.ActivityManagerService.MY_PID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060035import static com.android.server.am.UserState.STATE_BOOTING;
36import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
37import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
38import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070039
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070040import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000041import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000042import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070043import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080044import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070045import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070046import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070047import android.app.IStopUserCallback;
48import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000049import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080050import android.app.usage.UsageEvents;
Christopher Tate88dc93f2018-07-27 16:48:37 -070051import android.appwidget.AppWidgetManagerInternal;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070052import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070053import android.content.IIntentReceiver;
54import android.content.Intent;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080055import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070056import android.content.pm.PackageManager;
57import android.content.pm.UserInfo;
58import android.os.BatteryStats;
59import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060060import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070061import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070062import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070063import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070064import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060065import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070066import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070067import android.os.IUserManager;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -070068import android.os.Looper;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070069import android.os.Message;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070070import android.os.Process;
71import android.os.RemoteCallbackList;
72import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070073import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070074import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070075import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070076import android.os.UserHandle;
77import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010078import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080079import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080080import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070081import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070082import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070083import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080084import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070085import android.util.Slog;
86import android.util.SparseArray;
87import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070088import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080089import android.util.proto.ProtoOutputStream;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070090
91import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080092import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070093import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070094import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070095import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070096import com.android.internal.util.Preconditions;
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;
Ng Zhi An150a6ba2018-08-13 09:08:11 -0700103import com.android.server.wm.ActivityTaskManagerInternal;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700104import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700105
106import java.io.PrintWriter;
107import java.util.ArrayList;
108import java.util.Arrays;
Alex Chaub6ef8692018-01-09 14:16:36 +0000109import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700110import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600111import java.util.Objects;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700112import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700113
114/**
115 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700116 *
117 * <p>This class use {@link #mLock} to synchronize access to internal state. Methods that require
118 * {@link #mLock} to be held should have "LU" suffix in the name.
119 *
120 * <p><strong>Important:</strong> Synchronized code, i.e. one executed inside a synchronized(mLock)
121 * block or inside LU method, should only access internal state of this class or make calls to
122 * other LU methods. Non-LU method calls or calls to external classes are discouraged as they
123 * may cause lock inversion.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700124 */
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700125class UserController implements Handler.Callback {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700126 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600127
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700128 // Amount of time we wait for observers to handle a user switch before
129 // giving up on them and unfreezing the screen.
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700130 static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
131
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700132 // ActivityManager thread message constants
133 static final int REPORT_USER_SWITCH_MSG = 10;
134 static final int CONTINUE_USER_SWITCH_MSG = 20;
135 static final int USER_SWITCH_TIMEOUT_MSG = 30;
136 static final int START_PROFILES_MSG = 40;
137 static final int SYSTEM_USER_START_MSG = 50;
138 static final int SYSTEM_USER_CURRENT_MSG = 60;
139 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
140 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
141 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
142 static final int SYSTEM_USER_UNLOCK_MSG = 100;
143 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
144 static final int START_USER_SWITCH_FG_MSG = 120;
145
146 // UI thread message constants
147 static final int START_USER_SWITCH_UI_MSG = 1000;
148
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700149 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
150 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
151 // when it never calls back.
152 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700153
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700154 /**
155 * Maximum number of users we allow to be running at a time, including system user.
156 *
157 * <p>This parameter only affects how many background users will be stopped when switching to a
158 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
159 *
160 * <p>Note: Current and system user (and their related profiles) are never stopped when
161 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
162 */
163 int mMaxRunningUsers;
164
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700165 // Lock for internal state.
166 private final Object mLock = new Object();
167
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700168 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700169 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700170 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700171
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700172 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700173 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700174 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
175 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
176 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700177 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700178 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700179
180 /**
181 * Which users have been started, so are allowed to run code.
182 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700183 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700184 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800185
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700186 /**
187 * LRU list of history of current users. Most recently current is at the end.
188 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700189 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700190 private final ArrayList<Integer> mUserLru = new ArrayList<>();
191
192 /**
193 * Constant array of the users that are currently started.
194 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700195 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700196 private int[] mStartedUserArray = new int[] { 0 };
197
198 // If there are multiple profiles for the current user, their ids are here
199 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700200 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700201 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700202
203 /**
204 * Mapping from each known user ID to the profile group ID it is associated with.
205 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700206 @GuardedBy("mLock")
207 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700208
209 /**
210 * Registered observers of the user switching mechanics.
211 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700212 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700213 = new RemoteCallbackList<>();
214
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700215 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700216
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700217 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700218 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700219 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700220 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700221 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700222
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700223 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000224 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
225 */
226 @GuardedBy("mLock")
227 private String mSwitchingFromSystemUserMessage;
228
229 /**
230 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
231 */
232 @GuardedBy("mLock")
233 private String mSwitchingToSystemUserMessage;
234
235 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700236 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
237 */
238 @GuardedBy("mLock")
239 private ArraySet<String> mTimeoutUserSwitchCallbacks;
240
Clara Bayarria1771112015-12-18 16:29:18 +0000241 private final LockPatternUtils mLockPatternUtils;
242
Ng Zhi An7ff7fdb2019-01-16 15:35:51 -0800243 volatile boolean mBootCompleted;
244
Keun young Parkdf54b662019-03-13 14:06:42 -0700245 /**
246 * In this mode, user is always stopped when switched out but locking of user data is
247 * postponed until total number of unlocked users in the system reaches mMaxRunningUsers.
248 * Once total number of unlocked users reach mMaxRunningUsers, least recentely used user
249 * will be locked.
250 */
251 boolean mDelayUserDataLocking;
252 /**
253 * Keep track of last active users for mDelayUserDataLocking.
254 * The latest stopped user is placed in front while the least recently stopped user in back.
255 */
256 @GuardedBy("mLock")
257 private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>();
258
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700259 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700260 this(new Injector(service));
261 }
262
263 @VisibleForTesting
264 UserController(Injector injector) {
265 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700266 mHandler = mInjector.getHandler(this);
267 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700268 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800269 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700270 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800271 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700272 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700273 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700274 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700275 }
276
277 void finishUserSwitch(UserState uss) {
Wale Ogunwale86b74462018-07-02 08:42:43 -0700278 // This call holds the AM lock so we post to the handler.
279 mHandler.post(() -> {
280 finishUserBoot(uss);
281 startProfiles();
282 synchronized (mLock) {
283 stopRunningUsersLU(mMaxRunningUsers);
284 }
285 });
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700286 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700287
Andreas Gampee7739b32018-07-20 12:55:36 -0700288 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000289 List<Integer> getRunningUsersLU() {
290 ArrayList<Integer> runningUsers = new ArrayList<>();
291 for (Integer userId : mUserLru) {
292 UserState uss = mStartedUsers.get(userId);
293 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700294 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700295 continue;
296 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000297 if (uss.state == UserState.STATE_STOPPING
298 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700299 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700300 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700301 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000302 if (userId == UserHandle.USER_SYSTEM) {
303 // We only count system user as running when it is not a pure system user.
304 if (UserInfo.isSystemOnly(userId)) {
305 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700306 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000307 }
308 runningUsers.add(userId);
309 }
310 return runningUsers;
311 }
312
Andreas Gampee7739b32018-07-20 12:55:36 -0700313 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000314 void stopRunningUsersLU(int maxRunningUsers) {
315 List<Integer> currentlyRunning = getRunningUsersLU();
316 Iterator<Integer> iterator = currentlyRunning.iterator();
317 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
318 Integer userId = iterator.next();
319 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
320 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700321 continue;
322 }
Pavel Grafov67d44262019-05-03 15:58:54 +0100323 if (stopUsersLU(userId, false, null, null) == USER_OP_SUCCESS) {
Alex Chaub6ef8692018-01-09 14:16:36 +0000324 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700325 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000326 }
327 }
328
329 /**
330 * Returns if more users can be started without stopping currently running users.
331 */
332 boolean canStartMoreUsers() {
333 synchronized (mLock) {
334 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700335 }
336 }
337
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800338 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700339 finishUserBoot(uss, null);
340 }
341
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800342 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700343 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700344
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700345 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700346 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700347 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700348 if (mStartedUsers.get(userId) != uss) {
349 return;
350 }
351 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700352
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700353 // We always walk through all the user lifecycle states to send
354 // consistent developer events. We step into RUNNING_LOCKED here,
355 // but we might immediately step into RUNNING below if the user
356 // storage is already unlocked.
357 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
358 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
359 // Do not report secondary users, runtime restarts or first boot/upgrade
360 if (userId == UserHandle.USER_SYSTEM
361 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
362 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
363 MetricsLogger.histogram(mInjector.getContext(),
364 "framework_locked_boot_completed", uptimeSeconds);
365 final int MAX_UPTIME_SECONDS = 120;
366 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
367 Slog.wtf("SystemServerTiming",
368 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800369 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700370 }
371
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700372 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
373 userId, 0));
374 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
375 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
376 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
377 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
378 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
379 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
Michal Karpinskic99d7182019-02-17 13:15:23 +0000380 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
381 Binder.getCallingUid(), Binder.getCallingPid(), userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700382 }
383
384 // We need to delay unlocking managed profiles until the parent user
385 // is also unlocked.
386 if (mInjector.getUserManager().isManagedProfile(userId)) {
387 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
388 if (parent != null
389 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
390 Slog.d(TAG, "User " + userId + " (parent " + parent.id
391 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600392 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700393 } else {
394 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
395 Slog.d(TAG, "User " + userId + " (parent " + parentId
396 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600397 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700398 } else {
399 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700400 }
401 }
402
403 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600404 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
405 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700406 */
Rubin Xu98571a02019-02-28 16:26:06 +0000407 private boolean finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700408 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700409 // Only keep marching forward if user is actually unlocked
Rubin Xu98571a02019-02-28 16:26:06 +0000410 if (!StorageManager.isUserKeyUnlocked(userId)) return false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700411 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800412 // Do not proceed if unexpected state or a stale user
413 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Rubin Xu98571a02019-02-28 16:26:06 +0000414 return false;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600415 }
416 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700417 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200418
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700419 // Prepare app storage before we go any further
420 uss.mUnlockProgress.setProgress(5,
421 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200422
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800423 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
424 FgThread.getHandler().post(() -> {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100425 if (!StorageManager.isUserKeyUnlocked(userId)) {
426 Slog.w(TAG, "User key got locked unexpectedly, leaving user locked.");
427 return;
428 }
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800429 mInjector.getUserManager().onBeforeUnlockUser(userId);
430 synchronized (mLock) {
431 // Do not proceed if unexpected state
432 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
433 return;
434 }
435 }
436 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
437
438 uss.mUnlockProgress.setProgress(20);
439
440 // Dispatch unlocked to system services; when fully dispatched,
441 // that calls through to the next "unlocked" phase
442 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
443 .sendToTarget();
444 });
Rubin Xu98571a02019-02-28 16:26:06 +0000445 return true;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600446 }
447
448 /**
449 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
450 * {@link UserState#STATE_RUNNING_UNLOCKED}.
451 */
452 void finishUserUnlocked(final UserState uss) {
453 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700454 // Only keep marching forward if user is actually unlocked
455 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700456 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600457 // Bail if we ended up with a stale user
458 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
459
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700460 // Do not proceed if unexpected state
461 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
462 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600463 }
464 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700465 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
466 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700467
468 // Get unaware persistent apps running and start any unaware providers
469 // in already-running apps that are partially aware
470 if (userId == UserHandle.USER_SYSTEM) {
471 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
472 }
473 mInjector.installEncryptionUnawareProviders(userId);
474
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700475 // Dispatch unlocked to external apps
476 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
477 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
478 unlockedIntent.addFlags(
479 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
480 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
481 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000482 Binder.getCallingUid(), Binder.getCallingPid(), userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700483
484 if (getUserInfo(userId).isManagedProfile()) {
485 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
486 if (parent != null) {
487 final Intent profileUnlockedIntent = new Intent(
488 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
489 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
490 profileUnlockedIntent.addFlags(
491 Intent.FLAG_RECEIVER_REGISTERED_ONLY
492 | Intent.FLAG_RECEIVER_FOREGROUND);
493 mInjector.broadcastIntent(profileUnlockedIntent,
494 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000495 null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
496 Binder.getCallingPid(), parent.id);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700497 }
498 }
499
500 // Send PRE_BOOT broadcasts if user fingerprint changed; we
501 // purposefully block sending BOOT_COMPLETED until after all
502 // PRE_BOOT receivers are finished to avoid ANR'ing apps
503 final UserInfo info = getUserInfo(userId);
504 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
505 // Suppress double notifications for managed profiles that
506 // were unlocked automatically as part of their parent user
507 // being unlocked.
508 final boolean quiet;
509 if (info.isManagedProfile()) {
510 quiet = !uss.tokenProvided
511 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
512 } else {
513 quiet = false;
514 }
515 mInjector.sendPreBootBroadcast(userId, quiet,
516 () -> finishUserUnlockedCompleted(uss));
517 } else {
518 finishUserUnlockedCompleted(uss);
519 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600520 }
521
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600522 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600523 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700524 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600525 // Bail if we ended up with a stale user
526 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700527 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700528 UserInfo userInfo = getUserInfo(userId);
529 if (userInfo == null) {
530 return;
531 }
532 // Only keep marching forward if user is actually unlocked
533 if (!StorageManager.isUserKeyUnlocked(userId)) return;
534
535 // Remember that we logged in
536 mInjector.getUserManager().onUserLoggedIn(userId);
537
538 if (!userInfo.isInitialized()) {
539 if (userId != UserHandle.USER_SYSTEM) {
540 Slog.d(TAG, "Initializing user #" + userId);
541 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
542 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
543 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
544 mInjector.broadcastIntent(intent, null,
545 new IIntentReceiver.Stub() {
546 @Override
547 public void performReceive(Intent intent, int resultCode,
548 String data, Bundle extras, boolean ordered,
549 boolean sticky, int sendingUser) {
550 // Note: performReceive is called with mService lock held
551 mInjector.getUserManager().makeInitialized(userInfo.id);
552 }
553 }, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000554 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
555 Binder.getCallingPid(), userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700556 }
557 }
558
Christopher Tate88dc93f2018-07-27 16:48:37 -0700559 // Spin up app widgets prior to boot-complete, so they can be ready promptly
560 mInjector.startUserWidgets(userId);
561
Christopher Tate74e5b7d2019-06-07 17:55:43 -0700562 Slog.i(TAG, "Posting BOOT_COMPLETED user #" + userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700563 // Do not report secondary users, runtime restarts or first boot/upgrade
564 if (userId == UserHandle.USER_SYSTEM
565 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
566 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
567 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
568 uptimeSeconds);
569 }
570 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
571 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
572 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
Ng Zhi An150a6ba2018-08-13 09:08:11 -0700573 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
574 | Intent.FLAG_RECEIVER_OFFLOAD);
Christopher Tate74e5b7d2019-06-07 17:55:43 -0700575 // Widget broadcasts are outbound via FgThread, so to guarantee sequencing
576 // we also send the boot_completed broadcast from that thread.
577 final int callingUid = Binder.getCallingUid();
578 final int callingPid = Binder.getCallingPid();
579 FgThread.getHandler().post(() -> {
580 mInjector.broadcastIntent(bootIntent, null,
581 new IIntentReceiver.Stub() {
582 @Override
583 public void performReceive(Intent intent, int resultCode, String data,
584 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
585 throws RemoteException {
586 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u"
587 + userId);
588 mBootCompleted = true;
589 }
590 }, 0, null, null,
591 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
592 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
593 callingUid, callingPid, userId);
594 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700595 }
596
Andrew Scull85a63bc2016-10-24 13:47:47 +0100597 int restartUser(final int userId, final boolean foreground) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100598 return stopUser(userId, /* force */ true, null, new KeyEvictedCallback() {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100599 @Override
Pavel Grafov67d44262019-05-03 15:58:54 +0100600 public void keyEvicted(@UserIdInt int userId) {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100601 // Post to the same handler that this callback is called from to ensure the user
602 // cleanup is complete before restarting.
Pavel Grafov67d44262019-05-03 15:58:54 +0100603 mHandler.post(() -> UserController.this.startUser(userId, foreground));
Andrew Scull85a63bc2016-10-24 13:47:47 +0100604 }
Andrew Scull85a63bc2016-10-24 13:47:47 +0100605 });
606 }
607
Pavel Grafov67d44262019-05-03 15:58:54 +0100608 int stopUser(final int userId, final boolean force, final IStopUserCallback stopUserCallback,
609 KeyEvictedCallback keyEvictedCallback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700610 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700611 != PackageManager.PERMISSION_GRANTED) {
612 String msg = "Permission Denial: switchUser() from pid="
613 + Binder.getCallingPid()
614 + ", uid=" + Binder.getCallingUid()
615 + " requires " + INTERACT_ACROSS_USERS_FULL;
616 Slog.w(TAG, msg);
617 throw new SecurityException(msg);
618 }
619 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
620 throw new IllegalArgumentException("Can't stop system user " + userId);
621 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700622 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700623 synchronized (mLock) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100624 return stopUsersLU(userId, force, stopUserCallback, keyEvictedCallback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700625 }
626 }
627
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700628 /**
629 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700630 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700631 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700632 @GuardedBy("mLock")
Pavel Grafov67d44262019-05-03 15:58:54 +0100633 private int stopUsersLU(final int userId, boolean force,
634 final IStopUserCallback stopUserCallback, KeyEvictedCallback keyEvictedCallback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700635 if (userId == UserHandle.USER_SYSTEM) {
636 return USER_OP_ERROR_IS_SYSTEM;
637 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700638 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700639 return USER_OP_IS_CURRENT;
640 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700641 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700642 // If one of related users is system or current, no related users should be stopped
643 for (int i = 0; i < usersToStop.length; i++) {
644 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700645 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700646 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
647 + relatedUserId);
648 // We still need to stop the requested user if it's a force stop.
649 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800650 Slog.i(TAG,
651 "Force stop user " + userId + ". Related users will not be stopped");
Pavel Grafov67d44262019-05-03 15:58:54 +0100652 stopSingleUserLU(userId, stopUserCallback, keyEvictedCallback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800653 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700654 }
655 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
656 }
657 }
658 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
659 for (int userIdToStop : usersToStop) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100660 stopSingleUserLU(userIdToStop,
661 userIdToStop == userId ? stopUserCallback : null,
662 userIdToStop == userId ? keyEvictedCallback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700663 }
664 return USER_OP_SUCCESS;
665 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666
Andreas Gampee7739b32018-07-20 12:55:36 -0700667 @GuardedBy("mLock")
Pavel Grafov67d44262019-05-03 15:58:54 +0100668 private void stopSingleUserLU(final int userId, final IStopUserCallback stopUserCallback,
669 KeyEvictedCallback keyEvictedCallback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700670 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700671 final UserState uss = mStartedUsers.get(userId);
672 if (uss == null) {
673 // User is not started, nothing to do... but we do need to
674 // callback if requested.
Pavel Grafov67d44262019-05-03 15:58:54 +0100675 if (stopUserCallback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700676 mHandler.post(() -> {
677 try {
Pavel Grafov67d44262019-05-03 15:58:54 +0100678 stopUserCallback.userStopped(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700679 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700680 }
681 });
682 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700683 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700684 }
685
Pavel Grafov67d44262019-05-03 15:58:54 +0100686 if (stopUserCallback != null) {
687 uss.mStopCallbacks.add(stopUserCallback);
688 }
689 if (keyEvictedCallback != null) {
690 uss.mKeyEvictedCallbacks.add(keyEvictedCallback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700691 }
692
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700693 if (uss.state != UserState.STATE_STOPPING
694 && uss.state != UserState.STATE_SHUTDOWN) {
695 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700696 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700697 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700698
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700699 // Post to handler to obtain amLock
700 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700701 // We are going to broadcast ACTION_USER_STOPPING and then
702 // once that is done send a final ACTION_SHUTDOWN and then
703 // stop the user.
704 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
705 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
706 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
707 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700708 // This is the result receiver for the initial stopping broadcast.
709 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
710 @Override
711 public void performReceive(Intent intent, int resultCode, String data,
712 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700713 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700714 }
715 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700716
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700717 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700718 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700719 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700720 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700721 null, stoppingReceiver, 0, null, null,
722 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000723 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
724 Binder.getCallingPid(), UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700725 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700727 }
728
Amith Yamasani98c05562016-03-30 13:15:26 -0700729 void finishUserStopping(final int userId, final UserState uss) {
730 // On to the next.
731 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
732 // This is the result receiver for the final shutdown broadcast.
733 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
734 @Override
735 public void performReceive(Intent intent, int resultCode, String data,
736 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
737 mHandler.post(new Runnable() {
738 @Override
739 public void run() {
740 finishUserStopped(uss);
741 }
742 });
743 }
744 };
745
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700746 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700747 if (uss.state != UserState.STATE_STOPPING) {
748 // Whoops, we are being started back up. Abort, abort!
749 return;
750 }
751 uss.setState(UserState.STATE_SHUTDOWN);
752 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700753 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700754
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700755 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700756 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
757 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700758 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700759
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700760 mInjector.broadcastIntent(shutdownIntent,
761 null, shutdownReceiver, 0, null, null, null,
762 AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000763 null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
764 Binder.getCallingPid(), userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700765 }
766
767 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700768 final int userId = uss.mHandle.getIdentifier();
Pavel Grafov634c34e2018-04-10 19:19:01 +0100769 final boolean stopped;
Keun young Parkdf54b662019-03-13 14:06:42 -0700770 boolean lockUser = true;
Pavel Grafov67d44262019-05-03 15:58:54 +0100771 final ArrayList<IStopUserCallback> stopCallbacks;
772 final ArrayList<KeyEvictedCallback> keyEvictedCallbacks;
Keun young Parkdf54b662019-03-13 14:06:42 -0700773 int userIdToLock = userId;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700774 synchronized (mLock) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100775 stopCallbacks = new ArrayList<>(uss.mStopCallbacks);
776 keyEvictedCallbacks = new ArrayList<>(uss.mKeyEvictedCallbacks);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100777 if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700778 stopped = false;
779 } else {
780 stopped = true;
781 // User can no longer run.
782 mStartedUsers.remove(userId);
783 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700784 updateStartedUserArrayLU();
Keun young Parkdf54b662019-03-13 14:06:42 -0700785 userIdToLock = updateUserToLockLU(userId);
786 if (userIdToLock == UserHandle.USER_NULL) {
787 lockUser = false;
788 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700789 }
790 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100791 if (stopped) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700792 mInjector.getUserManagerInternal().removeUserState(userId);
793 mInjector.activityManagerOnUserStopped(userId);
794 // Clean up all state and processes associated with the user.
795 // Kill all the processes for the user.
796 forceStopUser(userId, "finish user");
797 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700798
Pavel Grafov67d44262019-05-03 15:58:54 +0100799 for (final IStopUserCallback callback : stopCallbacks) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700800 try {
Pavel Grafov67d44262019-05-03 15:58:54 +0100801 if (stopped) callback.userStopped(userId);
802 else callback.userStopAborted(userId);
803 } catch (RemoteException ignored) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700804 }
805 }
806
807 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700808 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700809 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100810 // Remove the user if it is ephemeral.
811 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000812 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100813 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100814
Keun young Parkdf54b662019-03-13 14:06:42 -0700815 if (!lockUser) {
816 return;
817 }
818 final int userIdToLockF = userIdToLock;
Pavel Grafov634c34e2018-04-10 19:19:01 +0100819 // Evict the user's credential encryption key. Performed on FgThread to make it
820 // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
821 // to prevent data corruption.
822 FgThread.getHandler().post(() -> {
823 synchronized (mLock) {
Keun young Parkdf54b662019-03-13 14:06:42 -0700824 if (mStartedUsers.get(userIdToLockF) != null) {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100825 Slog.w(TAG, "User was restarted, skipping key eviction");
826 return;
827 }
828 }
829 try {
Keun young Parkdf54b662019-03-13 14:06:42 -0700830 mInjector.getStorageManager().lockUserKey(userIdToLockF);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100831 } catch (RemoteException re) {
832 throw re.rethrowAsRuntimeException();
833 }
Pavel Grafov67d44262019-05-03 15:58:54 +0100834 if (userIdToLockF == userId) {
835 for (final KeyEvictedCallback callback : keyEvictedCallbacks) {
836 callback.keyEvicted(userId);
837 }
838 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100839 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700840 }
841 }
842
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700843 /**
Keun young Parkdf54b662019-03-13 14:06:42 -0700844 * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked.
845 * Total number of unlocked user storage is limited by mMaxRunningUsers.
846 * If there are more unlocked users, evict and lock the least recently stopped user and
847 * lock that user's data. Regardless of the mode, ephemeral user is always locked
848 * immediately.
849 *
850 * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked.
851 */
852 @GuardedBy("mLock")
853 private int updateUserToLockLU(int userId) {
854 int userIdToLock = userId;
855 if (mDelayUserDataLocking && !getUserInfo(userId).isEphemeral()
856 && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) {
857 mLastActiveUsers.remove((Integer) userId); // arg should be object, not index
858 mLastActiveUsers.add(0, userId);
859 int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsers.size();
860 if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user
861 userIdToLock = mLastActiveUsers.get(mLastActiveUsers.size() - 1);
862 mLastActiveUsers.remove(mLastActiveUsers.size() - 1);
863 Slog.i(TAG, "finishUserStopped, stopping user:" + userId
864 + " lock user:" + userIdToLock);
865 } else {
866 Slog.i(TAG, "finishUserStopped, user:" + userId
867 + ",skip locking");
868 // do not lock
869 userIdToLock = UserHandle.USER_NULL;
870
871 }
872 }
873 return userIdToLock;
874 }
875
876 /**
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700877 * Determines the list of users that should be stopped together with the specified
878 * {@code userId}. The returned list includes {@code userId}.
879 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700880 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700881 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700882 int startedUsersSize = mStartedUsers.size();
883 IntArray userIds = new IntArray();
884 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700885 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
886 for (int i = 0; i < startedUsersSize; i++) {
887 UserState uss = mStartedUsers.valueAt(i);
888 int startedUserId = uss.mHandle.getIdentifier();
889 // Skip unrelated users (profileGroupId mismatch)
890 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700891 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700892 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
893 && (userGroupId == startedUserGroupId);
894 // userId has already been added
895 boolean sameUserId = startedUserId == userId;
896 if (!sameGroup || sameUserId) {
897 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700898 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700899 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700900 }
901 return userIds.toArray();
902 }
903
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700904 private void forceStopUser(int userId, String reason) {
905 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700906 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
907 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
908 | Intent.FLAG_RECEIVER_FOREGROUND);
909 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700910 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700911 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +0000912 null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
913 Binder.getCallingPid(), UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700914 }
915
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700916 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100917 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700918 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000919 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
920 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000921 synchronized(mLock) {
922 UserState oldUss = mStartedUsers.get(oldUserId);
923 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
924 || oldUss.state == UserState.STATE_STOPPING
925 || oldUss.state == UserState.STATE_SHUTDOWN) {
926 return;
927 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700928 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000929
930 UserInfo userInfo = getUserInfo(oldUserId);
931 if (userInfo.isEphemeral()) {
932 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
933 }
934 if (userInfo.isGuest() || userInfo.isEphemeral()) {
935 // This is a user to be stopped.
936 synchronized (mLock) {
Pavel Grafov67d44262019-05-03 15:58:54 +0100937 stopUsersLU(oldUserId, true, null, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700938 }
939 }
940 }
941
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700942 void scheduleStartProfiles() {
Pavel Grafov10c16742018-09-20 15:03:47 +0100943 // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
944 // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
945 // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
946 // after the parent had chance to unlock fully.
947 FgThread.getHandler().post(() -> {
948 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
949 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
950 DateUtils.SECOND_IN_MILLIS);
951 }
952 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700953 }
954
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700955 void startProfiles() {
956 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700957 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700958 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700959 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700960 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
961 for (UserInfo user : profiles) {
962 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700963 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700964 profilesToStart.add(user);
965 }
966 }
967 final int profilesToStartSize = profilesToStart.size();
968 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700969 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700970 startUser(profilesToStart.get(i).id, /* foreground= */ false);
971 }
972 if (i < profilesToStartSize) {
973 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
974 }
975 }
976
Tony Mak64fd8c02017-12-01 19:11:59 +0000977 boolean startUser(final int userId, final boolean foreground) {
978 return startUser(userId, foreground, null);
979 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700980
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700981 /**
982 * Start user, if its not already running.
983 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
984 * When starting the user, multiple intents will be broadcast in the following order:</p>
985 * <ul>
986 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
987 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
988 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
989 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
990 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
991 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
992 * Sent only if {@code foreground} parameter is true
993 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
994 * of the new fg user
995 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
996 * the new user
997 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
998 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
999 * new user. Sent only when the user is booting after a system update.
1000 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
1001 * new user. Sent only the first time a user is starting.
1002 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
1003 * user. Indicates that the user has finished booting.
1004 * </ul>
1005 *
1006 * @param userId ID of the user to start
1007 * @param foreground true if user should be brought to the foreground
Bookatz03bfe6f2019-03-01 15:46:04 -08001008 * @param unlockListener Listener to be informed when the user has started and unlocked.
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001009 * @return true if the user has been successfully started
1010 */
Tony Mak64fd8c02017-12-01 19:11:59 +00001011 boolean startUser(
1012 final int userId,
1013 final boolean foreground,
1014 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001015 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001016 != PackageManager.PERMISSION_GRANTED) {
1017 String msg = "Permission Denial: switchUser() from pid="
1018 + Binder.getCallingPid()
1019 + ", uid=" + Binder.getCallingUid()
1020 + " requires " + INTERACT_ACROSS_USERS_FULL;
1021 Slog.w(TAG, msg);
1022 throw new SecurityException(msg);
1023 }
1024
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001025 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001026
Michal Karpinskic99d7182019-02-17 13:15:23 +00001027 final int callingUid = Binder.getCallingUid();
1028 final int callingPid = Binder.getCallingPid();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001029 final long ident = Binder.clearCallingIdentity();
1030 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001031 final int oldUserId = getCurrentUserId();
1032 if (oldUserId == userId) {
Bookatz03bfe6f2019-03-01 15:46:04 -08001033 final UserState state = getStartedUserState(userId);
Keun young Park0cb5ae72019-03-27 14:01:24 -07001034 if (state == null) {
1035 Slog.wtf(TAG, "Current user has no UserState");
1036 // continue starting.
1037 } else {
1038 if (userId == UserHandle.USER_SYSTEM && state.state == STATE_BOOTING) {
1039 // system user start explicitly requested. should continue starting as it
1040 // is not in running state.
1041 } else {
1042 if (state.state == STATE_RUNNING_UNLOCKED) {
1043 // We'll skip all later code, so we must tell listener it's already
1044 // unlocked.
Bookatzcecf1162019-04-10 12:52:34 -07001045 notifyFinished(userId, unlockListener);
Keun young Park0cb5ae72019-03-27 14:01:24 -07001046 }
1047 return true;
Bookatz03bfe6f2019-03-01 15:46:04 -08001048 }
1049 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001050 }
1051
1052 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +01001053 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001054 }
1055
1056 final UserInfo userInfo = getUserInfo(userId);
1057 if (userInfo == null) {
1058 Slog.w(TAG, "No user info for user #" + userId);
1059 return false;
1060 }
1061 if (foreground && userInfo.isManagedProfile()) {
1062 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
1063 return false;
1064 }
1065
1066 if (foreground && mUserSwitchUiEnabled) {
1067 mInjector.getWindowManager().startFreezingScreen(
1068 R.anim.screen_user_exit, R.anim.screen_user_enter);
1069 }
1070
1071 boolean needStart = false;
1072 boolean updateUmState = false;
1073 UserState uss;
1074
1075 // If the user we are switching to is not currently started, then
1076 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001077 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001078 uss = mStartedUsers.get(userId);
1079 if (uss == null) {
1080 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07001081 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001082 mStartedUsers.put(userId, uss);
1083 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001084 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001085 updateUmState = true;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001086 } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
1087 Slog.i(TAG, "User #" + userId
1088 + " is shutting down - will start after full stop");
1089 mHandler.post(() -> startUser(userId, foreground, unlockListener));
1090 return true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001091 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001092 final Integer userIdInt = userId;
1093 mUserLru.remove(userIdInt);
1094 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +00001095 }
1096 if (unlockListener != null) {
1097 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001098 }
1099 if (updateUmState) {
1100 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1101 }
1102 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -08001103 // Make sure the old user is no longer considering the display to be on.
1104 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001105 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001106 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001107 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001108 }
1109 mInjector.updateUserConfiguration();
1110 updateCurrentProfileIds();
1111 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -08001112 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001113 // Once the internal notion of the active user has switched, we lock the device
1114 // with the option to show the user switcher on the keyguard.
1115 if (mUserSwitchUiEnabled) {
1116 mInjector.getWindowManager().setSwitchingUser(true);
1117 mInjector.getWindowManager().lockNow(null);
1118 }
1119 } else {
1120 final Integer currentUserIdInt = mCurrentUserId;
1121 updateCurrentProfileIds();
1122 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
1123 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001124 mUserLru.remove(currentUserIdInt);
1125 mUserLru.add(currentUserIdInt);
1126 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001127 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001128
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001129 // Make sure user is in the started state. If it is currently
1130 // stopping, we need to knock that off.
1131 if (uss.state == UserState.STATE_STOPPING) {
1132 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
1133 // so we can just fairly silently bring the user back from
1134 // the almost-dead.
1135 uss.setState(uss.lastState);
1136 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1137 synchronized (mLock) {
1138 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001139 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001140 needStart = true;
1141 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1142 // This means ACTION_SHUTDOWN has been sent, so we will
1143 // need to treat this as a new boot of the user.
1144 uss.setState(UserState.STATE_BOOTING);
1145 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1146 synchronized (mLock) {
1147 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001148 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001149 needStart = true;
1150 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001151
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001152 if (uss.state == UserState.STATE_BOOTING) {
1153 // Give user manager a chance to propagate user restrictions
1154 // to other services and prepare app storage
1155 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001156
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001157 // Booting up a new user, need to tell system services about it.
1158 // Note that this is on the same handler as scheduling of broadcasts,
1159 // which is important because it needs to go first.
1160 mHandler.sendMessage(
1161 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1162 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001163
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001164 if (foreground) {
1165 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1166 oldUserId));
1167 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1168 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1169 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1170 oldUserId, userId, uss));
1171 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1172 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1173 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001174
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001175 if (needStart) {
1176 // Send USER_STARTED broadcast
1177 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1178 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1179 | Intent.FLAG_RECEIVER_FOREGROUND);
1180 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1181 mInjector.broadcastIntent(intent,
1182 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001183 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001184 }
1185
1186 if (foreground) {
1187 moveUserToForeground(uss, oldUserId, userId);
1188 } else {
1189 finishUserBoot(uss);
1190 }
1191
1192 if (needStart) {
1193 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1196 mInjector.broadcastIntent(intent,
1197 null, new IIntentReceiver.Stub() {
1198 @Override
1199 public void performReceive(Intent intent, int resultCode,
1200 String data, Bundle extras, boolean ordered,
1201 boolean sticky,
1202 int sendingUser) throws RemoteException {
1203 }
1204 }, 0, null, null,
1205 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001206 null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1207 UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001208 }
1209 } finally {
1210 Binder.restoreCallingIdentity(ident);
1211 }
1212
1213 return true;
1214 }
1215
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001216 private boolean isCallingOnHandlerThread() {
1217 return Looper.myLooper() == mHandler.getLooper();
1218 }
1219
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001220 /**
1221 * Start user, if its not already running, and bring it to foreground.
1222 */
Evan Rosky18396452016-07-27 15:19:37 -07001223 void startUserInForeground(final int targetUserId) {
1224 boolean success = startUser(targetUserId, /* foreground */ true);
1225 if (!success) {
1226 mInjector.getWindowManager().setSwitchingUser(false);
1227 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001228 }
1229
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001230 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001231 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001232 != PackageManager.PERMISSION_GRANTED) {
1233 String msg = "Permission Denial: unlockUser() from pid="
1234 + Binder.getCallingPid()
1235 + ", uid=" + Binder.getCallingUid()
1236 + " requires " + INTERACT_ACROSS_USERS_FULL;
1237 Slog.w(TAG, msg);
1238 throw new SecurityException(msg);
1239 }
1240
Jeff Sharkey8924e872015-11-30 12:52:10 -07001241 final long binderToken = Binder.clearCallingIdentity();
1242 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001243 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001244 } finally {
1245 Binder.restoreCallingIdentity(binderToken);
1246 }
1247 }
1248
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001249 /**
1250 * Attempt to unlock user without a credential token. This typically
1251 * succeeds when the device doesn't have credential-encrypted storage, or
shafik172e1fb2018-12-05 14:52:38 +00001252 * when the credential-encrypted storage isn't tied to a user-provided
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001253 * PIN or pattern.
1254 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001255 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001256 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001257 return unlockUserCleared(userId, null, null, null);
1258 }
1259
1260 private static void notifyFinished(int userId, IProgressListener listener) {
1261 if (listener == null) return;
1262 try {
1263 listener.onFinished(userId, null);
1264 } catch (RemoteException ignored) {
1265 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001266 }
1267
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001268 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001269 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001270 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001271 if (!StorageManager.isUserKeyUnlocked(userId)) {
1272 final UserInfo userInfo = getUserInfo(userId);
Keun young Parkdf54b662019-03-13 14:06:42 -07001273 final IStorageManager storageManager = mInjector.getStorageManager();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001274 try {
1275 // We always want to unlock user storage, even user is not started yet
1276 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1277 } catch (RemoteException | RuntimeException e) {
1278 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001279 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001280 }
1281 synchronized (mLock) {
1282 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001283 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001284 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001285 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001286 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001287 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001288 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001289 // Bail if user isn't actually running
1290 if (uss == null) {
1291 notifyFinished(userId, listener);
1292 return false;
1293 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001294
Rubin Xu98571a02019-02-28 16:26:06 +00001295 if (!finishUserUnlocking(uss)) {
1296 notifyFinished(userId, listener);
1297 return false;
1298 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001299
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001300 // We just unlocked a user, so let's now attempt to unlock any
1301 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001302
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001303 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1304 int[] userIds;
1305 synchronized (mLock) {
1306 userIds = new int[mStartedUsers.size()];
1307 for (int i = 0; i < userIds.length; i++) {
1308 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001309 }
1310 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001311 for (int testUserId : userIds) {
1312 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1313 if (parent != null && parent.id == userId && testUserId != userId) {
1314 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1315 + "): attempting unlock because parent was just unlocked");
1316 maybeUnlockUser(testUserId);
1317 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001318 }
1319
Jeff Sharkeyba512352015-11-12 20:17:45 -08001320 return true;
1321 }
1322
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001323 boolean switchUser(final int targetUserId) {
1324 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001325 int currentUserId = getCurrentUserId();
1326 UserInfo targetUserInfo = getUserInfo(targetUserId);
1327 if (targetUserId == currentUserId) {
1328 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1329 return true;
1330 }
1331 if (targetUserInfo == null) {
1332 Slog.w(TAG, "No user info for user #" + targetUserId);
1333 return false;
1334 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001335 if (!targetUserInfo.supportsSwitchTo()) {
1336 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1337 return false;
1338 }
1339 if (targetUserInfo.isManagedProfile()) {
1340 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1341 return false;
1342 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001343 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001344 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001345 }
1346 if (mUserSwitchUiEnabled) {
1347 UserInfo currentUserInfo = getUserInfo(currentUserId);
1348 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1349 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1350 mUiHandler.sendMessage(mHandler.obtainMessage(
1351 START_USER_SWITCH_UI_MSG, userNames));
1352 } else {
1353 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1354 mHandler.sendMessage(mHandler.obtainMessage(
1355 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1356 }
1357 return true;
1358 }
1359
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001360 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001361 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001362 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1363 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001364 }
1365
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001366 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001367 final int observerCount = mUserSwitchObservers.beginBroadcast();
1368 for (int i = 0; i < observerCount; i++) {
1369 try {
1370 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1371 } catch (RemoteException e) {
1372 // Ignore
1373 }
1374 }
1375 mUserSwitchObservers.finishBroadcast();
1376 }
1377
1378 /** Called on handler thread */
1379 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001380 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001381 final int observerCount = mUserSwitchObservers.beginBroadcast();
1382 for (int i = 0; i < observerCount; i++) {
1383 try {
1384 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1385 } catch (RemoteException e) {
1386 }
1387 }
1388 mUserSwitchObservers.finishBroadcast();
1389 }
1390
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001391 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001392 final int observerCount = mUserSwitchObservers.beginBroadcast();
1393 for (int i = 0; i < observerCount; i++) {
1394 try {
1395 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1396 } catch (RemoteException e) {
1397 // Ignore
1398 }
1399 }
1400 mUserSwitchObservers.finishBroadcast();
1401 }
1402
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001403 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1404 // Never stop system user
1405 if (oldUserId == UserHandle.USER_SYSTEM) {
1406 return;
1407 }
Keun young Parkdf54b662019-03-13 14:06:42 -07001408 // If running in background is disabled or mDelayUserDataLocking mode, stop the user.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001409 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
Keun young Parkdf54b662019-03-13 14:06:42 -07001410 oldUserId) || mDelayUserDataLocking;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001411 if (!disallowRunInBg) {
1412 return;
1413 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001414 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001415 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1416 + " and related users");
Pavel Grafov67d44262019-05-03 15:58:54 +01001417 stopUsersLU(oldUserId, false, null, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001418 }
1419 }
1420
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001421 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001422 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001423 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1424 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1425 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001426 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001427 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1428 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1429 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1430 }
1431 }
1432
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001433 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001434 synchronized (mLock) {
1435 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1436 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1437 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1438 mTimeoutUserSwitchCallbacks = null;
1439 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001440 }
1441 }
1442
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001443 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1444 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001445 final int observerCount = mUserSwitchObservers.beginBroadcast();
1446 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001447 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001448 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001449 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001450 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001451 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001452 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001453 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001454 for (int i = 0; i < observerCount; i++) {
1455 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001456 // Prepend with unique prefix to guarantee that keys are unique
1457 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001458 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001459 curWaitingUserSwitchCallbacks.add(name);
1460 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001461 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1462 @Override
1463 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001464 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001465 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001466 if (delay > USER_SWITCH_TIMEOUT_MS) {
1467 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001468 + " sent result after " + delay + " ms");
1469 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001470 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001471 // Continue switching if all callbacks have been notified and
1472 // user switching session is still valid
1473 if (waitingCallbacksCount.decrementAndGet() == 0
1474 && (curWaitingUserSwitchCallbacks
1475 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001476 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001477 }
1478 }
1479 }
1480 };
1481 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001482 } catch (RemoteException e) {
1483 }
1484 }
1485 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001486 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001487 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001488 }
1489 }
1490 mUserSwitchObservers.finishBroadcast();
1491 }
1492
Andreas Gampee7739b32018-07-20 12:55:36 -07001493 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001494 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001495 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001496 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001497 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001498 oldUserId, newUserId, uss));
1499 }
1500
1501 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001502 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001503 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001504 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001505 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001506 uss.switching = false;
1507 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1508 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1509 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001510 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001511 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001512 }
1513
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001514 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1515 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001516 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001517 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001518 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001519 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001520 }
1521 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001522 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001523 }
1524
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001525 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Michal Karpinskic99d7182019-02-17 13:15:23 +00001526 final int callingUid = Binder.getCallingUid();
1527 final int callingPid = Binder.getCallingPid();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001528 long ident = Binder.clearCallingIdentity();
1529 try {
1530 Intent intent;
1531 if (oldUserId >= 0) {
1532 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001533 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001534 int count = profiles.size();
1535 for (int i = 0; i < count; i++) {
1536 int profileUserId = profiles.get(i).id;
1537 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1538 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1539 | Intent.FLAG_RECEIVER_FOREGROUND);
1540 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001541 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001542 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001543 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1544 profileUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001545 }
1546 }
1547 if (newUserId >= 0) {
1548 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001549 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001550 int count = profiles.size();
1551 for (int i = 0; i < count; i++) {
1552 int profileUserId = profiles.get(i).id;
1553 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1554 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1555 | Intent.FLAG_RECEIVER_FOREGROUND);
1556 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001557 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001558 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Michal Karpinskic99d7182019-02-17 13:15:23 +00001559 null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
1560 profileUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001561 }
1562 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1563 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1564 | Intent.FLAG_RECEIVER_FOREGROUND);
1565 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001566 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001567 null, null, 0, null, null,
1568 new String[] {android.Manifest.permission.MANAGE_USERS},
Michal Karpinskic99d7182019-02-17 13:15:23 +00001569 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid,
1570 callingPid, UserHandle.USER_ALL);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001571 }
1572 } finally {
1573 Binder.restoreCallingIdentity(ident);
1574 }
1575 }
1576
1577
1578 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1579 int allowMode, String name, String callerPackage) {
1580 final int callingUserId = UserHandle.getUserId(callingUid);
1581 if (callingUserId == userId) {
1582 return userId;
1583 }
1584
1585 // Note that we may be accessing mCurrentUserId outside of a lock...
1586 // shouldn't be a big deal, if this is being called outside
1587 // of a locked context there is intrinsically a race with
1588 // the value the caller will receive and someone else changing it.
1589 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1590 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001591 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001592
1593 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1594 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001595 if (mInjector.isCallerRecents(callingUid)
1596 && callingUserId == getCurrentUserId()
1597 && isSameProfileGroup(callingUserId, targetUserId)) {
1598 // If the caller is Recents and it is running in the current user, we then allow it
1599 // to access its profiles.
1600 allow = true;
1601 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001602 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1603 // If the caller has this permission, they always pass go. And collect $200.
1604 allow = true;
1605 } else if (allowMode == ALLOW_FULL_ONLY) {
1606 // We require full access, sucks to be you.
1607 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001608 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001609 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1610 // If the caller does not have either permission, they are always doomed.
1611 allow = false;
1612 } else if (allowMode == ALLOW_NON_FULL) {
1613 // We are blanket allowing non-full access, you lucky caller!
1614 allow = true;
1615 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1616 // We may or may not allow this depending on whether the two users are
1617 // in the same profile.
1618 allow = isSameProfileGroup(callingUserId, targetUserId);
1619 } else {
1620 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1621 }
1622 if (!allow) {
1623 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1624 // In this case, they would like to just execute as their
1625 // owner user instead of failing.
1626 targetUserId = callingUserId;
1627 } else {
1628 StringBuilder builder = new StringBuilder(128);
1629 builder.append("Permission Denial: ");
1630 builder.append(name);
1631 if (callerPackage != null) {
1632 builder.append(" from ");
1633 builder.append(callerPackage);
1634 }
1635 builder.append(" asks to run as user ");
1636 builder.append(userId);
Dianne Hackborn4760f082019-03-12 11:37:19 -07001637 builder.append(" but is calling from uid ");
1638 UserHandle.formatUid(builder, callingUid);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001639 builder.append("; this requires ");
1640 builder.append(INTERACT_ACROSS_USERS_FULL);
1641 if (allowMode != ALLOW_FULL_ONLY) {
1642 builder.append(" or ");
1643 builder.append(INTERACT_ACROSS_USERS);
1644 }
1645 String msg = builder.toString();
1646 Slog.w(TAG, msg);
1647 throw new SecurityException(msg);
1648 }
1649 }
1650 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001651 if (!allowAll) {
1652 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001653 }
1654 // Check shell permission
1655 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1656 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1657 throw new SecurityException("Shell does not have permission to access user "
1658 + targetUserId + "\n " + Debug.getCallers(3));
1659 }
1660 }
1661 return targetUserId;
1662 }
1663
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001664 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001665 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001666 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001667 }
1668
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001669 void ensureNotSpecialUser(int userId) {
1670 if (userId >= 0) {
1671 return;
1672 }
1673 throw new IllegalArgumentException("Call does not support special user #" + userId);
1674 }
1675
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001676 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1677 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001678 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001679 != PackageManager.PERMISSION_GRANTED) {
1680 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1681 + Binder.getCallingPid()
1682 + ", uid=" + Binder.getCallingUid()
1683 + " requires " + INTERACT_ACROSS_USERS_FULL;
1684 Slog.w(TAG, msg);
1685 throw new SecurityException(msg);
1686 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001687 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001688 }
1689
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001690 void sendForegroundProfileChanged(int userId) {
1691 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1692 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1693 }
1694
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001695 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1696 mUserSwitchObservers.unregister(observer);
1697 }
1698
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001699 UserState getStartedUserState(int userId) {
1700 synchronized (mLock) {
1701 return mStartedUsers.get(userId);
1702 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001703 }
1704
1705 boolean hasStartedUserState(int userId) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07001706 synchronized (mLock) {
1707 return mStartedUsers.get(userId) != null;
1708 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001709 }
1710
Andreas Gampee7739b32018-07-20 12:55:36 -07001711 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001712 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001713 int num = 0;
1714 for (int i = 0; i < mStartedUsers.size(); i++) {
1715 UserState uss = mStartedUsers.valueAt(i);
1716 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001717 if (uss.state != UserState.STATE_STOPPING
1718 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001719 num++;
1720 }
1721 }
1722 mStartedUserArray = new int[num];
1723 num = 0;
1724 for (int i = 0; i < mStartedUsers.size(); i++) {
1725 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001726 if (uss.state != UserState.STATE_STOPPING
1727 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001728 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001729 }
1730 }
1731 }
1732
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001733 void sendBootCompleted(IIntentReceiver resultTo) {
1734 // Get a copy of mStartedUsers to use outside of lock
1735 SparseArray<UserState> startedUsers;
1736 synchronized (mLock) {
1737 startedUsers = mStartedUsers.clone();
1738 }
1739 for (int i = 0; i < startedUsers.size(); i++) {
1740 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001741 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001742 }
1743 }
1744
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001745 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001746 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001747 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001748 }
1749
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001750 /**
1751 * Refreshes the list of users related to the current user when either a
1752 * user switch happens or when a new related user is started in the
1753 * background.
1754 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001755 private void updateCurrentProfileIds() {
1756 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001757 false /* enabledOnly */);
1758 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1759 for (int i = 0; i < currentProfileIds.length; i++) {
1760 currentProfileIds[i] = profiles.get(i).id;
1761 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001762 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1763 synchronized (mLock) {
1764 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001765
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001766 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001767 for (int i = 0; i < users.size(); i++) {
1768 UserInfo user = users.get(i);
1769 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001770 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001771 }
1772 }
1773 }
1774 }
1775
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001776 int[] getStartedUserArray() {
1777 synchronized (mLock) {
1778 return mStartedUserArray;
1779 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001780 }
1781
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001782 boolean isUserRunning(int userId, int flags) {
1783 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001784 if (state == null) {
1785 return false;
1786 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001787 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001788 return true;
1789 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001790 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001791 switch (state.state) {
1792 case UserState.STATE_BOOTING:
1793 case UserState.STATE_RUNNING_LOCKED:
1794 return true;
1795 default:
1796 return false;
1797 }
1798 }
1799 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1800 switch (state.state) {
1801 case UserState.STATE_RUNNING_UNLOCKING:
1802 case UserState.STATE_RUNNING_UNLOCKED:
1803 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001804 // In the stopping/shutdown state return unlock state of the user key
1805 case UserState.STATE_STOPPING:
1806 case UserState.STATE_SHUTDOWN:
1807 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001808 default:
1809 return false;
1810 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001811 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001812 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001813 switch (state.state) {
1814 case UserState.STATE_RUNNING_UNLOCKED:
1815 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001816 // In the stopping/shutdown state return unlock state of the user key
1817 case UserState.STATE_STOPPING:
1818 case UserState.STATE_SHUTDOWN:
1819 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001820 default:
1821 return false;
1822 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001823 }
1824
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001825 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001826 }
1827
Keun young Parke339eef2019-03-27 13:20:16 -07001828 /**
1829 * Check if system user is already started. Unlike other user, system user is in STATE_BOOTING
1830 * even if it is not explicitly started. So isUserRunning cannot give the right state
1831 * to check if system user is started or not.
1832 * @return true if system user is started.
1833 */
1834 boolean isSystemUserStarted() {
1835 synchronized (mLock) {
1836 UserState uss = mStartedUsers.get(UserHandle.USER_SYSTEM);
1837 if (uss == null) {
1838 return false;
1839 }
1840 return uss.state == UserState.STATE_RUNNING_LOCKED
1841 || uss.state == UserState.STATE_RUNNING_UNLOCKING
1842 || uss.state == UserState.STATE_RUNNING_UNLOCKED;
1843 }
1844 }
1845
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001846 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001847 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001848 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001849 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001850 != PackageManager.PERMISSION_GRANTED)) {
1851 String msg = "Permission Denial: getCurrentUser() from pid="
1852 + Binder.getCallingPid()
1853 + ", uid=" + Binder.getCallingUid()
1854 + " requires " + INTERACT_ACROSS_USERS;
1855 Slog.w(TAG, msg);
1856 throw new SecurityException(msg);
1857 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001858
1859 // Optimization - if there is no pending user switch, return current id
1860 if (mTargetUserId == UserHandle.USER_NULL) {
1861 return getUserInfo(mCurrentUserId);
1862 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001863 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001864 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001865 }
1866 }
1867
Andreas Gampee7739b32018-07-20 12:55:36 -07001868 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001869 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001870 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001871 return getUserInfo(userId);
1872 }
1873
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001874 int getCurrentOrTargetUserId() {
1875 synchronized (mLock) {
1876 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1877 }
1878 }
1879
Andreas Gampee7739b32018-07-20 12:55:36 -07001880 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001881 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001882 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001883 }
1884
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001885
Andreas Gampee7739b32018-07-20 12:55:36 -07001886 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001887 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001888 return mCurrentUserId;
1889 }
1890
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001891 int getCurrentUserId() {
1892 synchronized (mLock) {
1893 return mCurrentUserId;
1894 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001895 }
1896
Andreas Gampee7739b32018-07-20 12:55:36 -07001897 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001898 private boolean isCurrentUserLU(int userId) {
1899 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001900 }
1901
1902 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001903 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001904 return ums != null ? ums.getUserIds() : new int[] { 0 };
1905 }
1906
Wale Ogunwale86b74462018-07-02 08:42:43 -07001907 private UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001908 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001909 }
1910
1911 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001912 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001913 }
1914
Makoto Onuki6569c362018-02-27 15:52:01 -08001915 /**
1916 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1917 * IDs. Otherwise return an array whose only element is the given user id.
1918 *
1919 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1920 */
1921 int[] expandUserId(int userId) {
1922 if (userId != UserHandle.USER_ALL) {
1923 return new int[] {userId};
1924 } else {
1925 return getUsers();
1926 }
1927 }
1928
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001929 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001930 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001931 }
1932
Wale Ogunwale86b74462018-07-02 08:42:43 -07001933 private void enforceShellRestriction(String restriction, int userHandle) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001934 if (Binder.getCallingUid() == SHELL_UID) {
1935 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1936 throw new SecurityException("Shell does not have permission to access user "
1937 + userHandle);
1938 }
1939 }
1940 }
1941
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001942 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001943 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001944 }
1945
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001946 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001947 if (callingUserId == targetUserId) {
1948 return true;
1949 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001950 synchronized (mLock) {
1951 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001952 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001953 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001954 UserInfo.NO_PROFILE_GROUP_ID);
1955 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1956 && callingProfile == targetProfile;
1957 }
1958 }
1959
Tony Mak60f53e62017-12-21 20:03:29 +00001960 boolean isUserOrItsParentRunning(int userId) {
1961 synchronized (mLock) {
1962 if (isUserRunning(userId, 0)) {
1963 return true;
1964 }
1965 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1966 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1967 return false;
1968 }
1969 return isUserRunning(parentUserId, 0);
1970 }
1971 }
1972
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001973 boolean isCurrentProfile(int userId) {
1974 synchronized (mLock) {
1975 return ArrayUtils.contains(mCurrentProfileIds, userId);
1976 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001977 }
1978
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001979 int[] getCurrentProfileIds() {
1980 synchronized (mLock) {
1981 return mCurrentProfileIds;
1982 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001983 }
1984
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001985 void onUserRemoved(int userId) {
1986 synchronized (mLock) {
1987 int size = mUserProfileGroupIds.size();
1988 for (int i = size - 1; i >= 0; i--) {
1989 if (mUserProfileGroupIds.keyAt(i) == userId
1990 || mUserProfileGroupIds.valueAt(i) == userId) {
1991 mUserProfileGroupIds.removeAt(i);
1992
1993 }
1994 }
1995 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1996 }
1997 }
1998
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001999 /**
2000 * Returns whether the given user requires credential entry at this time. This is used to
2001 * intercept activity launches for work apps when the Work Challenge is present.
2002 */
Benjamin Franz563707b2017-06-29 15:06:13 +01002003 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002004 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00002005 if (mStartedUsers.get(userId) == null) {
2006 return false;
2007 }
2008 }
Clara Bayarria1771112015-12-18 16:29:18 +00002009 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00002010 return false;
2011 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002012 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01002013 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00002014 }
2015
Tony Mak8c536f92016-03-21 12:20:41 +00002016 boolean isLockScreenDisabled(@UserIdInt int userId) {
2017 return mLockPatternUtils.isLockScreenDisabled(userId);
2018 }
2019
Alex Chau93ae42b2018-01-11 15:10:12 +00002020 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
2021 synchronized (mLock) {
2022 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
2023 }
2024 }
2025
2026 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
2027 synchronized (mLock) {
2028 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
2029 }
2030 }
2031
2032 private String getSwitchingFromSystemUserMessage() {
2033 synchronized (mLock) {
2034 return mSwitchingFromSystemUserMessage;
2035 }
2036 }
2037
2038 private String getSwitchingToSystemUserMessage() {
2039 synchronized (mLock) {
2040 return mSwitchingToSystemUserMessage;
2041 }
2042 }
2043
Yi Jin148d7f42017-11-28 14:23:56 -08002044 void writeToProto(ProtoOutputStream proto, long fieldId) {
2045 synchronized (mLock) {
2046 long token = proto.start(fieldId);
2047 for (int i = 0; i < mStartedUsers.size(); i++) {
2048 UserState uss = mStartedUsers.valueAt(i);
2049 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
2050 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
2051 uss.writeToProto(proto, UserControllerProto.User.STATE);
2052 proto.end(uToken);
2053 }
2054 for (int i = 0; i < mStartedUserArray.length; i++) {
2055 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
2056 }
2057 for (int i = 0; i < mUserLru.size(); i++) {
2058 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
2059 }
2060 if (mUserProfileGroupIds.size() > 0) {
2061 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
2062 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
2063 proto.write(UserControllerProto.UserProfile.USER,
2064 mUserProfileGroupIds.keyAt(i));
2065 proto.write(UserControllerProto.UserProfile.PROFILE,
2066 mUserProfileGroupIds.valueAt(i));
2067 proto.end(uToken);
2068 }
2069 }
2070 proto.end(token);
2071 }
2072 }
2073
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002074 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002075 synchronized (mLock) {
2076 pw.println(" mStartedUsers:");
2077 for (int i = 0; i < mStartedUsers.size(); i++) {
2078 UserState uss = mStartedUsers.valueAt(i);
2079 pw.print(" User #");
2080 pw.print(uss.mHandle.getIdentifier());
2081 pw.print(": ");
2082 uss.dump("", pw);
2083 }
2084 pw.print(" mStartedUserArray: [");
2085 for (int i = 0; i < mStartedUserArray.length; i++) {
2086 if (i > 0)
2087 pw.print(", ");
2088 pw.print(mStartedUserArray[i]);
2089 }
2090 pw.println("]");
2091 pw.print(" mUserLru: [");
2092 for (int i = 0; i < mUserLru.size(); i++) {
2093 if (i > 0)
2094 pw.print(", ");
2095 pw.print(mUserLru.get(i));
2096 }
2097 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002098 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002099 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002100 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002101 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002102 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002103 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002104 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002105 }
2106 }
Keun young Parkdf54b662019-03-13 14:06:42 -07002107 pw.println(" mCurrentUserId:" + mCurrentUserId);
2108 pw.println(" mLastActiveUsers:" + mLastActiveUsers);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002109 }
2110 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002111
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002112 public boolean handleMessage(Message msg) {
2113 switch (msg.what) {
2114 case START_USER_SWITCH_FG_MSG:
2115 startUserInForeground(msg.arg1);
2116 break;
2117 case REPORT_USER_SWITCH_MSG:
2118 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2119 break;
2120 case CONTINUE_USER_SWITCH_MSG:
2121 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2122 break;
2123 case USER_SWITCH_TIMEOUT_MSG:
2124 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2125 break;
2126 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
2127 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
2128 break;
2129 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002130 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002131 break;
2132 case SYSTEM_USER_START_MSG:
2133 mInjector.batteryStatsServiceNoteEvent(
2134 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2135 Integer.toString(msg.arg1), msg.arg1);
2136 mInjector.getSystemServiceManager().startUser(msg.arg1);
2137 break;
2138 case SYSTEM_USER_UNLOCK_MSG:
2139 final int userId = msg.arg1;
2140 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08002141 // Loads recents on a worker thread that allows disk I/O
2142 FgThread.getHandler().post(() -> {
2143 mInjector.loadUserRecents(userId);
2144 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002145 finishUserUnlocked((UserState) msg.obj);
2146 break;
2147 case SYSTEM_USER_CURRENT_MSG:
2148 mInjector.batteryStatsServiceNoteEvent(
2149 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2150 Integer.toString(msg.arg2), msg.arg2);
2151 mInjector.batteryStatsServiceNoteEvent(
2152 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2153 Integer.toString(msg.arg1), msg.arg1);
2154
2155 mInjector.getSystemServiceManager().switchUser(msg.arg1);
2156 break;
2157 case FOREGROUND_PROFILE_CHANGED_MSG:
2158 dispatchForegroundProfileChanged(msg.arg1);
2159 break;
2160 case REPORT_USER_SWITCH_COMPLETE_MSG:
2161 dispatchUserSwitchComplete(msg.arg1);
2162 break;
2163 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
2164 dispatchLockedBootComplete(msg.arg1);
2165 break;
2166 case START_USER_SWITCH_UI_MSG:
2167 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2168 break;
2169 }
2170 return false;
2171 }
2172
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002173 private static class UserProgressListener extends IProgressListener.Stub {
2174 private volatile long mUnlockStarted;
2175 @Override
2176 public void onStarted(int id, Bundle extras) throws RemoteException {
2177 Slog.d(TAG, "Started unlocking user " + id);
2178 mUnlockStarted = SystemClock.uptimeMillis();
2179 }
2180
2181 @Override
2182 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2183 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2184 }
2185
2186 @Override
2187 public void onFinished(int id, Bundle extras) throws RemoteException {
2188 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2189
2190 // Report system user unlock time to perf dashboard
2191 if (id == UserHandle.USER_SYSTEM) {
2192 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2193 .logDuration("SystemUserUnlock", unlockTime);
2194 } else {
Keun-young Park29f70de2019-02-07 09:33:12 -08002195 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2196 .logDuration("User" + id + "Unlock", unlockTime);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002197 }
2198 }
2199 };
2200
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002201 @VisibleForTesting
2202 static class Injector {
2203 private final ActivityManagerService mService;
2204 private UserManagerService mUserManager;
2205 private UserManagerInternal mUserManagerInternal;
2206
2207 Injector(ActivityManagerService service) {
2208 mService = service;
2209 }
2210
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002211 protected Handler getHandler(Handler.Callback callback) {
2212 return new Handler(mService.mHandlerThread.getLooper(), callback);
2213 }
2214
2215 protected Handler getUiHandler(Handler.Callback callback) {
2216 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002217 }
2218
2219 protected Context getContext() {
2220 return mService.mContext;
2221 }
2222
2223 protected LockPatternUtils getLockPatternUtils() {
2224 return new LockPatternUtils(getContext());
2225 }
2226
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002227 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002228 IIntentReceiver resultTo, int resultCode, String resultData,
2229 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
Michal Karpinskic99d7182019-02-17 13:15:23 +00002230 boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
2231 int realCallingPid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002232 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2233 synchronized (mService) {
2234 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2235 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
Michal Karpinskic99d7182019-02-17 13:15:23 +00002236 ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid,
2237 userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002238 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002239 }
2240
2241 int checkCallingPermission(String permission) {
2242 return mService.checkCallingPermission(permission);
2243 }
2244
2245 WindowManagerService getWindowManager() {
2246 return mService.mWindowManager;
2247 }
2248 void activityManagerOnUserStopped(int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002249 LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002250 }
2251
2252 void systemServiceManagerCleanupUser(int userId) {
2253 mService.mSystemServiceManager.cleanupUser(userId);
2254 }
2255
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002256 protected UserManagerService getUserManager() {
2257 if (mUserManager == null) {
2258 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2259 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2260 }
2261 return mUserManager;
2262 }
2263
2264 UserManagerInternal getUserManagerInternal() {
2265 if (mUserManagerInternal == null) {
2266 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2267 }
2268 return mUserManagerInternal;
2269 }
2270
2271 KeyguardManager getKeyguardManager() {
2272 return mService.mContext.getSystemService(KeyguardManager.class);
2273 }
2274
2275 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2276 mService.mBatteryStatsService.noteEvent(code, name, uid);
2277 }
2278
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002279 boolean isRuntimeRestarted() {
2280 return mService.mSystemServiceManager.isRuntimeRestarted();
2281 }
2282
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002283 SystemServiceManager getSystemServiceManager() {
2284 return mService.mSystemServiceManager;
2285 }
2286
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002287 boolean isFirstBootOrUpgrade() {
2288 IPackageManager pm = AppGlobals.getPackageManager();
2289 try {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002290 return pm.isFirstBoot() || pm.isDeviceUpgrading();
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002291 } catch (RemoteException e) {
2292 throw e.rethrowFromSystemServer();
2293 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002294 }
2295
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002296 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2297 new PreBootBroadcaster(mService, userId, null, quiet) {
2298 @Override
2299 public void onFinished() {
2300 onFinish.run();
2301 }
2302 }.sendNext();
2303 }
2304
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002305 void activityManagerForceStopPackage(int userId, String reason) {
2306 synchronized (mService) {
2307 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2308 userId, reason);
2309 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002310 };
2311
2312 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2313 boolean exported) {
2314 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2315 }
2316
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002317 protected void startHomeActivity(int userId, String reason) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07002318 mService.mAtmInternal.startHomeActivity(userId, reason);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002319 }
2320
Christopher Tate88dc93f2018-07-27 16:48:37 -07002321 void startUserWidgets(int userId) {
2322 AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
Ralph Nathan1d1e80a2018-08-13 16:08:53 -07002323 if (awm != null) {
Christopher Tate63227d92019-02-13 14:24:01 -08002324 // Out of band, because this is called during a sequence with
2325 // sensitive cross-service lock management
2326 FgThread.getHandler().post(() -> {
2327 awm.unlockUser(userId);
2328 });
Ralph Nathan1d1e80a2018-08-13 16:08:53 -07002329 }
Christopher Tate88dc93f2018-07-27 16:48:37 -07002330 }
2331
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002332 void updateUserConfiguration() {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002333 mService.mAtmInternal.updateUserConfiguration();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002334 }
2335
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002336 void clearBroadcastQueueForUser(int userId) {
2337 synchronized (mService) {
2338 mService.clearBroadcastQueueForUserLocked(userId);
2339 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002340 }
2341
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002342 void loadUserRecents(int userId) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002343 mService.mAtmInternal.loadRecentTasksForUser(userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002344 }
2345
2346 void startPersistentApps(int matchFlags) {
2347 mService.startPersistentApps(matchFlags);
2348 }
2349
2350 void installEncryptionUnawareProviders(int userId) {
2351 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002352 }
2353
Alex Chau93ae42b2018-01-11 15:10:12 +00002354 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2355 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002356 Dialog d;
2357 if (!mService.mContext.getPackageManager()
2358 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2359 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002360 true /* above system */, switchingFromSystemUserMessage,
2361 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002362 } else {
2363 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2364 true /* above system */, switchingFromSystemUserMessage,
2365 switchingToSystemUserMessage);
2366 }
2367
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002368 d.show();
2369 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002370
Dianne Hackbornced54392018-02-26 13:07:42 -08002371 void reportGlobalUsageEventLocked(int event) {
2372 synchronized (mService) {
2373 mService.reportGlobalUsageEventLocked(event);
2374 }
2375 }
2376
2377 void reportCurWakefulnessUsageEvent() {
2378 synchronized (mService) {
2379 mService.reportCurWakefulnessUsageEventLocked();
2380 }
2381 }
2382
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002383 void stackSupervisorRemoveUser(int userId) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002384 mService.mAtmInternal.removeUser(userId);
Tony Mak5c2cf032017-04-03 18:38:23 +01002385 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002386
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002387 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002388 return mService.mAtmInternal.switchUser(userId, uss);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002389 }
2390
2391 protected void stackSupervisorResumeFocusedStackTopActivity() {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002392 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002393 }
2394
Charles Heff9b4dff2017-09-22 10:18:37 +01002395 protected void clearAllLockedTasks(String reason) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002396 mService.mAtmInternal.clearLockedTasks(reason);
Benjamin Franza83859f2017-07-03 16:34:14 +01002397 }
Tony Make839d702018-01-22 15:34:46 +00002398
2399 protected boolean isCallerRecents(int callingUid) {
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002400 return mService.mAtmInternal.isCallerRecents(callingUid);
Tony Make839d702018-01-22 15:34:46 +00002401 }
Keun young Parkdf54b662019-03-13 14:06:42 -07002402
2403 protected IStorageManager getStorageManager() {
2404 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
2405 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002406 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002407}