blob: c981e6885a9e33ec8988766d525ef7d8518431d4 [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;
Daniel Rosenberge129e5c2018-11-07 19:25:55 -080070import android.os.PowerManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070071import android.os.Process;
72import android.os.RemoteCallbackList;
73import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070074import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070075import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070076import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070077import android.os.UserHandle;
78import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010079import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080080import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080081import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070082import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070083import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070084import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080085import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070086import android.util.Slog;
87import android.util.SparseArray;
88import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070089import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080090import android.util.proto.ProtoOutputStream;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070091
92import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080093import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070094import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070095import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070096import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070097import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000098import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080099import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100100import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700101import com.android.server.SystemServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700102import com.android.server.pm.UserManagerService;
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
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700245 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700246 this(new Injector(service));
247 }
248
249 @VisibleForTesting
250 UserController(Injector injector) {
251 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700252 mHandler = mInjector.getHandler(this);
253 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700254 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800255 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700256 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800257 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700258 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700259 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700260 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700261 }
262
263 void finishUserSwitch(UserState uss) {
Wale Ogunwale86b74462018-07-02 08:42:43 -0700264 // This call holds the AM lock so we post to the handler.
265 mHandler.post(() -> {
266 finishUserBoot(uss);
267 startProfiles();
268 synchronized (mLock) {
269 stopRunningUsersLU(mMaxRunningUsers);
270 }
271 });
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700272 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700273
Andreas Gampee7739b32018-07-20 12:55:36 -0700274 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000275 List<Integer> getRunningUsersLU() {
276 ArrayList<Integer> runningUsers = new ArrayList<>();
277 for (Integer userId : mUserLru) {
278 UserState uss = mStartedUsers.get(userId);
279 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700280 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700281 continue;
282 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000283 if (uss.state == UserState.STATE_STOPPING
284 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700285 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700286 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700287 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000288 if (userId == UserHandle.USER_SYSTEM) {
289 // We only count system user as running when it is not a pure system user.
290 if (UserInfo.isSystemOnly(userId)) {
291 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700292 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000293 }
294 runningUsers.add(userId);
295 }
296 return runningUsers;
297 }
298
Andreas Gampee7739b32018-07-20 12:55:36 -0700299 @GuardedBy("mLock")
Alex Chaub6ef8692018-01-09 14:16:36 +0000300 void stopRunningUsersLU(int maxRunningUsers) {
301 List<Integer> currentlyRunning = getRunningUsersLU();
302 Iterator<Integer> iterator = currentlyRunning.iterator();
303 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
304 Integer userId = iterator.next();
305 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
306 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700307 continue;
308 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000309 if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
310 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700311 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000312 }
313 }
314
315 /**
316 * Returns if more users can be started without stopping currently running users.
317 */
318 boolean canStartMoreUsers() {
319 synchronized (mLock) {
320 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700321 }
322 }
323
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800324 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700325 finishUserBoot(uss, null);
326 }
327
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800328 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700329 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700330
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700331 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700332 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700333 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700334 if (mStartedUsers.get(userId) != uss) {
335 return;
336 }
337 }
Daniel Rosenberge129e5c2018-11-07 19:25:55 -0800338 // Inform checkpointing systems of success
339 try {
340 getStorageManager().commitChanges();
341 } catch (Exception e) {
342 PowerManager pm = (PowerManager)
343 mInjector.getContext().getSystemService(Context.POWER_SERVICE);
344 pm.reboot("Checkpoint commit failed");
345 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700346
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700347 // We always walk through all the user lifecycle states to send
348 // consistent developer events. We step into RUNNING_LOCKED here,
349 // but we might immediately step into RUNNING below if the user
350 // storage is already unlocked.
351 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
352 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
353 // Do not report secondary users, runtime restarts or first boot/upgrade
354 if (userId == UserHandle.USER_SYSTEM
355 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
356 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
357 MetricsLogger.histogram(mInjector.getContext(),
358 "framework_locked_boot_completed", uptimeSeconds);
359 final int MAX_UPTIME_SECONDS = 120;
360 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
361 Slog.wtf("SystemServerTiming",
362 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800363 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700364 }
365
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700366 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
367 userId, 0));
368 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
369 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
370 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
371 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
372 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
373 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
374 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
375 }
376
377 // We need to delay unlocking managed profiles until the parent user
378 // is also unlocked.
379 if (mInjector.getUserManager().isManagedProfile(userId)) {
380 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
381 if (parent != null
382 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
383 Slog.d(TAG, "User " + userId + " (parent " + parent.id
384 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600385 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700386 } else {
387 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
388 Slog.d(TAG, "User " + userId + " (parent " + parentId
389 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600390 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700391 } else {
392 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700393 }
394 }
395
396 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600397 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
398 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700399 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600400 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700401 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700402 // Only keep marching forward if user is actually unlocked
403 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700404 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800405 // Do not proceed if unexpected state or a stale user
406 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700407 return;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600408 }
409 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700410 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200411
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700412 // Prepare app storage before we go any further
413 uss.mUnlockProgress.setProgress(5,
414 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200415
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800416 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
417 FgThread.getHandler().post(() -> {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100418 if (!StorageManager.isUserKeyUnlocked(userId)) {
419 Slog.w(TAG, "User key got locked unexpectedly, leaving user locked.");
420 return;
421 }
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800422 mInjector.getUserManager().onBeforeUnlockUser(userId);
423 synchronized (mLock) {
424 // Do not proceed if unexpected state
425 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
426 return;
427 }
428 }
429 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
430
431 uss.mUnlockProgress.setProgress(20);
432
433 // Dispatch unlocked to system services; when fully dispatched,
434 // that calls through to the next "unlocked" phase
435 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
436 .sendToTarget();
437 });
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600438 }
439
440 /**
441 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
442 * {@link UserState#STATE_RUNNING_UNLOCKED}.
443 */
444 void finishUserUnlocked(final UserState uss) {
445 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700446 // Only keep marching forward if user is actually unlocked
447 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700448 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600449 // Bail if we ended up with a stale user
450 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
451
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700452 // Do not proceed if unexpected state
453 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
454 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600455 }
456 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700457 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
458 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700459
460 // Get unaware persistent apps running and start any unaware providers
461 // in already-running apps that are partially aware
462 if (userId == UserHandle.USER_SYSTEM) {
463 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
464 }
465 mInjector.installEncryptionUnawareProviders(userId);
466
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700467 // Dispatch unlocked to external apps
468 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
469 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
470 unlockedIntent.addFlags(
471 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
472 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
473 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
474 userId);
475
476 if (getUserInfo(userId).isManagedProfile()) {
477 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
478 if (parent != null) {
479 final Intent profileUnlockedIntent = new Intent(
480 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
481 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
482 profileUnlockedIntent.addFlags(
483 Intent.FLAG_RECEIVER_REGISTERED_ONLY
484 | Intent.FLAG_RECEIVER_FOREGROUND);
485 mInjector.broadcastIntent(profileUnlockedIntent,
486 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
487 null, false, false, MY_PID, SYSTEM_UID,
488 parent.id);
489 }
490 }
491
492 // Send PRE_BOOT broadcasts if user fingerprint changed; we
493 // purposefully block sending BOOT_COMPLETED until after all
494 // PRE_BOOT receivers are finished to avoid ANR'ing apps
495 final UserInfo info = getUserInfo(userId);
496 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
497 // Suppress double notifications for managed profiles that
498 // were unlocked automatically as part of their parent user
499 // being unlocked.
500 final boolean quiet;
501 if (info.isManagedProfile()) {
502 quiet = !uss.tokenProvided
503 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
504 } else {
505 quiet = false;
506 }
507 mInjector.sendPreBootBroadcast(userId, quiet,
508 () -> finishUserUnlockedCompleted(uss));
509 } else {
510 finishUserUnlockedCompleted(uss);
511 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600512 }
513
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600514 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600515 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700516 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600517 // Bail if we ended up with a stale user
518 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700519 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700520 UserInfo userInfo = getUserInfo(userId);
521 if (userInfo == null) {
522 return;
523 }
524 // Only keep marching forward if user is actually unlocked
525 if (!StorageManager.isUserKeyUnlocked(userId)) return;
526
527 // Remember that we logged in
528 mInjector.getUserManager().onUserLoggedIn(userId);
529
530 if (!userInfo.isInitialized()) {
531 if (userId != UserHandle.USER_SYSTEM) {
532 Slog.d(TAG, "Initializing user #" + userId);
533 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
534 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
535 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
536 mInjector.broadcastIntent(intent, null,
537 new IIntentReceiver.Stub() {
538 @Override
539 public void performReceive(Intent intent, int resultCode,
540 String data, Bundle extras, boolean ordered,
541 boolean sticky, int sendingUser) {
542 // Note: performReceive is called with mService lock held
543 mInjector.getUserManager().makeInitialized(userInfo.id);
544 }
545 }, 0, null, null, null, AppOpsManager.OP_NONE,
546 null, true, false, MY_PID, SYSTEM_UID, userId);
547 }
548 }
549
Christopher Tate88dc93f2018-07-27 16:48:37 -0700550 // Spin up app widgets prior to boot-complete, so they can be ready promptly
551 mInjector.startUserWidgets(userId);
552
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700553 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
554 // Do not report secondary users, runtime restarts or first boot/upgrade
555 if (userId == UserHandle.USER_SYSTEM
556 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
557 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
558 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
559 uptimeSeconds);
560 }
561 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
562 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
563 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
Ng Zhi An150a6ba2018-08-13 09:08:11 -0700564 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
565 | Intent.FLAG_RECEIVER_OFFLOAD);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700566 mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
567 @Override
568 public void performReceive(Intent intent, int resultCode, String data,
569 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
570 throws RemoteException {
571 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
Ng Zhi An7ff7fdb2019-01-16 15:35:51 -0800572 mBootCompleted = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700573 }
574 }, 0, null, null,
575 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
576 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700577 }
578
Andrew Scull85a63bc2016-10-24 13:47:47 +0100579 int restartUser(final int userId, final boolean foreground) {
580 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
581 @Override
582 public void userStopped(final int userId) {
583 // Post to the same handler that this callback is called from to ensure the user
584 // cleanup is complete before restarting.
585 mHandler.post(() -> startUser(userId, foreground));
586 }
587 @Override
588 public void userStopAborted(final int userId) {}
589 });
590 }
591
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700592 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700593 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700594 != PackageManager.PERMISSION_GRANTED) {
595 String msg = "Permission Denial: switchUser() from pid="
596 + Binder.getCallingPid()
597 + ", uid=" + Binder.getCallingUid()
598 + " requires " + INTERACT_ACROSS_USERS_FULL;
599 Slog.w(TAG, msg);
600 throw new SecurityException(msg);
601 }
602 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
603 throw new IllegalArgumentException("Can't stop system user " + userId);
604 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700605 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700606 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700607 return stopUsersLU(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700608 }
609 }
610
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700611 /**
612 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700613 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700614 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700615 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700616 private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700617 if (userId == UserHandle.USER_SYSTEM) {
618 return USER_OP_ERROR_IS_SYSTEM;
619 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700620 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700621 return USER_OP_IS_CURRENT;
622 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700623 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700624 // If one of related users is system or current, no related users should be stopped
625 for (int i = 0; i < usersToStop.length; i++) {
626 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700627 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700628 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
629 + relatedUserId);
630 // We still need to stop the requested user if it's a force stop.
631 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800632 Slog.i(TAG,
633 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700634 stopSingleUserLU(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800635 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700636 }
637 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
638 }
639 }
640 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
641 for (int userIdToStop : usersToStop) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700642 stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700643 }
644 return USER_OP_SUCCESS;
645 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700646
Andreas Gampee7739b32018-07-20 12:55:36 -0700647 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700648 private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700649 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700650 final UserState uss = mStartedUsers.get(userId);
651 if (uss == null) {
652 // User is not started, nothing to do... but we do need to
653 // callback if requested.
654 if (callback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700655 mHandler.post(() -> {
656 try {
657 callback.userStopped(userId);
658 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700659 }
660 });
661 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700662 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700663 }
664
665 if (callback != null) {
666 uss.mStopCallbacks.add(callback);
667 }
668
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700669 if (uss.state != UserState.STATE_STOPPING
670 && uss.state != UserState.STATE_SHUTDOWN) {
671 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700672 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700673 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700674
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700675 // Post to handler to obtain amLock
676 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700677 // We are going to broadcast ACTION_USER_STOPPING and then
678 // once that is done send a final ACTION_SHUTDOWN and then
679 // stop the user.
680 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
681 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
682 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
683 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700684 // This is the result receiver for the initial stopping broadcast.
685 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
686 @Override
687 public void performReceive(Intent intent, int resultCode, String data,
688 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700689 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700690 }
691 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700692
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700693 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700694 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700695 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700696 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700697 null, stoppingReceiver, 0, null, null,
698 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700699 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700700 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700701 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700702 }
703
Amith Yamasani98c05562016-03-30 13:15:26 -0700704 void finishUserStopping(final int userId, final UserState uss) {
705 // On to the next.
706 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
707 // This is the result receiver for the final shutdown broadcast.
708 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
709 @Override
710 public void performReceive(Intent intent, int resultCode, String data,
711 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
712 mHandler.post(new Runnable() {
713 @Override
714 public void run() {
715 finishUserStopped(uss);
716 }
717 });
718 }
719 };
720
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700721 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700722 if (uss.state != UserState.STATE_STOPPING) {
723 // Whoops, we are being started back up. Abort, abort!
724 return;
725 }
726 uss.setState(UserState.STATE_SHUTDOWN);
727 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700728 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700729
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700730 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700731 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
732 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700733 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700734
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700735 mInjector.broadcastIntent(shutdownIntent,
736 null, shutdownReceiver, 0, null, null, null,
737 AppOpsManager.OP_NONE,
738 null, true, false, MY_PID, SYSTEM_UID, userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700739 }
740
741 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700742 final int userId = uss.mHandle.getIdentifier();
Pavel Grafov634c34e2018-04-10 19:19:01 +0100743 final boolean stopped;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700744 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700745 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700746 callbacks = new ArrayList<>(uss.mStopCallbacks);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100747 if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700748 stopped = false;
749 } else {
750 stopped = true;
751 // User can no longer run.
752 mStartedUsers.remove(userId);
753 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700754 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700755 }
756 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100757
758 if (stopped) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700759 mInjector.getUserManagerInternal().removeUserState(userId);
760 mInjector.activityManagerOnUserStopped(userId);
761 // Clean up all state and processes associated with the user.
762 // Kill all the processes for the user.
763 forceStopUser(userId, "finish user");
764 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700765
766 for (int i = 0; i < callbacks.size(); i++) {
767 try {
768 if (stopped) callbacks.get(i).userStopped(userId);
769 else callbacks.get(i).userStopAborted(userId);
770 } catch (RemoteException e) {
771 }
772 }
773
774 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700775 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700776 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100777 // Remove the user if it is ephemeral.
778 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000779 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100780 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100781
782 // Evict the user's credential encryption key. Performed on FgThread to make it
783 // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
784 // to prevent data corruption.
785 FgThread.getHandler().post(() -> {
786 synchronized (mLock) {
787 if (mStartedUsers.get(userId) != null) {
788 Slog.w(TAG, "User was restarted, skipping key eviction");
789 return;
790 }
791 }
792 try {
793 getStorageManager().lockUserKey(userId);
794 } catch (RemoteException re) {
795 throw re.rethrowAsRuntimeException();
796 }
797 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700798 }
799 }
800
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700801 /**
802 * Determines the list of users that should be stopped together with the specified
803 * {@code userId}. The returned list includes {@code userId}.
804 */
Andreas Gampee7739b32018-07-20 12:55:36 -0700805 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700806 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700807 int startedUsersSize = mStartedUsers.size();
808 IntArray userIds = new IntArray();
809 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700810 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
811 for (int i = 0; i < startedUsersSize; i++) {
812 UserState uss = mStartedUsers.valueAt(i);
813 int startedUserId = uss.mHandle.getIdentifier();
814 // Skip unrelated users (profileGroupId mismatch)
815 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700816 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700817 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
818 && (userGroupId == startedUserGroupId);
819 // userId has already been added
820 boolean sameUserId = startedUserId == userId;
821 if (!sameGroup || sameUserId) {
822 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700823 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700824 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700825 }
826 return userIds.toArray();
827 }
828
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700829 private void forceStopUser(int userId, String reason) {
830 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700831 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
832 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
833 | Intent.FLAG_RECEIVER_FOREGROUND);
834 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700835 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700836 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700837 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700838 }
839
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700840 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100841 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700842 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000843 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
844 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000845 synchronized(mLock) {
846 UserState oldUss = mStartedUsers.get(oldUserId);
847 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
848 || oldUss.state == UserState.STATE_STOPPING
849 || oldUss.state == UserState.STATE_SHUTDOWN) {
850 return;
851 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700852 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000853
854 UserInfo userInfo = getUserInfo(oldUserId);
855 if (userInfo.isEphemeral()) {
856 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
857 }
858 if (userInfo.isGuest() || userInfo.isEphemeral()) {
859 // This is a user to be stopped.
860 synchronized (mLock) {
861 stopUsersLU(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700862 }
863 }
864 }
865
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700866 void scheduleStartProfiles() {
Pavel Grafov10c16742018-09-20 15:03:47 +0100867 // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
868 // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
869 // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
870 // after the parent had chance to unlock fully.
871 FgThread.getHandler().post(() -> {
872 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
873 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
874 DateUtils.SECOND_IN_MILLIS);
875 }
876 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700877 }
878
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700879 void startProfiles() {
880 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700881 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700882 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700883 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700884 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
885 for (UserInfo user : profiles) {
886 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700887 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700888 profilesToStart.add(user);
889 }
890 }
891 final int profilesToStartSize = profilesToStart.size();
892 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700893 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700894 startUser(profilesToStart.get(i).id, /* foreground= */ false);
895 }
896 if (i < profilesToStartSize) {
897 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
898 }
899 }
900
Sudheer Shanka2250d562016-11-07 15:41:02 -0800901 private IStorageManager getStorageManager() {
902 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700903 }
Tony Mak64fd8c02017-12-01 19:11:59 +0000904 boolean startUser(final int userId, final boolean foreground) {
905 return startUser(userId, foreground, null);
906 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700907
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700908 /**
909 * Start user, if its not already running.
910 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
911 * When starting the user, multiple intents will be broadcast in the following order:</p>
912 * <ul>
913 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
914 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
915 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
916 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
917 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
918 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
919 * Sent only if {@code foreground} parameter is true
920 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
921 * of the new fg user
922 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
923 * the new user
924 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
925 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
926 * new user. Sent only when the user is booting after a system update.
927 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
928 * new user. Sent only the first time a user is starting.
929 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
930 * user. Indicates that the user has finished booting.
931 * </ul>
932 *
933 * @param userId ID of the user to start
934 * @param foreground true if user should be brought to the foreground
935 * @return true if the user has been successfully started
936 */
Tony Mak64fd8c02017-12-01 19:11:59 +0000937 boolean startUser(
938 final int userId,
939 final boolean foreground,
940 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700941 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700942 != PackageManager.PERMISSION_GRANTED) {
943 String msg = "Permission Denial: switchUser() from pid="
944 + Binder.getCallingPid()
945 + ", uid=" + Binder.getCallingUid()
946 + " requires " + INTERACT_ACROSS_USERS_FULL;
947 Slog.w(TAG, msg);
948 throw new SecurityException(msg);
949 }
950
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700951 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700952
953 final long ident = Binder.clearCallingIdentity();
954 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700955 final int oldUserId = getCurrentUserId();
956 if (oldUserId == userId) {
957 return true;
958 }
959
960 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100961 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700962 }
963
964 final UserInfo userInfo = getUserInfo(userId);
965 if (userInfo == null) {
966 Slog.w(TAG, "No user info for user #" + userId);
967 return false;
968 }
969 if (foreground && userInfo.isManagedProfile()) {
970 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
971 return false;
972 }
973
974 if (foreground && mUserSwitchUiEnabled) {
975 mInjector.getWindowManager().startFreezingScreen(
976 R.anim.screen_user_exit, R.anim.screen_user_enter);
977 }
978
979 boolean needStart = false;
980 boolean updateUmState = false;
981 UserState uss;
982
983 // If the user we are switching to is not currently started, then
984 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700985 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700986 uss = mStartedUsers.get(userId);
987 if (uss == null) {
988 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700989 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700990 mStartedUsers.put(userId, uss);
991 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700992 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700993 updateUmState = true;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -0700994 } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
995 Slog.i(TAG, "User #" + userId
996 + " is shutting down - will start after full stop");
997 mHandler.post(() -> startUser(userId, foreground, unlockListener));
998 return true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700999 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001000 final Integer userIdInt = userId;
1001 mUserLru.remove(userIdInt);
1002 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +00001003 }
1004 if (unlockListener != null) {
1005 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001006 }
1007 if (updateUmState) {
1008 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1009 }
1010 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -08001011 // Make sure the old user is no longer considering the display to be on.
1012 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001013 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001014 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001015 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001016 }
1017 mInjector.updateUserConfiguration();
1018 updateCurrentProfileIds();
1019 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -08001020 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001021 // Once the internal notion of the active user has switched, we lock the device
1022 // with the option to show the user switcher on the keyguard.
1023 if (mUserSwitchUiEnabled) {
1024 mInjector.getWindowManager().setSwitchingUser(true);
1025 mInjector.getWindowManager().lockNow(null);
1026 }
1027 } else {
1028 final Integer currentUserIdInt = mCurrentUserId;
1029 updateCurrentProfileIds();
1030 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
1031 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001032 mUserLru.remove(currentUserIdInt);
1033 mUserLru.add(currentUserIdInt);
1034 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001035 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001036
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001037 // Make sure user is in the started state. If it is currently
1038 // stopping, we need to knock that off.
1039 if (uss.state == UserState.STATE_STOPPING) {
1040 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
1041 // so we can just fairly silently bring the user back from
1042 // the almost-dead.
1043 uss.setState(uss.lastState);
1044 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1045 synchronized (mLock) {
1046 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001047 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001048 needStart = true;
1049 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1050 // This means ACTION_SHUTDOWN has been sent, so we will
1051 // need to treat this as a new boot of the user.
1052 uss.setState(UserState.STATE_BOOTING);
1053 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1054 synchronized (mLock) {
1055 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001056 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001057 needStart = true;
1058 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001059
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001060 if (uss.state == UserState.STATE_BOOTING) {
1061 // Give user manager a chance to propagate user restrictions
1062 // to other services and prepare app storage
1063 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001064
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001065 // Booting up a new user, need to tell system services about it.
1066 // Note that this is on the same handler as scheduling of broadcasts,
1067 // which is important because it needs to go first.
1068 mHandler.sendMessage(
1069 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1070 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001071
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001072 if (foreground) {
1073 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1074 oldUserId));
1075 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1076 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1077 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1078 oldUserId, userId, uss));
1079 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1080 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1081 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001082
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001083 if (needStart) {
1084 // Send USER_STARTED broadcast
1085 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1086 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1087 | Intent.FLAG_RECEIVER_FOREGROUND);
1088 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1089 mInjector.broadcastIntent(intent,
1090 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1091 null, false, false, MY_PID, SYSTEM_UID, userId);
1092 }
1093
1094 if (foreground) {
1095 moveUserToForeground(uss, oldUserId, userId);
1096 } else {
1097 finishUserBoot(uss);
1098 }
1099
1100 if (needStart) {
1101 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1102 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1103 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1104 mInjector.broadcastIntent(intent,
1105 null, new IIntentReceiver.Stub() {
1106 @Override
1107 public void performReceive(Intent intent, int resultCode,
1108 String data, Bundle extras, boolean ordered,
1109 boolean sticky,
1110 int sendingUser) throws RemoteException {
1111 }
1112 }, 0, null, null,
1113 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
1114 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001115 }
1116 } finally {
1117 Binder.restoreCallingIdentity(ident);
1118 }
1119
1120 return true;
1121 }
1122
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001123 private boolean isCallingOnHandlerThread() {
1124 return Looper.myLooper() == mHandler.getLooper();
1125 }
1126
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001127 /**
1128 * Start user, if its not already running, and bring it to foreground.
1129 */
Evan Rosky18396452016-07-27 15:19:37 -07001130 void startUserInForeground(final int targetUserId) {
1131 boolean success = startUser(targetUserId, /* foreground */ true);
1132 if (!success) {
1133 mInjector.getWindowManager().setSwitchingUser(false);
1134 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001135 }
1136
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001137 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001138 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001139 != PackageManager.PERMISSION_GRANTED) {
1140 String msg = "Permission Denial: unlockUser() from pid="
1141 + Binder.getCallingPid()
1142 + ", uid=" + Binder.getCallingUid()
1143 + " requires " + INTERACT_ACROSS_USERS_FULL;
1144 Slog.w(TAG, msg);
1145 throw new SecurityException(msg);
1146 }
1147
Jeff Sharkey8924e872015-11-30 12:52:10 -07001148 final long binderToken = Binder.clearCallingIdentity();
1149 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001150 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001151 } finally {
1152 Binder.restoreCallingIdentity(binderToken);
1153 }
1154 }
1155
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001156 /**
1157 * Attempt to unlock user without a credential token. This typically
1158 * succeeds when the device doesn't have credential-encrypted storage, or
shafik172e1fb2018-12-05 14:52:38 +00001159 * when the credential-encrypted storage isn't tied to a user-provided
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001160 * PIN or pattern.
1161 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001162 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001163 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001164 return unlockUserCleared(userId, null, null, null);
1165 }
1166
1167 private static void notifyFinished(int userId, IProgressListener listener) {
1168 if (listener == null) return;
1169 try {
1170 listener.onFinished(userId, null);
1171 } catch (RemoteException ignored) {
1172 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001173 }
1174
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001175 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001176 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001177 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001178 if (!StorageManager.isUserKeyUnlocked(userId)) {
1179 final UserInfo userInfo = getUserInfo(userId);
1180 final IStorageManager storageManager = getStorageManager();
1181 try {
1182 // We always want to unlock user storage, even user is not started yet
1183 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1184 } catch (RemoteException | RuntimeException e) {
1185 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001186 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001187 }
1188 synchronized (mLock) {
1189 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001190 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001191 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001192 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001193 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001194 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001195 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001196 // Bail if user isn't actually running
1197 if (uss == null) {
1198 notifyFinished(userId, listener);
1199 return false;
1200 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001201
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001202 finishUserUnlocking(uss);
1203
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001204 // We just unlocked a user, so let's now attempt to unlock any
1205 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001206
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001207 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1208 int[] userIds;
1209 synchronized (mLock) {
1210 userIds = new int[mStartedUsers.size()];
1211 for (int i = 0; i < userIds.length; i++) {
1212 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001213 }
1214 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001215 for (int testUserId : userIds) {
1216 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1217 if (parent != null && parent.id == userId && testUserId != userId) {
1218 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1219 + "): attempting unlock because parent was just unlocked");
1220 maybeUnlockUser(testUserId);
1221 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001222 }
1223
Jeff Sharkeyba512352015-11-12 20:17:45 -08001224 return true;
1225 }
1226
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001227 boolean switchUser(final int targetUserId) {
1228 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001229 int currentUserId = getCurrentUserId();
1230 UserInfo targetUserInfo = getUserInfo(targetUserId);
1231 if (targetUserId == currentUserId) {
1232 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1233 return true;
1234 }
1235 if (targetUserInfo == null) {
1236 Slog.w(TAG, "No user info for user #" + targetUserId);
1237 return false;
1238 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001239 if (!targetUserInfo.supportsSwitchTo()) {
1240 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1241 return false;
1242 }
1243 if (targetUserInfo.isManagedProfile()) {
1244 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1245 return false;
1246 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001247 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001248 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001249 }
1250 if (mUserSwitchUiEnabled) {
1251 UserInfo currentUserInfo = getUserInfo(currentUserId);
1252 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1253 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1254 mUiHandler.sendMessage(mHandler.obtainMessage(
1255 START_USER_SWITCH_UI_MSG, userNames));
1256 } else {
1257 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1258 mHandler.sendMessage(mHandler.obtainMessage(
1259 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1260 }
1261 return true;
1262 }
1263
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001264 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001265 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001266 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1267 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001268 }
1269
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001270 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001271 final int observerCount = mUserSwitchObservers.beginBroadcast();
1272 for (int i = 0; i < observerCount; i++) {
1273 try {
1274 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1275 } catch (RemoteException e) {
1276 // Ignore
1277 }
1278 }
1279 mUserSwitchObservers.finishBroadcast();
1280 }
1281
1282 /** Called on handler thread */
1283 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001284 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001285 final int observerCount = mUserSwitchObservers.beginBroadcast();
1286 for (int i = 0; i < observerCount; i++) {
1287 try {
1288 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1289 } catch (RemoteException e) {
1290 }
1291 }
1292 mUserSwitchObservers.finishBroadcast();
1293 }
1294
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001295 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001296 final int observerCount = mUserSwitchObservers.beginBroadcast();
1297 for (int i = 0; i < observerCount; i++) {
1298 try {
1299 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1300 } catch (RemoteException e) {
1301 // Ignore
1302 }
1303 }
1304 mUserSwitchObservers.finishBroadcast();
1305 }
1306
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001307 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1308 // Never stop system user
1309 if (oldUserId == UserHandle.USER_SYSTEM) {
1310 return;
1311 }
1312 // For now, only check for user restriction. Additional checks can be added here
1313 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1314 oldUserId);
1315 if (!disallowRunInBg) {
1316 return;
1317 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001318 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001319 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1320 + " and related users");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001321 stopUsersLU(oldUserId, false, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001322 }
1323 }
1324
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001325 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001326 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001327 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1328 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1329 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001330 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001331 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1332 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1333 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1334 }
1335 }
1336
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001337 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001338 synchronized (mLock) {
1339 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1340 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1341 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1342 mTimeoutUserSwitchCallbacks = null;
1343 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001344 }
1345 }
1346
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001347 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1348 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001349 final int observerCount = mUserSwitchObservers.beginBroadcast();
1350 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001351 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001352 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001353 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001354 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001355 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001356 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001357 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001358 for (int i = 0; i < observerCount; i++) {
1359 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001360 // Prepend with unique prefix to guarantee that keys are unique
1361 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001362 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001363 curWaitingUserSwitchCallbacks.add(name);
1364 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001365 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1366 @Override
1367 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001368 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001369 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001370 if (delay > USER_SWITCH_TIMEOUT_MS) {
1371 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001372 + " sent result after " + delay + " ms");
1373 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001374 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001375 // Continue switching if all callbacks have been notified and
1376 // user switching session is still valid
1377 if (waitingCallbacksCount.decrementAndGet() == 0
1378 && (curWaitingUserSwitchCallbacks
1379 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001380 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001381 }
1382 }
1383 }
1384 };
1385 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001386 } catch (RemoteException e) {
1387 }
1388 }
1389 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001390 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001391 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001392 }
1393 }
1394 mUserSwitchObservers.finishBroadcast();
1395 }
1396
Andreas Gampee7739b32018-07-20 12:55:36 -07001397 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001398 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001399 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001400 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001401 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001402 oldUserId, newUserId, uss));
1403 }
1404
1405 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001406 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001407 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001408 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001409 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001410 uss.switching = false;
1411 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1412 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1413 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001414 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001415 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001416 }
1417
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001418 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1419 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001420 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001421 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001422 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001423 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001424 }
1425 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001426 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001427 }
1428
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001429 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001430 long ident = Binder.clearCallingIdentity();
1431 try {
1432 Intent intent;
1433 if (oldUserId >= 0) {
1434 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001435 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001436 int count = profiles.size();
1437 for (int i = 0; i < count; i++) {
1438 int profileUserId = profiles.get(i).id;
1439 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1440 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1441 | Intent.FLAG_RECEIVER_FOREGROUND);
1442 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001443 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001444 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1445 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1446 }
1447 }
1448 if (newUserId >= 0) {
1449 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001450 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001451 int count = profiles.size();
1452 for (int i = 0; i < count; i++) {
1453 int profileUserId = profiles.get(i).id;
1454 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1455 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1456 | Intent.FLAG_RECEIVER_FOREGROUND);
1457 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001458 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001459 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1460 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1461 }
1462 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1463 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1464 | Intent.FLAG_RECEIVER_FOREGROUND);
1465 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001466 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001467 null, null, 0, null, null,
1468 new String[] {android.Manifest.permission.MANAGE_USERS},
1469 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1470 UserHandle.USER_ALL);
1471 }
1472 } finally {
1473 Binder.restoreCallingIdentity(ident);
1474 }
1475 }
1476
1477
1478 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1479 int allowMode, String name, String callerPackage) {
1480 final int callingUserId = UserHandle.getUserId(callingUid);
1481 if (callingUserId == userId) {
1482 return userId;
1483 }
1484
1485 // Note that we may be accessing mCurrentUserId outside of a lock...
1486 // shouldn't be a big deal, if this is being called outside
1487 // of a locked context there is intrinsically a race with
1488 // the value the caller will receive and someone else changing it.
1489 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1490 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001491 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001492
1493 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1494 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001495 if (mInjector.isCallerRecents(callingUid)
1496 && callingUserId == getCurrentUserId()
1497 && isSameProfileGroup(callingUserId, targetUserId)) {
1498 // If the caller is Recents and it is running in the current user, we then allow it
1499 // to access its profiles.
1500 allow = true;
1501 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001502 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1503 // If the caller has this permission, they always pass go. And collect $200.
1504 allow = true;
1505 } else if (allowMode == ALLOW_FULL_ONLY) {
1506 // We require full access, sucks to be you.
1507 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001508 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001509 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1510 // If the caller does not have either permission, they are always doomed.
1511 allow = false;
1512 } else if (allowMode == ALLOW_NON_FULL) {
1513 // We are blanket allowing non-full access, you lucky caller!
1514 allow = true;
1515 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1516 // We may or may not allow this depending on whether the two users are
1517 // in the same profile.
1518 allow = isSameProfileGroup(callingUserId, targetUserId);
1519 } else {
1520 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1521 }
1522 if (!allow) {
1523 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1524 // In this case, they would like to just execute as their
1525 // owner user instead of failing.
1526 targetUserId = callingUserId;
1527 } else {
1528 StringBuilder builder = new StringBuilder(128);
1529 builder.append("Permission Denial: ");
1530 builder.append(name);
1531 if (callerPackage != null) {
1532 builder.append(" from ");
1533 builder.append(callerPackage);
1534 }
1535 builder.append(" asks to run as user ");
1536 builder.append(userId);
1537 builder.append(" but is calling from user ");
1538 builder.append(UserHandle.getUserId(callingUid));
1539 builder.append("; this requires ");
1540 builder.append(INTERACT_ACROSS_USERS_FULL);
1541 if (allowMode != ALLOW_FULL_ONLY) {
1542 builder.append(" or ");
1543 builder.append(INTERACT_ACROSS_USERS);
1544 }
1545 String msg = builder.toString();
1546 Slog.w(TAG, msg);
1547 throw new SecurityException(msg);
1548 }
1549 }
1550 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001551 if (!allowAll) {
1552 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001553 }
1554 // Check shell permission
1555 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1556 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1557 throw new SecurityException("Shell does not have permission to access user "
1558 + targetUserId + "\n " + Debug.getCallers(3));
1559 }
1560 }
1561 return targetUserId;
1562 }
1563
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001564 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001565 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001566 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001567 }
1568
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001569 void ensureNotSpecialUser(int userId) {
1570 if (userId >= 0) {
1571 return;
1572 }
1573 throw new IllegalArgumentException("Call does not support special user #" + userId);
1574 }
1575
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001576 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1577 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001578 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001579 != PackageManager.PERMISSION_GRANTED) {
1580 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1581 + Binder.getCallingPid()
1582 + ", uid=" + Binder.getCallingUid()
1583 + " requires " + INTERACT_ACROSS_USERS_FULL;
1584 Slog.w(TAG, msg);
1585 throw new SecurityException(msg);
1586 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001587 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001588 }
1589
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001590 void sendForegroundProfileChanged(int userId) {
1591 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1592 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1593 }
1594
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001595 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1596 mUserSwitchObservers.unregister(observer);
1597 }
1598
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001599 UserState getStartedUserState(int userId) {
1600 synchronized (mLock) {
1601 return mStartedUsers.get(userId);
1602 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001603 }
1604
1605 boolean hasStartedUserState(int userId) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07001606 synchronized (mLock) {
1607 return mStartedUsers.get(userId) != null;
1608 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001609 }
1610
Andreas Gampee7739b32018-07-20 12:55:36 -07001611 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001612 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001613 int num = 0;
1614 for (int i = 0; i < mStartedUsers.size(); i++) {
1615 UserState uss = mStartedUsers.valueAt(i);
1616 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001617 if (uss.state != UserState.STATE_STOPPING
1618 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001619 num++;
1620 }
1621 }
1622 mStartedUserArray = new int[num];
1623 num = 0;
1624 for (int i = 0; i < mStartedUsers.size(); i++) {
1625 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001626 if (uss.state != UserState.STATE_STOPPING
1627 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001628 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001629 }
1630 }
1631 }
1632
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001633 void sendBootCompleted(IIntentReceiver resultTo) {
1634 // Get a copy of mStartedUsers to use outside of lock
1635 SparseArray<UserState> startedUsers;
1636 synchronized (mLock) {
1637 startedUsers = mStartedUsers.clone();
1638 }
1639 for (int i = 0; i < startedUsers.size(); i++) {
1640 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001641 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001642 }
1643 }
1644
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001645 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001646 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001647 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001648 }
1649
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001650 /**
1651 * Refreshes the list of users related to the current user when either a
1652 * user switch happens or when a new related user is started in the
1653 * background.
1654 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001655 private void updateCurrentProfileIds() {
1656 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001657 false /* enabledOnly */);
1658 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1659 for (int i = 0; i < currentProfileIds.length; i++) {
1660 currentProfileIds[i] = profiles.get(i).id;
1661 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001662 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1663 synchronized (mLock) {
1664 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001665
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001666 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001667 for (int i = 0; i < users.size(); i++) {
1668 UserInfo user = users.get(i);
1669 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001670 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001671 }
1672 }
1673 }
1674 }
1675
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001676 int[] getStartedUserArray() {
1677 synchronized (mLock) {
1678 return mStartedUserArray;
1679 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001680 }
1681
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001682 boolean isUserRunning(int userId, int flags) {
1683 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001684 if (state == null) {
1685 return false;
1686 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001687 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001688 return true;
1689 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001690 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001691 switch (state.state) {
1692 case UserState.STATE_BOOTING:
1693 case UserState.STATE_RUNNING_LOCKED:
1694 return true;
1695 default:
1696 return false;
1697 }
1698 }
1699 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1700 switch (state.state) {
1701 case UserState.STATE_RUNNING_UNLOCKING:
1702 case UserState.STATE_RUNNING_UNLOCKED:
1703 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001704 // In the stopping/shutdown state return unlock state of the user key
1705 case UserState.STATE_STOPPING:
1706 case UserState.STATE_SHUTDOWN:
1707 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001708 default:
1709 return false;
1710 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001711 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001712 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001713 switch (state.state) {
1714 case UserState.STATE_RUNNING_UNLOCKED:
1715 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001716 // In the stopping/shutdown state return unlock state of the user key
1717 case UserState.STATE_STOPPING:
1718 case UserState.STATE_SHUTDOWN:
1719 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001720 default:
1721 return false;
1722 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001723 }
1724
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001725 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001726 }
1727
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001728 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001729 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001730 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001731 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001732 != PackageManager.PERMISSION_GRANTED)) {
1733 String msg = "Permission Denial: getCurrentUser() from pid="
1734 + Binder.getCallingPid()
1735 + ", uid=" + Binder.getCallingUid()
1736 + " requires " + INTERACT_ACROSS_USERS;
1737 Slog.w(TAG, msg);
1738 throw new SecurityException(msg);
1739 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001740
1741 // Optimization - if there is no pending user switch, return current id
1742 if (mTargetUserId == UserHandle.USER_NULL) {
1743 return getUserInfo(mCurrentUserId);
1744 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001745 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001746 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001747 }
1748 }
1749
Andreas Gampee7739b32018-07-20 12:55:36 -07001750 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001751 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001752 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001753 return getUserInfo(userId);
1754 }
1755
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001756 int getCurrentOrTargetUserId() {
1757 synchronized (mLock) {
1758 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1759 }
1760 }
1761
Andreas Gampee7739b32018-07-20 12:55:36 -07001762 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001763 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001764 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001765 }
1766
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001767
Andreas Gampee7739b32018-07-20 12:55:36 -07001768 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001769 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001770 return mCurrentUserId;
1771 }
1772
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001773 int getCurrentUserId() {
1774 synchronized (mLock) {
1775 return mCurrentUserId;
1776 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001777 }
1778
Andreas Gampee7739b32018-07-20 12:55:36 -07001779 @GuardedBy("mLock")
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001780 private boolean isCurrentUserLU(int userId) {
1781 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001782 }
1783
1784 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001785 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001786 return ums != null ? ums.getUserIds() : new int[] { 0 };
1787 }
1788
Wale Ogunwale86b74462018-07-02 08:42:43 -07001789 private UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001790 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001791 }
1792
1793 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001794 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001795 }
1796
Makoto Onuki6569c362018-02-27 15:52:01 -08001797 /**
1798 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1799 * IDs. Otherwise return an array whose only element is the given user id.
1800 *
1801 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1802 */
1803 int[] expandUserId(int userId) {
1804 if (userId != UserHandle.USER_ALL) {
1805 return new int[] {userId};
1806 } else {
1807 return getUsers();
1808 }
1809 }
1810
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001811 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001812 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001813 }
1814
Wale Ogunwale86b74462018-07-02 08:42:43 -07001815 private void enforceShellRestriction(String restriction, int userHandle) {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001816 if (Binder.getCallingUid() == SHELL_UID) {
1817 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1818 throw new SecurityException("Shell does not have permission to access user "
1819 + userHandle);
1820 }
1821 }
1822 }
1823
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001824 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001825 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001826 }
1827
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001828 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001829 if (callingUserId == targetUserId) {
1830 return true;
1831 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001832 synchronized (mLock) {
1833 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001834 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001835 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001836 UserInfo.NO_PROFILE_GROUP_ID);
1837 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1838 && callingProfile == targetProfile;
1839 }
1840 }
1841
Tony Mak60f53e62017-12-21 20:03:29 +00001842 boolean isUserOrItsParentRunning(int userId) {
1843 synchronized (mLock) {
1844 if (isUserRunning(userId, 0)) {
1845 return true;
1846 }
1847 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1848 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1849 return false;
1850 }
1851 return isUserRunning(parentUserId, 0);
1852 }
1853 }
1854
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001855 boolean isCurrentProfile(int userId) {
1856 synchronized (mLock) {
1857 return ArrayUtils.contains(mCurrentProfileIds, userId);
1858 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001859 }
1860
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001861 int[] getCurrentProfileIds() {
1862 synchronized (mLock) {
1863 return mCurrentProfileIds;
1864 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001865 }
1866
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001867 void onUserRemoved(int userId) {
1868 synchronized (mLock) {
1869 int size = mUserProfileGroupIds.size();
1870 for (int i = size - 1; i >= 0; i--) {
1871 if (mUserProfileGroupIds.keyAt(i) == userId
1872 || mUserProfileGroupIds.valueAt(i) == userId) {
1873 mUserProfileGroupIds.removeAt(i);
1874
1875 }
1876 }
1877 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1878 }
1879 }
1880
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001881 /**
1882 * Returns whether the given user requires credential entry at this time. This is used to
1883 * intercept activity launches for work apps when the Work Challenge is present.
1884 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001885 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001886 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001887 if (mStartedUsers.get(userId) == null) {
1888 return false;
1889 }
1890 }
Clara Bayarria1771112015-12-18 16:29:18 +00001891 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001892 return false;
1893 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001894 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001895 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001896 }
1897
Tony Mak8c536f92016-03-21 12:20:41 +00001898 boolean isLockScreenDisabled(@UserIdInt int userId) {
1899 return mLockPatternUtils.isLockScreenDisabled(userId);
1900 }
1901
Alex Chau93ae42b2018-01-11 15:10:12 +00001902 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
1903 synchronized (mLock) {
1904 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
1905 }
1906 }
1907
1908 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
1909 synchronized (mLock) {
1910 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
1911 }
1912 }
1913
1914 private String getSwitchingFromSystemUserMessage() {
1915 synchronized (mLock) {
1916 return mSwitchingFromSystemUserMessage;
1917 }
1918 }
1919
1920 private String getSwitchingToSystemUserMessage() {
1921 synchronized (mLock) {
1922 return mSwitchingToSystemUserMessage;
1923 }
1924 }
1925
Yi Jin148d7f42017-11-28 14:23:56 -08001926 void writeToProto(ProtoOutputStream proto, long fieldId) {
1927 synchronized (mLock) {
1928 long token = proto.start(fieldId);
1929 for (int i = 0; i < mStartedUsers.size(); i++) {
1930 UserState uss = mStartedUsers.valueAt(i);
1931 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
1932 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
1933 uss.writeToProto(proto, UserControllerProto.User.STATE);
1934 proto.end(uToken);
1935 }
1936 for (int i = 0; i < mStartedUserArray.length; i++) {
1937 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
1938 }
1939 for (int i = 0; i < mUserLru.size(); i++) {
1940 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
1941 }
1942 if (mUserProfileGroupIds.size() > 0) {
1943 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
1944 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
1945 proto.write(UserControllerProto.UserProfile.USER,
1946 mUserProfileGroupIds.keyAt(i));
1947 proto.write(UserControllerProto.UserProfile.PROFILE,
1948 mUserProfileGroupIds.valueAt(i));
1949 proto.end(uToken);
1950 }
1951 }
1952 proto.end(token);
1953 }
1954 }
1955
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001956 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001957 synchronized (mLock) {
1958 pw.println(" mStartedUsers:");
1959 for (int i = 0; i < mStartedUsers.size(); i++) {
1960 UserState uss = mStartedUsers.valueAt(i);
1961 pw.print(" User #");
1962 pw.print(uss.mHandle.getIdentifier());
1963 pw.print(": ");
1964 uss.dump("", pw);
1965 }
1966 pw.print(" mStartedUserArray: [");
1967 for (int i = 0; i < mStartedUserArray.length; i++) {
1968 if (i > 0)
1969 pw.print(", ");
1970 pw.print(mStartedUserArray[i]);
1971 }
1972 pw.println("]");
1973 pw.print(" mUserLru: [");
1974 for (int i = 0; i < mUserLru.size(); i++) {
1975 if (i > 0)
1976 pw.print(", ");
1977 pw.print(mUserLru.get(i));
1978 }
1979 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001980 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001981 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001982 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001983 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001984 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001985 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001986 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001987 }
1988 }
1989 }
1990 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001991
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001992 public boolean handleMessage(Message msg) {
1993 switch (msg.what) {
1994 case START_USER_SWITCH_FG_MSG:
1995 startUserInForeground(msg.arg1);
1996 break;
1997 case REPORT_USER_SWITCH_MSG:
1998 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1999 break;
2000 case CONTINUE_USER_SWITCH_MSG:
2001 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2002 break;
2003 case USER_SWITCH_TIMEOUT_MSG:
2004 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2005 break;
2006 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
2007 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
2008 break;
2009 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002010 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002011 break;
2012 case SYSTEM_USER_START_MSG:
2013 mInjector.batteryStatsServiceNoteEvent(
2014 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2015 Integer.toString(msg.arg1), msg.arg1);
2016 mInjector.getSystemServiceManager().startUser(msg.arg1);
2017 break;
2018 case SYSTEM_USER_UNLOCK_MSG:
2019 final int userId = msg.arg1;
2020 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08002021 // Loads recents on a worker thread that allows disk I/O
2022 FgThread.getHandler().post(() -> {
2023 mInjector.loadUserRecents(userId);
2024 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002025 finishUserUnlocked((UserState) msg.obj);
2026 break;
2027 case SYSTEM_USER_CURRENT_MSG:
2028 mInjector.batteryStatsServiceNoteEvent(
2029 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2030 Integer.toString(msg.arg2), msg.arg2);
2031 mInjector.batteryStatsServiceNoteEvent(
2032 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2033 Integer.toString(msg.arg1), msg.arg1);
2034
2035 mInjector.getSystemServiceManager().switchUser(msg.arg1);
2036 break;
2037 case FOREGROUND_PROFILE_CHANGED_MSG:
2038 dispatchForegroundProfileChanged(msg.arg1);
2039 break;
2040 case REPORT_USER_SWITCH_COMPLETE_MSG:
2041 dispatchUserSwitchComplete(msg.arg1);
2042 break;
2043 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
2044 dispatchLockedBootComplete(msg.arg1);
2045 break;
2046 case START_USER_SWITCH_UI_MSG:
2047 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2048 break;
2049 }
2050 return false;
2051 }
2052
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002053 private static class UserProgressListener extends IProgressListener.Stub {
2054 private volatile long mUnlockStarted;
2055 @Override
2056 public void onStarted(int id, Bundle extras) throws RemoteException {
2057 Slog.d(TAG, "Started unlocking user " + id);
2058 mUnlockStarted = SystemClock.uptimeMillis();
2059 }
2060
2061 @Override
2062 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2063 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2064 }
2065
2066 @Override
2067 public void onFinished(int id, Bundle extras) throws RemoteException {
2068 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2069
2070 // Report system user unlock time to perf dashboard
2071 if (id == UserHandle.USER_SYSTEM) {
2072 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2073 .logDuration("SystemUserUnlock", unlockTime);
2074 } else {
2075 Slog.d(TAG, "Unlocking user " + id + " took " + unlockTime + " ms");
2076 }
2077 }
2078 };
2079
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002080 @VisibleForTesting
2081 static class Injector {
2082 private final ActivityManagerService mService;
2083 private UserManagerService mUserManager;
2084 private UserManagerInternal mUserManagerInternal;
2085
2086 Injector(ActivityManagerService service) {
2087 mService = service;
2088 }
2089
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002090 protected Handler getHandler(Handler.Callback callback) {
2091 return new Handler(mService.mHandlerThread.getLooper(), callback);
2092 }
2093
2094 protected Handler getUiHandler(Handler.Callback callback) {
2095 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002096 }
2097
2098 protected Context getContext() {
2099 return mService.mContext;
2100 }
2101
2102 protected LockPatternUtils getLockPatternUtils() {
2103 return new LockPatternUtils(getContext());
2104 }
2105
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002106 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002107 IIntentReceiver resultTo, int resultCode, String resultData,
2108 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
2109 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002110 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2111 synchronized (mService) {
2112 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2113 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
2114 ordered, sticky, callingPid, callingUid, userId);
2115 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002116 }
2117
2118 int checkCallingPermission(String permission) {
2119 return mService.checkCallingPermission(permission);
2120 }
2121
2122 WindowManagerService getWindowManager() {
2123 return mService.mWindowManager;
2124 }
2125 void activityManagerOnUserStopped(int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002126 LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002127 }
2128
2129 void systemServiceManagerCleanupUser(int userId) {
2130 mService.mSystemServiceManager.cleanupUser(userId);
2131 }
2132
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002133 protected UserManagerService getUserManager() {
2134 if (mUserManager == null) {
2135 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2136 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2137 }
2138 return mUserManager;
2139 }
2140
2141 UserManagerInternal getUserManagerInternal() {
2142 if (mUserManagerInternal == null) {
2143 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2144 }
2145 return mUserManagerInternal;
2146 }
2147
2148 KeyguardManager getKeyguardManager() {
2149 return mService.mContext.getSystemService(KeyguardManager.class);
2150 }
2151
2152 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2153 mService.mBatteryStatsService.noteEvent(code, name, uid);
2154 }
2155
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002156 boolean isRuntimeRestarted() {
2157 return mService.mSystemServiceManager.isRuntimeRestarted();
2158 }
2159
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002160 SystemServiceManager getSystemServiceManager() {
2161 return mService.mSystemServiceManager;
2162 }
2163
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002164 boolean isFirstBootOrUpgrade() {
2165 IPackageManager pm = AppGlobals.getPackageManager();
2166 try {
2167 return pm.isFirstBoot() || pm.isUpgrade();
2168 } catch (RemoteException e) {
2169 throw e.rethrowFromSystemServer();
2170 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002171 }
2172
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002173 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2174 new PreBootBroadcaster(mService, userId, null, quiet) {
2175 @Override
2176 public void onFinished() {
2177 onFinish.run();
2178 }
2179 }.sendNext();
2180 }
2181
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002182 void activityManagerForceStopPackage(int userId, String reason) {
2183 synchronized (mService) {
2184 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2185 userId, reason);
2186 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002187 };
2188
2189 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2190 boolean exported) {
2191 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2192 }
2193
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002194 protected void startHomeActivity(int userId, String reason) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07002195 mService.mAtmInternal.startHomeActivity(userId, reason);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002196 }
2197
Christopher Tate88dc93f2018-07-27 16:48:37 -07002198 void startUserWidgets(int userId) {
2199 AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
Ralph Nathan1d1e80a2018-08-13 16:08:53 -07002200 if (awm != null) {
2201 awm.unlockUser(userId);
2202 }
Christopher Tate88dc93f2018-07-27 16:48:37 -07002203 }
2204
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002205 void updateUserConfiguration() {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002206 mService.mAtmInternal.updateUserConfiguration();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002207 }
2208
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002209 void clearBroadcastQueueForUser(int userId) {
2210 synchronized (mService) {
2211 mService.clearBroadcastQueueForUserLocked(userId);
2212 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002213 }
2214
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002215 void loadUserRecents(int userId) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002216 mService.mAtmInternal.loadRecentTasksForUser(userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002217 }
2218
2219 void startPersistentApps(int matchFlags) {
2220 mService.startPersistentApps(matchFlags);
2221 }
2222
2223 void installEncryptionUnawareProviders(int userId) {
2224 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002225 }
2226
Alex Chau93ae42b2018-01-11 15:10:12 +00002227 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2228 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002229 Dialog d;
2230 if (!mService.mContext.getPackageManager()
2231 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2232 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002233 true /* above system */, switchingFromSystemUserMessage,
2234 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002235 } else {
2236 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2237 true /* above system */, switchingFromSystemUserMessage,
2238 switchingToSystemUserMessage);
2239 }
2240
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002241 d.show();
2242 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002243
Dianne Hackbornced54392018-02-26 13:07:42 -08002244 void reportGlobalUsageEventLocked(int event) {
2245 synchronized (mService) {
2246 mService.reportGlobalUsageEventLocked(event);
2247 }
2248 }
2249
2250 void reportCurWakefulnessUsageEvent() {
2251 synchronized (mService) {
2252 mService.reportCurWakefulnessUsageEventLocked();
2253 }
2254 }
2255
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002256 void stackSupervisorRemoveUser(int userId) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002257 mService.mAtmInternal.removeUser(userId);
Tony Mak5c2cf032017-04-03 18:38:23 +01002258 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002259
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002260 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002261 return mService.mAtmInternal.switchUser(userId, uss);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002262 }
2263
2264 protected void stackSupervisorResumeFocusedStackTopActivity() {
Wale Ogunwale31913b52018-10-13 08:29:31 -07002265 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002266 }
2267
Charles Heff9b4dff2017-09-22 10:18:37 +01002268 protected void clearAllLockedTasks(String reason) {
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002269 mService.mAtmInternal.clearLockedTasks(reason);
Benjamin Franza83859f2017-07-03 16:34:14 +01002270 }
Tony Make839d702018-01-22 15:34:46 +00002271
2272 protected boolean isCallerRecents(int callingUid) {
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002273 return mService.mAtmInternal.isCallerRecents(callingUid);
Tony Make839d702018-01-22 15:34:46 +00002274 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002275 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002276}