blob: 415a822e3160abbe5e057761fb546b0df952eb56 [file] [log] [blame]
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070021import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
22import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070023import static android.app.ActivityManager.USER_OP_IS_CURRENT;
24import static android.app.ActivityManager.USER_OP_SUCCESS;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070025import static android.os.Process.SHELL_UID;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070026import static android.os.Process.SYSTEM_UID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070027import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
28import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
29import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070030import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
31import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
32import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
33import static com.android.server.am.ActivityManagerService.MY_PID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060034import static com.android.server.am.UserState.STATE_BOOTING;
35import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
36import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
37import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070038
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070039import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000040import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000041import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070042import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080043import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070044import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070045import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070046import android.app.IStopUserCallback;
47import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000048import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080049import android.app.usage.UsageEvents;
Christopher Tate2ec961d2018-07-27 16:48:37 -070050import android.appwidget.AppWidgetManagerInternal;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070051import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070052import android.content.IIntentReceiver;
53import android.content.Intent;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080054import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.content.pm.PackageManager;
56import android.content.pm.UserInfo;
57import android.os.BatteryStats;
58import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060059import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070060import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070061import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070062import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070063import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060064import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070065import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070066import android.os.IUserManager;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -070067import android.os.Looper;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070068import android.os.Message;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070069import android.os.Process;
70import android.os.RemoteCallbackList;
71import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070072import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070073import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070074import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070075import android.os.UserHandle;
76import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010077import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080078import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080079import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070080import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070081import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070082import android.util.IntArray;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070083import android.util.Log;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080084import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070085import android.util.Slog;
86import android.util.SparseArray;
87import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070088import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080089import android.util.proto.ProtoOutputStream;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070090import android.view.Window;
Christopher Tate2ec961d2018-07-27 16:48:37 -070091
Fyodor Kupolov610acda2015-10-19 18:44:07 -070092import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080093import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070094import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070095import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070096import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070097import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000098import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080099import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100100import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700101import com.android.server.SystemServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700102import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700103import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700104
105import java.io.PrintWriter;
106import java.util.ArrayList;
107import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700108import java.util.HashSet;
Alex Chaub6ef8692018-01-09 14:16:36 +0000109import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700110import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600111import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700112import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700113import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700114
115/**
116 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700117 *
118 * <p>This class use {@link #mLock} to synchronize access to internal state. Methods that require
119 * {@link #mLock} to be held should have "LU" suffix in the name.
120 *
121 * <p><strong>Important:</strong> Synchronized code, i.e. one executed inside a synchronized(mLock)
122 * block or inside LU method, should only access internal state of this class or make calls to
123 * other LU methods. Non-LU method calls or calls to external classes are discouraged as they
124 * may cause lock inversion.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700125 */
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700126class UserController implements Handler.Callback {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700127 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600128
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700129 // Amount of time we wait for observers to handle a user switch before
130 // giving up on them and unfreezing the screen.
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700131 static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
132
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700133 // ActivityManager thread message constants
134 static final int REPORT_USER_SWITCH_MSG = 10;
135 static final int CONTINUE_USER_SWITCH_MSG = 20;
136 static final int USER_SWITCH_TIMEOUT_MSG = 30;
137 static final int START_PROFILES_MSG = 40;
138 static final int SYSTEM_USER_START_MSG = 50;
139 static final int SYSTEM_USER_CURRENT_MSG = 60;
140 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
141 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
142 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
143 static final int SYSTEM_USER_UNLOCK_MSG = 100;
144 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
145 static final int START_USER_SWITCH_FG_MSG = 120;
146
147 // UI thread message constants
148 static final int START_USER_SWITCH_UI_MSG = 1000;
149
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700150 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
151 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
152 // when it never calls back.
153 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700154
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700155 /**
156 * Maximum number of users we allow to be running at a time, including system user.
157 *
158 * <p>This parameter only affects how many background users will be stopped when switching to a
159 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
160 *
161 * <p>Note: Current and system user (and their related profiles) are never stopped when
162 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
163 */
164 int mMaxRunningUsers;
165
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700166 // Lock for internal state.
167 private final Object mLock = new Object();
168
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700169 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700170 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700171 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700172
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700173 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700174 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700175 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
176 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
177 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700178 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700179 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700180
181 /**
182 * Which users have been started, so are allowed to run code.
183 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700184 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700185 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800186
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700187 /**
188 * LRU list of history of current users. Most recently current is at the end.
189 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700190 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700191 private final ArrayList<Integer> mUserLru = new ArrayList<>();
192
193 /**
194 * Constant array of the users that are currently started.
195 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700196 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700197 private int[] mStartedUserArray = new int[] { 0 };
198
199 // If there are multiple profiles for the current user, their ids are here
200 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700201 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700202 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700203
204 /**
205 * Mapping from each known user ID to the profile group ID it is associated with.
206 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700207 @GuardedBy("mLock")
208 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700209
210 /**
211 * Registered observers of the user switching mechanics.
212 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700213 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700214 = new RemoteCallbackList<>();
215
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700216 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700217
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700218 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700219 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700220 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700221 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700222 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700223
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700224 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000225 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
226 */
227 @GuardedBy("mLock")
228 private String mSwitchingFromSystemUserMessage;
229
230 /**
231 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
232 */
233 @GuardedBy("mLock")
234 private String mSwitchingToSystemUserMessage;
235
236 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700237 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
238 */
239 @GuardedBy("mLock")
240 private ArraySet<String> mTimeoutUserSwitchCallbacks;
241
Clara Bayarria1771112015-12-18 16:29:18 +0000242 private final LockPatternUtils mLockPatternUtils;
243
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700244 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700245 this(new Injector(service));
246 }
247
248 @VisibleForTesting
249 UserController(Injector injector) {
250 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700251 mHandler = mInjector.getHandler(this);
252 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700253 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800254 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700255 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800256 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700257 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700258 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700259 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700260 }
261
262 void finishUserSwitch(UserState uss) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700263 finishUserBoot(uss);
264 startProfiles();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700265 synchronized (mLock) {
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700266 stopRunningUsersLU(mMaxRunningUsers);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700267 }
268 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700269
Alex Chaub6ef8692018-01-09 14:16:36 +0000270 List<Integer> getRunningUsersLU() {
271 ArrayList<Integer> runningUsers = new ArrayList<>();
272 for (Integer userId : mUserLru) {
273 UserState uss = mStartedUsers.get(userId);
274 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700275 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700276 continue;
277 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000278 if (uss.state == UserState.STATE_STOPPING
279 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700280 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700281 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700282 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000283 if (userId == UserHandle.USER_SYSTEM) {
284 // We only count system user as running when it is not a pure system user.
285 if (UserInfo.isSystemOnly(userId)) {
286 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700287 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000288 }
289 runningUsers.add(userId);
290 }
291 return runningUsers;
292 }
293
294 void stopRunningUsersLU(int maxRunningUsers) {
295 List<Integer> currentlyRunning = getRunningUsersLU();
296 Iterator<Integer> iterator = currentlyRunning.iterator();
297 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
298 Integer userId = iterator.next();
299 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
300 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700301 continue;
302 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000303 if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
304 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700305 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000306 }
307 }
308
309 /**
310 * Returns if more users can be started without stopping currently running users.
311 */
312 boolean canStartMoreUsers() {
313 synchronized (mLock) {
314 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700315 }
316 }
317
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800318 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700319 finishUserBoot(uss, null);
320 }
321
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800322 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700323 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700324
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700325 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700326 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700327 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700328 if (mStartedUsers.get(userId) != uss) {
329 return;
330 }
331 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700332
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700333 // We always walk through all the user lifecycle states to send
334 // consistent developer events. We step into RUNNING_LOCKED here,
335 // but we might immediately step into RUNNING below if the user
336 // storage is already unlocked.
337 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
338 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
339 // Do not report secondary users, runtime restarts or first boot/upgrade
340 if (userId == UserHandle.USER_SYSTEM
341 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
342 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
343 MetricsLogger.histogram(mInjector.getContext(),
344 "framework_locked_boot_completed", uptimeSeconds);
345 final int MAX_UPTIME_SECONDS = 120;
346 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
347 Slog.wtf("SystemServerTiming",
348 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800349 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700350 }
351
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700352 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
353 userId, 0));
354 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
355 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
356 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
357 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
358 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
359 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
360 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
361 }
362
363 // We need to delay unlocking managed profiles until the parent user
364 // is also unlocked.
365 if (mInjector.getUserManager().isManagedProfile(userId)) {
366 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
367 if (parent != null
368 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
369 Slog.d(TAG, "User " + userId + " (parent " + parent.id
370 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600371 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700372 } else {
373 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
374 Slog.d(TAG, "User " + userId + " (parent " + parentId
375 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600376 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700377 } else {
378 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700379 }
380 }
381
382 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600383 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
384 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700385 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600386 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700387 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700388 // Only keep marching forward if user is actually unlocked
389 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700390 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800391 // Do not proceed if unexpected state or a stale user
392 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700393 return;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600394 }
395 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700396 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200397
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700398 // Prepare app storage before we go any further
399 uss.mUnlockProgress.setProgress(5,
400 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200401
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800402 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
403 FgThread.getHandler().post(() -> {
Pavel Grafov634c34e2018-04-10 19:19:01 +0100404 if (!StorageManager.isUserKeyUnlocked(userId)) {
405 Slog.w(TAG, "User key got locked unexpectedly, leaving user locked.");
406 return;
407 }
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800408 mInjector.getUserManager().onBeforeUnlockUser(userId);
409 synchronized (mLock) {
410 // Do not proceed if unexpected state
411 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
412 return;
413 }
414 }
415 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
416
417 uss.mUnlockProgress.setProgress(20);
418
419 // Dispatch unlocked to system services; when fully dispatched,
420 // that calls through to the next "unlocked" phase
421 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
422 .sendToTarget();
423 });
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600424 }
425
426 /**
427 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
428 * {@link UserState#STATE_RUNNING_UNLOCKED}.
429 */
430 void finishUserUnlocked(final UserState uss) {
431 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700432 // Only keep marching forward if user is actually unlocked
433 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700434 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600435 // Bail if we ended up with a stale user
436 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
437
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700438 // Do not proceed if unexpected state
439 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
440 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600441 }
442 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700443 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
444 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700445
446 // Get unaware persistent apps running and start any unaware providers
447 // in already-running apps that are partially aware
448 if (userId == UserHandle.USER_SYSTEM) {
449 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
450 }
451 mInjector.installEncryptionUnawareProviders(userId);
452
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700453 // Dispatch unlocked to external apps
454 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
455 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
456 unlockedIntent.addFlags(
457 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
458 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
459 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
460 userId);
461
462 if (getUserInfo(userId).isManagedProfile()) {
463 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
464 if (parent != null) {
465 final Intent profileUnlockedIntent = new Intent(
466 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
467 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
468 profileUnlockedIntent.addFlags(
469 Intent.FLAG_RECEIVER_REGISTERED_ONLY
470 | Intent.FLAG_RECEIVER_FOREGROUND);
471 mInjector.broadcastIntent(profileUnlockedIntent,
472 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
473 null, false, false, MY_PID, SYSTEM_UID,
474 parent.id);
475 }
476 }
477
478 // Send PRE_BOOT broadcasts if user fingerprint changed; we
479 // purposefully block sending BOOT_COMPLETED until after all
480 // PRE_BOOT receivers are finished to avoid ANR'ing apps
481 final UserInfo info = getUserInfo(userId);
482 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
483 // Suppress double notifications for managed profiles that
484 // were unlocked automatically as part of their parent user
485 // being unlocked.
486 final boolean quiet;
487 if (info.isManagedProfile()) {
488 quiet = !uss.tokenProvided
489 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
490 } else {
491 quiet = false;
492 }
493 mInjector.sendPreBootBroadcast(userId, quiet,
494 () -> finishUserUnlockedCompleted(uss));
495 } else {
496 finishUserUnlockedCompleted(uss);
497 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600498 }
499
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600500 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600501 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700502 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600503 // Bail if we ended up with a stale user
504 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700505 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700506 UserInfo userInfo = getUserInfo(userId);
507 if (userInfo == null) {
508 return;
509 }
510 // Only keep marching forward if user is actually unlocked
511 if (!StorageManager.isUserKeyUnlocked(userId)) return;
512
513 // Remember that we logged in
514 mInjector.getUserManager().onUserLoggedIn(userId);
515
516 if (!userInfo.isInitialized()) {
517 if (userId != UserHandle.USER_SYSTEM) {
518 Slog.d(TAG, "Initializing user #" + userId);
519 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
520 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
521 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
522 mInjector.broadcastIntent(intent, null,
523 new IIntentReceiver.Stub() {
524 @Override
525 public void performReceive(Intent intent, int resultCode,
526 String data, Bundle extras, boolean ordered,
527 boolean sticky, int sendingUser) {
528 // Note: performReceive is called with mService lock held
529 mInjector.getUserManager().makeInitialized(userInfo.id);
530 }
531 }, 0, null, null, null, AppOpsManager.OP_NONE,
532 null, true, false, MY_PID, SYSTEM_UID, userId);
533 }
534 }
535
Christopher Tate2ec961d2018-07-27 16:48:37 -0700536 // Spin up app widgets prior to boot-complete, so they can be ready promptly
537 mInjector.startUserWidgets(userId);
538
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700539 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
540 // Do not report secondary users, runtime restarts or first boot/upgrade
541 if (userId == UserHandle.USER_SYSTEM
542 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
543 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
544 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
545 uptimeSeconds);
546 }
547 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
548 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
549 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
550 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
551 mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
552 @Override
553 public void performReceive(Intent intent, int resultCode, String data,
554 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
555 throws RemoteException {
556 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
557 }
558 }, 0, null, null,
559 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
560 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700561 }
562
Andrew Scull85a63bc2016-10-24 13:47:47 +0100563 int restartUser(final int userId, final boolean foreground) {
564 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
565 @Override
566 public void userStopped(final int userId) {
567 // Post to the same handler that this callback is called from to ensure the user
568 // cleanup is complete before restarting.
569 mHandler.post(() -> startUser(userId, foreground));
570 }
571 @Override
572 public void userStopAborted(final int userId) {}
573 });
574 }
575
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700576 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700577 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700578 != PackageManager.PERMISSION_GRANTED) {
579 String msg = "Permission Denial: switchUser() from pid="
580 + Binder.getCallingPid()
581 + ", uid=" + Binder.getCallingUid()
582 + " requires " + INTERACT_ACROSS_USERS_FULL;
583 Slog.w(TAG, msg);
584 throw new SecurityException(msg);
585 }
586 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
587 throw new IllegalArgumentException("Can't stop system user " + userId);
588 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700589 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700590 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700591 return stopUsersLU(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700592 }
593 }
594
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700595 /**
596 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700597 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700598 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700599 private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700600 if (userId == UserHandle.USER_SYSTEM) {
601 return USER_OP_ERROR_IS_SYSTEM;
602 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700603 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700604 return USER_OP_IS_CURRENT;
605 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700606 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700607 // If one of related users is system or current, no related users should be stopped
608 for (int i = 0; i < usersToStop.length; i++) {
609 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700610 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700611 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
612 + relatedUserId);
613 // We still need to stop the requested user if it's a force stop.
614 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800615 Slog.i(TAG,
616 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700617 stopSingleUserLU(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800618 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700619 }
620 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
621 }
622 }
623 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
624 for (int userIdToStop : usersToStop) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700625 stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700626 }
627 return USER_OP_SUCCESS;
628 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700629
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700630 private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700631 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700632 final UserState uss = mStartedUsers.get(userId);
633 if (uss == null) {
634 // User is not started, nothing to do... but we do need to
635 // callback if requested.
636 if (callback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700637 mHandler.post(() -> {
638 try {
639 callback.userStopped(userId);
640 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700641 }
642 });
643 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700644 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700645 }
646
647 if (callback != null) {
648 uss.mStopCallbacks.add(callback);
649 }
650
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700651 if (uss.state != UserState.STATE_STOPPING
652 && uss.state != UserState.STATE_SHUTDOWN) {
653 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700654 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700655 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700656
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700657 // Post to handler to obtain amLock
658 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700659 // We are going to broadcast ACTION_USER_STOPPING and then
660 // once that is done send a final ACTION_SHUTDOWN and then
661 // stop the user.
662 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
663 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
664 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
665 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700666 // This is the result receiver for the initial stopping broadcast.
667 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
668 @Override
669 public void performReceive(Intent intent, int resultCode, String data,
670 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700671 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700672 }
673 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700674
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700675 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700676 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700677 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700678 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700679 null, stoppingReceiver, 0, null, null,
680 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700681 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700682 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700683 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700684 }
685
Amith Yamasani98c05562016-03-30 13:15:26 -0700686 void finishUserStopping(final int userId, final UserState uss) {
687 // On to the next.
688 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
689 // This is the result receiver for the final shutdown broadcast.
690 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
691 @Override
692 public void performReceive(Intent intent, int resultCode, String data,
693 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
694 mHandler.post(new Runnable() {
695 @Override
696 public void run() {
697 finishUserStopped(uss);
698 }
699 });
700 }
701 };
702
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700703 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700704 if (uss.state != UserState.STATE_STOPPING) {
705 // Whoops, we are being started back up. Abort, abort!
706 return;
707 }
708 uss.setState(UserState.STATE_SHUTDOWN);
709 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700710 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700711
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700712 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700713 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
714 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700715 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700716
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700717 mInjector.broadcastIntent(shutdownIntent,
718 null, shutdownReceiver, 0, null, null, null,
719 AppOpsManager.OP_NONE,
720 null, true, false, MY_PID, SYSTEM_UID, userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700721 }
722
723 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700724 final int userId = uss.mHandle.getIdentifier();
Pavel Grafov634c34e2018-04-10 19:19:01 +0100725 final boolean stopped;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700727 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700728 callbacks = new ArrayList<>(uss.mStopCallbacks);
Pavel Grafov634c34e2018-04-10 19:19:01 +0100729 if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700730 stopped = false;
731 } else {
732 stopped = true;
733 // User can no longer run.
734 mStartedUsers.remove(userId);
735 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700736 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700737 }
738 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100739
740 if (stopped) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700741 mInjector.getUserManagerInternal().removeUserState(userId);
742 mInjector.activityManagerOnUserStopped(userId);
743 // Clean up all state and processes associated with the user.
744 // Kill all the processes for the user.
745 forceStopUser(userId, "finish user");
746 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700747
748 for (int i = 0; i < callbacks.size(); i++) {
749 try {
750 if (stopped) callbacks.get(i).userStopped(userId);
751 else callbacks.get(i).userStopAborted(userId);
752 } catch (RemoteException e) {
753 }
754 }
755
756 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700757 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700758 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100759 // Remove the user if it is ephemeral.
760 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000761 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100762 }
Pavel Grafov634c34e2018-04-10 19:19:01 +0100763
764 // Evict the user's credential encryption key. Performed on FgThread to make it
765 // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
766 // to prevent data corruption.
767 FgThread.getHandler().post(() -> {
768 synchronized (mLock) {
769 if (mStartedUsers.get(userId) != null) {
770 Slog.w(TAG, "User was restarted, skipping key eviction");
771 return;
772 }
773 }
774 try {
775 getStorageManager().lockUserKey(userId);
776 } catch (RemoteException re) {
777 throw re.rethrowAsRuntimeException();
778 }
779 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700780 }
781 }
782
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700783 /**
784 * Determines the list of users that should be stopped together with the specified
785 * {@code userId}. The returned list includes {@code userId}.
786 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700787 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700788 int startedUsersSize = mStartedUsers.size();
789 IntArray userIds = new IntArray();
790 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700791 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
792 for (int i = 0; i < startedUsersSize; i++) {
793 UserState uss = mStartedUsers.valueAt(i);
794 int startedUserId = uss.mHandle.getIdentifier();
795 // Skip unrelated users (profileGroupId mismatch)
796 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700797 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700798 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
799 && (userGroupId == startedUserGroupId);
800 // userId has already been added
801 boolean sameUserId = startedUserId == userId;
802 if (!sameGroup || sameUserId) {
803 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700804 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700805 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700806 }
807 return userIds.toArray();
808 }
809
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700810 private void forceStopUser(int userId, String reason) {
811 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700812 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
813 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
814 | Intent.FLAG_RECEIVER_FOREGROUND);
815 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700816 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700817 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700818 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700819 }
820
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700821 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100822 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700823 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000824 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
825 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000826 synchronized(mLock) {
827 UserState oldUss = mStartedUsers.get(oldUserId);
828 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
829 || oldUss.state == UserState.STATE_STOPPING
830 || oldUss.state == UserState.STATE_SHUTDOWN) {
831 return;
832 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700833 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000834
835 UserInfo userInfo = getUserInfo(oldUserId);
836 if (userInfo.isEphemeral()) {
837 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
838 }
839 if (userInfo.isGuest() || userInfo.isEphemeral()) {
840 // This is a user to be stopped.
841 synchronized (mLock) {
842 stopUsersLU(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700843 }
844 }
845 }
846
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700847 void scheduleStartProfiles() {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700848 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
849 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
850 DateUtils.SECOND_IN_MILLIS);
851 }
852 }
853
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700854 void startProfiles() {
855 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700856 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700857 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700858 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700859 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
860 for (UserInfo user : profiles) {
861 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700862 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700863 profilesToStart.add(user);
864 }
865 }
866 final int profilesToStartSize = profilesToStart.size();
867 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700868 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700869 startUser(profilesToStart.get(i).id, /* foreground= */ false);
870 }
871 if (i < profilesToStartSize) {
872 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
873 }
874 }
875
Sudheer Shanka2250d562016-11-07 15:41:02 -0800876 private IStorageManager getStorageManager() {
877 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700878 }
Tony Mak64fd8c02017-12-01 19:11:59 +0000879 boolean startUser(final int userId, final boolean foreground) {
880 return startUser(userId, foreground, null);
881 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700882
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700883 /**
884 * Start user, if its not already running.
885 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
886 * When starting the user, multiple intents will be broadcast in the following order:</p>
887 * <ul>
888 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
889 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
890 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
891 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
892 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
893 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
894 * Sent only if {@code foreground} parameter is true
895 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
896 * of the new fg user
897 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
898 * the new user
899 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
900 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
901 * new user. Sent only when the user is booting after a system update.
902 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
903 * new user. Sent only the first time a user is starting.
904 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
905 * user. Indicates that the user has finished booting.
906 * </ul>
907 *
908 * @param userId ID of the user to start
909 * @param foreground true if user should be brought to the foreground
910 * @return true if the user has been successfully started
911 */
Tony Mak64fd8c02017-12-01 19:11:59 +0000912 boolean startUser(
913 final int userId,
914 final boolean foreground,
915 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700916 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700917 != PackageManager.PERMISSION_GRANTED) {
918 String msg = "Permission Denial: switchUser() from pid="
919 + Binder.getCallingPid()
920 + ", uid=" + Binder.getCallingUid()
921 + " requires " + INTERACT_ACROSS_USERS_FULL;
922 Slog.w(TAG, msg);
923 throw new SecurityException(msg);
924 }
925
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700926 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700927
928 final long ident = Binder.clearCallingIdentity();
929 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700930 final int oldUserId = getCurrentUserId();
931 if (oldUserId == userId) {
932 return true;
933 }
934
935 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100936 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700937 }
938
939 final UserInfo userInfo = getUserInfo(userId);
940 if (userInfo == null) {
941 Slog.w(TAG, "No user info for user #" + userId);
942 return false;
943 }
944 if (foreground && userInfo.isManagedProfile()) {
945 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
946 return false;
947 }
948
949 if (foreground && mUserSwitchUiEnabled) {
950 mInjector.getWindowManager().startFreezingScreen(
951 R.anim.screen_user_exit, R.anim.screen_user_enter);
952 }
953
954 boolean needStart = false;
955 boolean updateUmState = false;
956 UserState uss;
957
958 // If the user we are switching to is not currently started, then
959 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700960 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700961 uss = mStartedUsers.get(userId);
962 if (uss == null) {
963 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700964 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700965 mStartedUsers.put(userId, uss);
966 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700967 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700968 updateUmState = true;
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -0700969 } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
970 Slog.i(TAG, "User #" + userId
971 + " is shutting down - will start after full stop");
972 mHandler.post(() -> startUser(userId, foreground, unlockListener));
973 return true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700974 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700975 final Integer userIdInt = userId;
976 mUserLru.remove(userIdInt);
977 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +0000978 }
979 if (unlockListener != null) {
980 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700981 }
982 if (updateUmState) {
983 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
984 }
985 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -0800986 // Make sure the old user is no longer considering the display to be on.
987 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700988 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700989 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700990 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700991 }
992 mInjector.updateUserConfiguration();
993 updateCurrentProfileIds();
994 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -0800995 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700996 // Once the internal notion of the active user has switched, we lock the device
997 // with the option to show the user switcher on the keyguard.
998 if (mUserSwitchUiEnabled) {
999 mInjector.getWindowManager().setSwitchingUser(true);
1000 mInjector.getWindowManager().lockNow(null);
1001 }
1002 } else {
1003 final Integer currentUserIdInt = mCurrentUserId;
1004 updateCurrentProfileIds();
1005 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
1006 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001007 mUserLru.remove(currentUserIdInt);
1008 mUserLru.add(currentUserIdInt);
1009 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001010 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001011
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001012 // Make sure user is in the started state. If it is currently
1013 // stopping, we need to knock that off.
1014 if (uss.state == UserState.STATE_STOPPING) {
1015 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
1016 // so we can just fairly silently bring the user back from
1017 // the almost-dead.
1018 uss.setState(uss.lastState);
1019 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1020 synchronized (mLock) {
1021 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001022 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001023 needStart = true;
1024 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1025 // This means ACTION_SHUTDOWN has been sent, so we will
1026 // need to treat this as a new boot of the user.
1027 uss.setState(UserState.STATE_BOOTING);
1028 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1029 synchronized (mLock) {
1030 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001031 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001032 needStart = true;
1033 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001034
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001035 if (uss.state == UserState.STATE_BOOTING) {
1036 // Give user manager a chance to propagate user restrictions
1037 // to other services and prepare app storage
1038 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001039
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001040 // Booting up a new user, need to tell system services about it.
1041 // Note that this is on the same handler as scheduling of broadcasts,
1042 // which is important because it needs to go first.
1043 mHandler.sendMessage(
1044 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1045 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001046
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001047 if (foreground) {
1048 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1049 oldUserId));
1050 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1051 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1052 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1053 oldUserId, userId, uss));
1054 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1055 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1056 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001057
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001058 if (needStart) {
1059 // Send USER_STARTED broadcast
1060 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1062 | Intent.FLAG_RECEIVER_FOREGROUND);
1063 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1064 mInjector.broadcastIntent(intent,
1065 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1066 null, false, false, MY_PID, SYSTEM_UID, userId);
1067 }
1068
1069 if (foreground) {
1070 moveUserToForeground(uss, oldUserId, userId);
1071 } else {
1072 finishUserBoot(uss);
1073 }
1074
1075 if (needStart) {
1076 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1077 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1078 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1079 mInjector.broadcastIntent(intent,
1080 null, new IIntentReceiver.Stub() {
1081 @Override
1082 public void performReceive(Intent intent, int resultCode,
1083 String data, Bundle extras, boolean ordered,
1084 boolean sticky,
1085 int sendingUser) throws RemoteException {
1086 }
1087 }, 0, null, null,
1088 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
1089 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001090 }
1091 } finally {
1092 Binder.restoreCallingIdentity(ident);
1093 }
1094
1095 return true;
1096 }
1097
Fyodor Kupolov3d4b5c92018-04-30 18:49:34 -07001098 private boolean isCallingOnHandlerThread() {
1099 return Looper.myLooper() == mHandler.getLooper();
1100 }
1101
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001102 /**
1103 * Start user, if its not already running, and bring it to foreground.
1104 */
Evan Rosky18396452016-07-27 15:19:37 -07001105 void startUserInForeground(final int targetUserId) {
1106 boolean success = startUser(targetUserId, /* foreground */ true);
1107 if (!success) {
1108 mInjector.getWindowManager().setSwitchingUser(false);
1109 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001110 }
1111
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001112 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001113 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001114 != PackageManager.PERMISSION_GRANTED) {
1115 String msg = "Permission Denial: unlockUser() from pid="
1116 + Binder.getCallingPid()
1117 + ", uid=" + Binder.getCallingUid()
1118 + " requires " + INTERACT_ACROSS_USERS_FULL;
1119 Slog.w(TAG, msg);
1120 throw new SecurityException(msg);
1121 }
1122
Jeff Sharkey8924e872015-11-30 12:52:10 -07001123 final long binderToken = Binder.clearCallingIdentity();
1124 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001125 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001126 } finally {
1127 Binder.restoreCallingIdentity(binderToken);
1128 }
1129 }
1130
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001131 /**
1132 * Attempt to unlock user without a credential token. This typically
1133 * succeeds when the device doesn't have credential-encrypted storage, or
1134 * when the the credential-encrypted storage isn't tied to a user-provided
1135 * PIN or pattern.
1136 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001137 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001138 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001139 return unlockUserCleared(userId, null, null, null);
1140 }
1141
1142 private static void notifyFinished(int userId, IProgressListener listener) {
1143 if (listener == null) return;
1144 try {
1145 listener.onFinished(userId, null);
1146 } catch (RemoteException ignored) {
1147 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001148 }
1149
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001150 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001151 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001152 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001153 if (!StorageManager.isUserKeyUnlocked(userId)) {
1154 final UserInfo userInfo = getUserInfo(userId);
1155 final IStorageManager storageManager = getStorageManager();
1156 try {
1157 // We always want to unlock user storage, even user is not started yet
1158 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1159 } catch (RemoteException | RuntimeException e) {
1160 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001161 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001162 }
1163 synchronized (mLock) {
1164 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001165 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001166 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001167 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001168 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001169 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001170 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001171 // Bail if user isn't actually running
1172 if (uss == null) {
1173 notifyFinished(userId, listener);
1174 return false;
1175 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001176
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001177 finishUserUnlocking(uss);
1178
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001179 // We just unlocked a user, so let's now attempt to unlock any
1180 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001181
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001182 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1183 int[] userIds;
1184 synchronized (mLock) {
1185 userIds = new int[mStartedUsers.size()];
1186 for (int i = 0; i < userIds.length; i++) {
1187 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001188 }
1189 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001190 for (int testUserId : userIds) {
1191 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1192 if (parent != null && parent.id == userId && testUserId != userId) {
1193 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1194 + "): attempting unlock because parent was just unlocked");
1195 maybeUnlockUser(testUserId);
1196 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001197 }
1198
Jeff Sharkeyba512352015-11-12 20:17:45 -08001199 return true;
1200 }
1201
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001202 boolean switchUser(final int targetUserId) {
1203 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001204 int currentUserId = getCurrentUserId();
1205 UserInfo targetUserInfo = getUserInfo(targetUserId);
1206 if (targetUserId == currentUserId) {
1207 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1208 return true;
1209 }
1210 if (targetUserInfo == null) {
1211 Slog.w(TAG, "No user info for user #" + targetUserId);
1212 return false;
1213 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001214 if (!targetUserInfo.supportsSwitchTo()) {
1215 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1216 return false;
1217 }
1218 if (targetUserInfo.isManagedProfile()) {
1219 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1220 return false;
1221 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001222 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001223 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001224 }
1225 if (mUserSwitchUiEnabled) {
1226 UserInfo currentUserInfo = getUserInfo(currentUserId);
1227 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1228 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1229 mUiHandler.sendMessage(mHandler.obtainMessage(
1230 START_USER_SWITCH_UI_MSG, userNames));
1231 } else {
1232 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1233 mHandler.sendMessage(mHandler.obtainMessage(
1234 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1235 }
1236 return true;
1237 }
1238
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001239 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001240 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001241 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1242 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001243 }
1244
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001245 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001246 final int observerCount = mUserSwitchObservers.beginBroadcast();
1247 for (int i = 0; i < observerCount; i++) {
1248 try {
1249 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1250 } catch (RemoteException e) {
1251 // Ignore
1252 }
1253 }
1254 mUserSwitchObservers.finishBroadcast();
1255 }
1256
1257 /** Called on handler thread */
1258 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001259 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001260 final int observerCount = mUserSwitchObservers.beginBroadcast();
1261 for (int i = 0; i < observerCount; i++) {
1262 try {
1263 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1264 } catch (RemoteException e) {
1265 }
1266 }
1267 mUserSwitchObservers.finishBroadcast();
1268 }
1269
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001270 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001271 final int observerCount = mUserSwitchObservers.beginBroadcast();
1272 for (int i = 0; i < observerCount; i++) {
1273 try {
1274 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1275 } catch (RemoteException e) {
1276 // Ignore
1277 }
1278 }
1279 mUserSwitchObservers.finishBroadcast();
1280 }
1281
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001282 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1283 // Never stop system user
1284 if (oldUserId == UserHandle.USER_SYSTEM) {
1285 return;
1286 }
1287 // For now, only check for user restriction. Additional checks can be added here
1288 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1289 oldUserId);
1290 if (!disallowRunInBg) {
1291 return;
1292 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001293 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001294 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1295 + " and related users");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001296 stopUsersLU(oldUserId, false, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001297 }
1298 }
1299
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001300 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001301 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001302 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1303 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1304 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001305 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001306 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1307 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1308 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1309 }
1310 }
1311
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001312 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001313 synchronized (mLock) {
1314 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1315 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1316 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1317 mTimeoutUserSwitchCallbacks = null;
1318 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001319 }
1320 }
1321
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001322 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1323 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001324 final int observerCount = mUserSwitchObservers.beginBroadcast();
1325 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001326 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001327 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001328 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001329 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001330 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001331 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001332 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001333 for (int i = 0; i < observerCount; i++) {
1334 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001335 // Prepend with unique prefix to guarantee that keys are unique
1336 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001337 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001338 curWaitingUserSwitchCallbacks.add(name);
1339 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001340 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1341 @Override
1342 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001343 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001344 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001345 if (delay > USER_SWITCH_TIMEOUT_MS) {
1346 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001347 + " sent result after " + delay + " ms");
1348 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001349 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001350 // Continue switching if all callbacks have been notified and
1351 // user switching session is still valid
1352 if (waitingCallbacksCount.decrementAndGet() == 0
1353 && (curWaitingUserSwitchCallbacks
1354 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001355 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001356 }
1357 }
1358 }
1359 };
1360 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001361 } catch (RemoteException e) {
1362 }
1363 }
1364 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001365 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001366 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001367 }
1368 }
1369 mUserSwitchObservers.finishBroadcast();
1370 }
1371
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001372 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001373 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001374 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001375 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001376 oldUserId, newUserId, uss));
1377 }
1378
1379 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001380 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001381 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001382 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001383 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001384 uss.switching = false;
1385 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1386 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1387 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001388 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001389 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001390 }
1391
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001392 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1393 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001394 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001395 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001396 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001397 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001398 }
1399 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001400 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001401 }
1402
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001403 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001404 long ident = Binder.clearCallingIdentity();
1405 try {
1406 Intent intent;
1407 if (oldUserId >= 0) {
1408 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001409 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001410 int count = profiles.size();
1411 for (int i = 0; i < count; i++) {
1412 int profileUserId = profiles.get(i).id;
1413 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1415 | Intent.FLAG_RECEIVER_FOREGROUND);
1416 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001417 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001418 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1419 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1420 }
1421 }
1422 if (newUserId >= 0) {
1423 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001424 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001425 int count = profiles.size();
1426 for (int i = 0; i < count; i++) {
1427 int profileUserId = profiles.get(i).id;
1428 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1430 | Intent.FLAG_RECEIVER_FOREGROUND);
1431 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001432 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001433 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1434 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1435 }
1436 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1438 | Intent.FLAG_RECEIVER_FOREGROUND);
1439 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001440 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001441 null, null, 0, null, null,
1442 new String[] {android.Manifest.permission.MANAGE_USERS},
1443 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1444 UserHandle.USER_ALL);
1445 }
1446 } finally {
1447 Binder.restoreCallingIdentity(ident);
1448 }
1449 }
1450
1451
1452 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1453 int allowMode, String name, String callerPackage) {
1454 final int callingUserId = UserHandle.getUserId(callingUid);
1455 if (callingUserId == userId) {
1456 return userId;
1457 }
1458
1459 // Note that we may be accessing mCurrentUserId outside of a lock...
1460 // shouldn't be a big deal, if this is being called outside
1461 // of a locked context there is intrinsically a race with
1462 // the value the caller will receive and someone else changing it.
1463 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1464 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001465 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001466
1467 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1468 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001469 if (mInjector.isCallerRecents(callingUid)
1470 && callingUserId == getCurrentUserId()
1471 && isSameProfileGroup(callingUserId, targetUserId)) {
1472 // If the caller is Recents and it is running in the current user, we then allow it
1473 // to access its profiles.
1474 allow = true;
1475 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001476 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1477 // If the caller has this permission, they always pass go. And collect $200.
1478 allow = true;
1479 } else if (allowMode == ALLOW_FULL_ONLY) {
1480 // We require full access, sucks to be you.
1481 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001482 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001483 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1484 // If the caller does not have either permission, they are always doomed.
1485 allow = false;
1486 } else if (allowMode == ALLOW_NON_FULL) {
1487 // We are blanket allowing non-full access, you lucky caller!
1488 allow = true;
1489 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1490 // We may or may not allow this depending on whether the two users are
1491 // in the same profile.
1492 allow = isSameProfileGroup(callingUserId, targetUserId);
1493 } else {
1494 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1495 }
1496 if (!allow) {
1497 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1498 // In this case, they would like to just execute as their
1499 // owner user instead of failing.
1500 targetUserId = callingUserId;
1501 } else {
1502 StringBuilder builder = new StringBuilder(128);
1503 builder.append("Permission Denial: ");
1504 builder.append(name);
1505 if (callerPackage != null) {
1506 builder.append(" from ");
1507 builder.append(callerPackage);
1508 }
1509 builder.append(" asks to run as user ");
1510 builder.append(userId);
1511 builder.append(" but is calling from user ");
1512 builder.append(UserHandle.getUserId(callingUid));
1513 builder.append("; this requires ");
1514 builder.append(INTERACT_ACROSS_USERS_FULL);
1515 if (allowMode != ALLOW_FULL_ONLY) {
1516 builder.append(" or ");
1517 builder.append(INTERACT_ACROSS_USERS);
1518 }
1519 String msg = builder.toString();
1520 Slog.w(TAG, msg);
1521 throw new SecurityException(msg);
1522 }
1523 }
1524 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001525 if (!allowAll) {
1526 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001527 }
1528 // Check shell permission
1529 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1530 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1531 throw new SecurityException("Shell does not have permission to access user "
1532 + targetUserId + "\n " + Debug.getCallers(3));
1533 }
1534 }
1535 return targetUserId;
1536 }
1537
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001538 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001539 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001540 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001541 }
1542
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001543 void ensureNotSpecialUser(int userId) {
1544 if (userId >= 0) {
1545 return;
1546 }
1547 throw new IllegalArgumentException("Call does not support special user #" + userId);
1548 }
1549
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001550 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1551 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001552 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001553 != PackageManager.PERMISSION_GRANTED) {
1554 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1555 + Binder.getCallingPid()
1556 + ", uid=" + Binder.getCallingUid()
1557 + " requires " + INTERACT_ACROSS_USERS_FULL;
1558 Slog.w(TAG, msg);
1559 throw new SecurityException(msg);
1560 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001561 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001562 }
1563
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001564 void sendForegroundProfileChanged(int userId) {
1565 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1566 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1567 }
1568
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001569 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1570 mUserSwitchObservers.unregister(observer);
1571 }
1572
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001573 UserState getStartedUserState(int userId) {
1574 synchronized (mLock) {
1575 return mStartedUsers.get(userId);
1576 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001577 }
1578
1579 boolean hasStartedUserState(int userId) {
1580 return mStartedUsers.get(userId) != null;
1581 }
1582
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001583 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001584 int num = 0;
1585 for (int i = 0; i < mStartedUsers.size(); i++) {
1586 UserState uss = mStartedUsers.valueAt(i);
1587 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001588 if (uss.state != UserState.STATE_STOPPING
1589 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001590 num++;
1591 }
1592 }
1593 mStartedUserArray = new int[num];
1594 num = 0;
1595 for (int i = 0; i < mStartedUsers.size(); i++) {
1596 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001597 if (uss.state != UserState.STATE_STOPPING
1598 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001599 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001600 }
1601 }
1602 }
1603
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001604 void sendBootCompleted(IIntentReceiver resultTo) {
1605 // Get a copy of mStartedUsers to use outside of lock
1606 SparseArray<UserState> startedUsers;
1607 synchronized (mLock) {
1608 startedUsers = mStartedUsers.clone();
1609 }
1610 for (int i = 0; i < startedUsers.size(); i++) {
1611 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001612 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001613 }
1614 }
1615
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001616 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001617 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001618 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001619 }
1620
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001621 /**
1622 * Refreshes the list of users related to the current user when either a
1623 * user switch happens or when a new related user is started in the
1624 * background.
1625 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001626 private void updateCurrentProfileIds() {
1627 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001628 false /* enabledOnly */);
1629 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1630 for (int i = 0; i < currentProfileIds.length; i++) {
1631 currentProfileIds[i] = profiles.get(i).id;
1632 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001633 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1634 synchronized (mLock) {
1635 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001636
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001637 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001638 for (int i = 0; i < users.size(); i++) {
1639 UserInfo user = users.get(i);
1640 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001641 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001642 }
1643 }
1644 }
1645 }
1646
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001647 int[] getStartedUserArray() {
1648 synchronized (mLock) {
1649 return mStartedUserArray;
1650 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001651 }
1652
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001653 boolean isUserRunning(int userId, int flags) {
1654 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001655 if (state == null) {
1656 return false;
1657 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001658 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001659 return true;
1660 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001661 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001662 switch (state.state) {
1663 case UserState.STATE_BOOTING:
1664 case UserState.STATE_RUNNING_LOCKED:
1665 return true;
1666 default:
1667 return false;
1668 }
1669 }
1670 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1671 switch (state.state) {
1672 case UserState.STATE_RUNNING_UNLOCKING:
1673 case UserState.STATE_RUNNING_UNLOCKED:
1674 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001675 // In the stopping/shutdown state return unlock state of the user key
1676 case UserState.STATE_STOPPING:
1677 case UserState.STATE_SHUTDOWN:
1678 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001679 default:
1680 return false;
1681 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001682 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001683 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001684 switch (state.state) {
1685 case UserState.STATE_RUNNING_UNLOCKED:
1686 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001687 // In the stopping/shutdown state return unlock state of the user key
1688 case UserState.STATE_STOPPING:
1689 case UserState.STATE_SHUTDOWN:
1690 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001691 default:
1692 return false;
1693 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001694 }
1695
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001696 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001697 }
1698
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001699 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001700 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001701 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001702 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001703 != PackageManager.PERMISSION_GRANTED)) {
1704 String msg = "Permission Denial: getCurrentUser() from pid="
1705 + Binder.getCallingPid()
1706 + ", uid=" + Binder.getCallingUid()
1707 + " requires " + INTERACT_ACROSS_USERS;
1708 Slog.w(TAG, msg);
1709 throw new SecurityException(msg);
1710 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001711
1712 // Optimization - if there is no pending user switch, return current id
1713 if (mTargetUserId == UserHandle.USER_NULL) {
1714 return getUserInfo(mCurrentUserId);
1715 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001716 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001717 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001718 }
1719 }
1720
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001721 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001722 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001723 return getUserInfo(userId);
1724 }
1725
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001726 int getCurrentOrTargetUserId() {
1727 synchronized (mLock) {
1728 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1729 }
1730 }
1731
1732 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001733 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001734 }
1735
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001736
1737 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001738 return mCurrentUserId;
1739 }
1740
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001741 int getCurrentUserId() {
1742 synchronized (mLock) {
1743 return mCurrentUserId;
1744 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001745 }
1746
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001747 private boolean isCurrentUserLU(int userId) {
1748 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001749 }
1750
1751 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001752 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001753 return ums != null ? ums.getUserIds() : new int[] { 0 };
1754 }
1755
1756 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001757 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001758 }
1759
1760 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001761 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001762 }
1763
Makoto Onuki6569c362018-02-27 15:52:01 -08001764 /**
1765 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1766 * IDs. Otherwise return an array whose only element is the given user id.
1767 *
1768 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1769 */
1770 int[] expandUserId(int userId) {
1771 if (userId != UserHandle.USER_ALL) {
1772 return new int[] {userId};
1773 } else {
1774 return getUsers();
1775 }
1776 }
1777
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001778 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001779 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001780 }
1781
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001782 void enforceShellRestriction(String restriction, int userHandle) {
1783 if (Binder.getCallingUid() == SHELL_UID) {
1784 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1785 throw new SecurityException("Shell does not have permission to access user "
1786 + userHandle);
1787 }
1788 }
1789 }
1790
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001791 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001792 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001793 }
1794
1795 Set<Integer> getProfileIds(int userId) {
1796 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001797 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001798 false /* enabledOnly */);
1799 for (UserInfo user : profiles) {
1800 userIds.add(user.id);
1801 }
1802 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001803 }
1804
1805 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001806 if (callingUserId == targetUserId) {
1807 return true;
1808 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001809 synchronized (mLock) {
1810 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001811 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001812 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001813 UserInfo.NO_PROFILE_GROUP_ID);
1814 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1815 && callingProfile == targetProfile;
1816 }
1817 }
1818
Tony Mak60f53e62017-12-21 20:03:29 +00001819 boolean isUserOrItsParentRunning(int userId) {
1820 synchronized (mLock) {
1821 if (isUserRunning(userId, 0)) {
1822 return true;
1823 }
1824 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1825 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1826 return false;
1827 }
1828 return isUserRunning(parentUserId, 0);
1829 }
1830 }
1831
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001832 boolean isCurrentProfile(int userId) {
1833 synchronized (mLock) {
1834 return ArrayUtils.contains(mCurrentProfileIds, userId);
1835 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001836 }
1837
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001838 int[] getCurrentProfileIds() {
1839 synchronized (mLock) {
1840 return mCurrentProfileIds;
1841 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001842 }
1843
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001844 void onUserRemoved(int userId) {
1845 synchronized (mLock) {
1846 int size = mUserProfileGroupIds.size();
1847 for (int i = size - 1; i >= 0; i--) {
1848 if (mUserProfileGroupIds.keyAt(i) == userId
1849 || mUserProfileGroupIds.valueAt(i) == userId) {
1850 mUserProfileGroupIds.removeAt(i);
1851
1852 }
1853 }
1854 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1855 }
1856 }
1857
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001858 /**
1859 * Returns whether the given user requires credential entry at this time. This is used to
1860 * intercept activity launches for work apps when the Work Challenge is present.
1861 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001862 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001863 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001864 if (mStartedUsers.get(userId) == null) {
1865 return false;
1866 }
1867 }
Clara Bayarria1771112015-12-18 16:29:18 +00001868 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001869 return false;
1870 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001871 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001872 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001873 }
1874
Tony Mak8c536f92016-03-21 12:20:41 +00001875 boolean isLockScreenDisabled(@UserIdInt int userId) {
1876 return mLockPatternUtils.isLockScreenDisabled(userId);
1877 }
1878
Alex Chau93ae42b2018-01-11 15:10:12 +00001879 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
1880 synchronized (mLock) {
1881 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
1882 }
1883 }
1884
1885 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
1886 synchronized (mLock) {
1887 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
1888 }
1889 }
1890
1891 private String getSwitchingFromSystemUserMessage() {
1892 synchronized (mLock) {
1893 return mSwitchingFromSystemUserMessage;
1894 }
1895 }
1896
1897 private String getSwitchingToSystemUserMessage() {
1898 synchronized (mLock) {
1899 return mSwitchingToSystemUserMessage;
1900 }
1901 }
1902
Yi Jin148d7f42017-11-28 14:23:56 -08001903 void writeToProto(ProtoOutputStream proto, long fieldId) {
1904 synchronized (mLock) {
1905 long token = proto.start(fieldId);
1906 for (int i = 0; i < mStartedUsers.size(); i++) {
1907 UserState uss = mStartedUsers.valueAt(i);
1908 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
1909 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
1910 uss.writeToProto(proto, UserControllerProto.User.STATE);
1911 proto.end(uToken);
1912 }
1913 for (int i = 0; i < mStartedUserArray.length; i++) {
1914 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
1915 }
1916 for (int i = 0; i < mUserLru.size(); i++) {
1917 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
1918 }
1919 if (mUserProfileGroupIds.size() > 0) {
1920 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
1921 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
1922 proto.write(UserControllerProto.UserProfile.USER,
1923 mUserProfileGroupIds.keyAt(i));
1924 proto.write(UserControllerProto.UserProfile.PROFILE,
1925 mUserProfileGroupIds.valueAt(i));
1926 proto.end(uToken);
1927 }
1928 }
1929 proto.end(token);
1930 }
1931 }
1932
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001933 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001934 synchronized (mLock) {
1935 pw.println(" mStartedUsers:");
1936 for (int i = 0; i < mStartedUsers.size(); i++) {
1937 UserState uss = mStartedUsers.valueAt(i);
1938 pw.print(" User #");
1939 pw.print(uss.mHandle.getIdentifier());
1940 pw.print(": ");
1941 uss.dump("", pw);
1942 }
1943 pw.print(" mStartedUserArray: [");
1944 for (int i = 0; i < mStartedUserArray.length; i++) {
1945 if (i > 0)
1946 pw.print(", ");
1947 pw.print(mStartedUserArray[i]);
1948 }
1949 pw.println("]");
1950 pw.print(" mUserLru: [");
1951 for (int i = 0; i < mUserLru.size(); i++) {
1952 if (i > 0)
1953 pw.print(", ");
1954 pw.print(mUserLru.get(i));
1955 }
1956 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001957 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001958 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001959 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001960 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001961 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001962 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001963 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001964 }
1965 }
1966 }
1967 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001968
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001969 public boolean handleMessage(Message msg) {
1970 switch (msg.what) {
1971 case START_USER_SWITCH_FG_MSG:
1972 startUserInForeground(msg.arg1);
1973 break;
1974 case REPORT_USER_SWITCH_MSG:
1975 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1976 break;
1977 case CONTINUE_USER_SWITCH_MSG:
1978 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1979 break;
1980 case USER_SWITCH_TIMEOUT_MSG:
1981 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1982 break;
1983 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
1984 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
1985 break;
1986 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001987 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001988 break;
1989 case SYSTEM_USER_START_MSG:
1990 mInjector.batteryStatsServiceNoteEvent(
1991 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1992 Integer.toString(msg.arg1), msg.arg1);
1993 mInjector.getSystemServiceManager().startUser(msg.arg1);
1994 break;
1995 case SYSTEM_USER_UNLOCK_MSG:
1996 final int userId = msg.arg1;
1997 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08001998 // Loads recents on a worker thread that allows disk I/O
1999 FgThread.getHandler().post(() -> {
2000 mInjector.loadUserRecents(userId);
2001 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002002 finishUserUnlocked((UserState) msg.obj);
2003 break;
2004 case SYSTEM_USER_CURRENT_MSG:
2005 mInjector.batteryStatsServiceNoteEvent(
2006 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2007 Integer.toString(msg.arg2), msg.arg2);
2008 mInjector.batteryStatsServiceNoteEvent(
2009 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2010 Integer.toString(msg.arg1), msg.arg1);
2011
2012 mInjector.getSystemServiceManager().switchUser(msg.arg1);
2013 break;
2014 case FOREGROUND_PROFILE_CHANGED_MSG:
2015 dispatchForegroundProfileChanged(msg.arg1);
2016 break;
2017 case REPORT_USER_SWITCH_COMPLETE_MSG:
2018 dispatchUserSwitchComplete(msg.arg1);
2019 break;
2020 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
2021 dispatchLockedBootComplete(msg.arg1);
2022 break;
2023 case START_USER_SWITCH_UI_MSG:
2024 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2025 break;
2026 }
2027 return false;
2028 }
2029
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002030 private static class UserProgressListener extends IProgressListener.Stub {
2031 private volatile long mUnlockStarted;
2032 @Override
2033 public void onStarted(int id, Bundle extras) throws RemoteException {
2034 Slog.d(TAG, "Started unlocking user " + id);
2035 mUnlockStarted = SystemClock.uptimeMillis();
2036 }
2037
2038 @Override
2039 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2040 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2041 }
2042
2043 @Override
2044 public void onFinished(int id, Bundle extras) throws RemoteException {
2045 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2046
2047 // Report system user unlock time to perf dashboard
2048 if (id == UserHandle.USER_SYSTEM) {
2049 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2050 .logDuration("SystemUserUnlock", unlockTime);
2051 } else {
2052 Slog.d(TAG, "Unlocking user " + id + " took " + unlockTime + " ms");
2053 }
2054 }
2055 };
2056
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002057 @VisibleForTesting
2058 static class Injector {
2059 private final ActivityManagerService mService;
2060 private UserManagerService mUserManager;
2061 private UserManagerInternal mUserManagerInternal;
2062
2063 Injector(ActivityManagerService service) {
2064 mService = service;
2065 }
2066
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002067 protected Handler getHandler(Handler.Callback callback) {
2068 return new Handler(mService.mHandlerThread.getLooper(), callback);
2069 }
2070
2071 protected Handler getUiHandler(Handler.Callback callback) {
2072 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002073 }
2074
2075 protected Context getContext() {
2076 return mService.mContext;
2077 }
2078
2079 protected LockPatternUtils getLockPatternUtils() {
2080 return new LockPatternUtils(getContext());
2081 }
2082
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002083 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002084 IIntentReceiver resultTo, int resultCode, String resultData,
2085 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
2086 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002087 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2088 synchronized (mService) {
2089 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2090 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
2091 ordered, sticky, callingPid, callingUid, userId);
2092 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002093 }
2094
2095 int checkCallingPermission(String permission) {
2096 return mService.checkCallingPermission(permission);
2097 }
2098
2099 WindowManagerService getWindowManager() {
2100 return mService.mWindowManager;
2101 }
2102 void activityManagerOnUserStopped(int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002103 synchronized (mService) {
2104 mService.onUserStoppedLocked(userId);
2105 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002106 }
2107
2108 void systemServiceManagerCleanupUser(int userId) {
2109 mService.mSystemServiceManager.cleanupUser(userId);
2110 }
2111
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002112 protected UserManagerService getUserManager() {
2113 if (mUserManager == null) {
2114 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2115 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2116 }
2117 return mUserManager;
2118 }
2119
2120 UserManagerInternal getUserManagerInternal() {
2121 if (mUserManagerInternal == null) {
2122 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2123 }
2124 return mUserManagerInternal;
2125 }
2126
2127 KeyguardManager getKeyguardManager() {
2128 return mService.mContext.getSystemService(KeyguardManager.class);
2129 }
2130
2131 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2132 mService.mBatteryStatsService.noteEvent(code, name, uid);
2133 }
2134
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002135 boolean isRuntimeRestarted() {
2136 return mService.mSystemServiceManager.isRuntimeRestarted();
2137 }
2138
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002139 SystemServiceManager getSystemServiceManager() {
2140 return mService.mSystemServiceManager;
2141 }
2142
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002143 boolean isFirstBootOrUpgrade() {
2144 IPackageManager pm = AppGlobals.getPackageManager();
2145 try {
2146 return pm.isFirstBoot() || pm.isUpgrade();
2147 } catch (RemoteException e) {
2148 throw e.rethrowFromSystemServer();
2149 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002150 }
2151
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002152 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2153 new PreBootBroadcaster(mService, userId, null, quiet) {
2154 @Override
2155 public void onFinished() {
2156 onFinish.run();
2157 }
2158 }.sendNext();
2159 }
2160
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002161 void activityManagerForceStopPackage(int userId, String reason) {
2162 synchronized (mService) {
2163 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2164 userId, reason);
2165 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002166 };
2167
2168 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2169 boolean exported) {
2170 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2171 }
2172
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002173 protected void startHomeActivity(int userId, String reason) {
2174 synchronized (mService) {
2175 mService.startHomeActivityLocked(userId, reason);
2176 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002177 }
2178
Christopher Tate2ec961d2018-07-27 16:48:37 -07002179 void startUserWidgets(int userId) {
2180 AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
2181 if (awm != null) {
2182 awm.unlockUser(userId);
2183 }
2184 }
2185
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002186 void updateUserConfiguration() {
2187 synchronized (mService) {
2188 mService.updateUserConfigurationLocked();
2189 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002190 }
2191
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002192 void clearBroadcastQueueForUser(int userId) {
2193 synchronized (mService) {
2194 mService.clearBroadcastQueueForUserLocked(userId);
2195 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002196 }
2197
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002198 void loadUserRecents(int userId) {
2199 synchronized (mService) {
Winson Chung3f0e59a2017-10-25 10:19:05 -07002200 mService.getRecentTasks().loadUserRecentsLocked(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002201 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002202 }
2203
2204 void startPersistentApps(int matchFlags) {
2205 mService.startPersistentApps(matchFlags);
2206 }
2207
2208 void installEncryptionUnawareProviders(int userId) {
2209 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002210 }
2211
Alex Chau93ae42b2018-01-11 15:10:12 +00002212 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2213 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002214 Dialog d;
2215 if (!mService.mContext.getPackageManager()
2216 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2217 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002218 true /* above system */, switchingFromSystemUserMessage,
2219 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002220 } else {
2221 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2222 true /* above system */, switchingFromSystemUserMessage,
2223 switchingToSystemUserMessage);
2224 }
2225
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002226 d.show();
2227 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002228
Dianne Hackbornced54392018-02-26 13:07:42 -08002229 void reportGlobalUsageEventLocked(int event) {
2230 synchronized (mService) {
2231 mService.reportGlobalUsageEventLocked(event);
2232 }
2233 }
2234
2235 void reportCurWakefulnessUsageEvent() {
2236 synchronized (mService) {
2237 mService.reportCurWakefulnessUsageEventLocked();
2238 }
2239 }
2240
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002241 void stackSupervisorRemoveUser(int userId) {
2242 synchronized (mService) {
2243 mService.mStackSupervisor.removeUserLocked(userId);
2244 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002245 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002246
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002247 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
2248 synchronized (mService) {
2249 return mService.mStackSupervisor.switchUserLocked(userId, uss);
2250 }
2251 }
2252
2253 protected void stackSupervisorResumeFocusedStackTopActivity() {
2254 synchronized (mService) {
2255 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
2256 }
2257 }
2258
Charles Heff9b4dff2017-09-22 10:18:37 +01002259 protected void clearAllLockedTasks(String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002260 synchronized (mService) {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002261 mService.getLockTaskController().clearLockedTasks(reason);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002262 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002263 }
Tony Make839d702018-01-22 15:34:46 +00002264
2265 protected boolean isCallerRecents(int callingUid) {
2266 return mService.getRecentTasks().isCallerRecents(callingUid);
2267 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002268 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002269}