blob: 060d4c8497ddabbdfabdfa2738d9e633950e1af2 [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;
Tony Mak64fd8c02017-12-01 19:11:59 +000027
Fyodor Kupolov610acda2015-10-19 18:44:07 -070028import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
29import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
30import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070031import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
32import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
33import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
34import static com.android.server.am.ActivityManagerService.MY_PID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060035import static com.android.server.am.UserState.STATE_BOOTING;
36import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
37import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
38import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070039
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070040import android.annotation.NonNull;
Tony Mak64fd8c02017-12-01 19:11:59 +000041import android.annotation.Nullable;
Tony Mak8c536f92016-03-21 12:20:41 +000042import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070043import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080044import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070045import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070046import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070047import android.app.IStopUserCallback;
48import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000049import android.app.KeyguardManager;
Dianne Hackbornced54392018-02-26 13:07:42 -080050import android.app.usage.UsageEvents;
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 Kupolov58e732d2017-09-12 17:35:41 -070067import android.os.Message;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070068import android.os.Process;
69import android.os.RemoteCallbackList;
70import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070071import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070072import android.os.SystemClock;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070073import android.os.Trace;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070074import android.os.UserHandle;
75import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010076import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080077import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080078import android.os.storage.StorageManager;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -070079import android.text.format.DateUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070080import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070081import android.util.IntArray;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070082import android.util.Log;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080083import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070084import android.util.Slog;
85import android.util.SparseArray;
86import android.util.SparseIntArray;
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -070087import android.util.TimingsTraceLog;
Yi Jin148d7f42017-11-28 14:23:56 -080088import android.util.proto.ProtoOutputStream;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070089
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070090import android.view.Window;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070091import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080092import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070093import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070094import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070095import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070096import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000097import com.android.internal.widget.LockPatternUtils;
Fyodor Kupolov4c72df02017-11-14 11:43:40 -080098import com.android.server.FgThread;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010099import com.android.server.LocalServices;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700100import com.android.server.SystemServiceManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700101import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700102import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700103
104import java.io.PrintWriter;
105import java.util.ArrayList;
106import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700107import java.util.HashSet;
Alex Chaub6ef8692018-01-09 14:16:36 +0000108import java.util.Iterator;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700109import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600110import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700111import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700112import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700113
114/**
115 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700116 *
117 * <p>This class use {@link #mLock} to synchronize access to internal state. Methods that require
118 * {@link #mLock} to be held should have "LU" suffix in the name.
119 *
120 * <p><strong>Important:</strong> Synchronized code, i.e. one executed inside a synchronized(mLock)
121 * block or inside LU method, should only access internal state of this class or make calls to
122 * other LU methods. Non-LU method calls or calls to external classes are discouraged as they
123 * may cause lock inversion.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700124 */
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700125class UserController implements Handler.Callback {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700126 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600127
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700128 // Amount of time we wait for observers to handle a user switch before
129 // giving up on them and unfreezing the screen.
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700130 static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
131
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700132 // ActivityManager thread message constants
133 static final int REPORT_USER_SWITCH_MSG = 10;
134 static final int CONTINUE_USER_SWITCH_MSG = 20;
135 static final int USER_SWITCH_TIMEOUT_MSG = 30;
136 static final int START_PROFILES_MSG = 40;
137 static final int SYSTEM_USER_START_MSG = 50;
138 static final int SYSTEM_USER_CURRENT_MSG = 60;
139 static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
140 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
141 static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
142 static final int SYSTEM_USER_UNLOCK_MSG = 100;
143 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
144 static final int START_USER_SWITCH_FG_MSG = 120;
145
146 // UI thread message constants
147 static final int START_USER_SWITCH_UI_MSG = 1000;
148
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700149 // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
150 // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
151 // when it never calls back.
152 private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700153
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700154 /**
155 * Maximum number of users we allow to be running at a time, including system user.
156 *
157 * <p>This parameter only affects how many background users will be stopped when switching to a
158 * new user. It has no impact on {@link #startUser(int, boolean)} behavior.
159 *
160 * <p>Note: Current and system user (and their related profiles) are never stopped when
161 * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers
162 */
163 int mMaxRunningUsers;
164
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700165 // Lock for internal state.
166 private final Object mLock = new Object();
167
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700168 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700169 private final Handler mHandler;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700170 private final Handler mUiHandler;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700171
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700172 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700173 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700174 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
175 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
176 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700177 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700178 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700179
180 /**
181 * Which users have been started, so are allowed to run code.
182 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700183 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700184 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800185
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700186 /**
187 * LRU list of history of current users. Most recently current is at the end.
188 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700189 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700190 private final ArrayList<Integer> mUserLru = new ArrayList<>();
191
192 /**
193 * Constant array of the users that are currently started.
194 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700195 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700196 private int[] mStartedUserArray = new int[] { 0 };
197
198 // If there are multiple profiles for the current user, their ids are here
199 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700200 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700201 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700202
203 /**
204 * Mapping from each known user ID to the profile group ID it is associated with.
205 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700206 @GuardedBy("mLock")
207 private final SparseIntArray mUserProfileGroupIds = new SparseIntArray();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700208
209 /**
210 * Registered observers of the user switching mechanics.
211 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700212 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700213 = new RemoteCallbackList<>();
214
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700215 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700216
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700217 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700218 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700219 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700220 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700221 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700222
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700223 /**
Alex Chau93ae42b2018-01-11 15:10:12 +0000224 * Messages for for switching from {@link android.os.UserHandle#SYSTEM}.
225 */
226 @GuardedBy("mLock")
227 private String mSwitchingFromSystemUserMessage;
228
229 /**
230 * Messages for for switching to {@link android.os.UserHandle#SYSTEM}.
231 */
232 @GuardedBy("mLock")
233 private String mSwitchingToSystemUserMessage;
234
235 /**
Fyodor Kupolov807e6502017-08-21 16:07:14 -0700236 * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
237 */
238 @GuardedBy("mLock")
239 private ArraySet<String> mTimeoutUserSwitchCallbacks;
240
Clara Bayarria1771112015-12-18 16:29:18 +0000241 private final LockPatternUtils mLockPatternUtils;
242
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700243 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700244 this(new Injector(service));
245 }
246
247 @VisibleForTesting
248 UserController(Injector injector) {
249 mInjector = injector;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700250 mHandler = mInjector.getHandler(this);
251 mUiHandler = mInjector.getUiHandler(this);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700252 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800253 final UserState uss = new UserState(UserHandle.SYSTEM);
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700254 uss.mUnlockProgress.addListener(new UserProgressListener());
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800255 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700256 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700257 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700258 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700259 }
260
261 void finishUserSwitch(UserState uss) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700262 finishUserBoot(uss);
263 startProfiles();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700264 synchronized (mLock) {
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700265 stopRunningUsersLU(mMaxRunningUsers);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700266 }
267 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700268
Alex Chaub6ef8692018-01-09 14:16:36 +0000269 List<Integer> getRunningUsersLU() {
270 ArrayList<Integer> runningUsers = new ArrayList<>();
271 for (Integer userId : mUserLru) {
272 UserState uss = mStartedUsers.get(userId);
273 if (uss == null) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700274 // Shouldn't happen, but be sane if it does.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700275 continue;
276 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000277 if (uss.state == UserState.STATE_STOPPING
278 || uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700279 // This user is already stopping, doesn't count.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700280 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700281 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000282 if (userId == UserHandle.USER_SYSTEM) {
283 // We only count system user as running when it is not a pure system user.
284 if (UserInfo.isSystemOnly(userId)) {
285 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700286 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000287 }
288 runningUsers.add(userId);
289 }
290 return runningUsers;
291 }
292
293 void stopRunningUsersLU(int maxRunningUsers) {
294 List<Integer> currentlyRunning = getRunningUsersLU();
295 Iterator<Integer> iterator = currentlyRunning.iterator();
296 while (currentlyRunning.size() > maxRunningUsers && iterator.hasNext()) {
297 Integer userId = iterator.next();
298 if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUserId) {
299 // Owner/System user and current user can't be stopped
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700300 continue;
301 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000302 if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
303 iterator.remove();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700304 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000305 }
306 }
307
308 /**
309 * Returns if more users can be started without stopping currently running users.
310 */
311 boolean canStartMoreUsers() {
312 synchronized (mLock) {
313 return getRunningUsersLU().size() < mMaxRunningUsers;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700314 }
315 }
316
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800317 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700318 finishUserBoot(uss, null);
319 }
320
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800321 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700322 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700323
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700324 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700325 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700326 // Bail if we ended up with a stale user
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700327 if (mStartedUsers.get(userId) != uss) {
328 return;
329 }
330 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700331
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700332 // We always walk through all the user lifecycle states to send
333 // consistent developer events. We step into RUNNING_LOCKED here,
334 // but we might immediately step into RUNNING below if the user
335 // storage is already unlocked.
336 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
337 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
338 // Do not report secondary users, runtime restarts or first boot/upgrade
339 if (userId == UserHandle.USER_SYSTEM
340 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
341 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
342 MetricsLogger.histogram(mInjector.getContext(),
343 "framework_locked_boot_completed", uptimeSeconds);
344 final int MAX_UPTIME_SECONDS = 120;
345 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
346 Slog.wtf("SystemServerTiming",
347 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800348 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700349 }
350
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700351 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
352 userId, 0));
353 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
354 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
355 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
356 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
357 mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
358 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
359 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
360 }
361
362 // We need to delay unlocking managed profiles until the parent user
363 // is also unlocked.
364 if (mInjector.getUserManager().isManagedProfile(userId)) {
365 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
366 if (parent != null
367 && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
368 Slog.d(TAG, "User " + userId + " (parent " + parent.id
369 + "): attempting unlock because parent is unlocked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600370 maybeUnlockUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700371 } else {
372 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
373 Slog.d(TAG, "User " + userId + " (parent " + parentId
374 + "): delaying unlock because parent is locked");
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600375 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700376 } else {
377 maybeUnlockUser(userId);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700378 }
379 }
380
381 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600382 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
383 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700384 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600385 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700386 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700387 // Only keep marching forward if user is actually unlocked
388 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700389 synchronized (mLock) {
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800390 // Do not proceed if unexpected state or a stale user
391 if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700392 return;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600393 }
394 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700395 uss.mUnlockProgress.start();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200396
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700397 // Prepare app storage before we go any further
398 uss.mUnlockProgress.setProgress(5,
399 mInjector.getContext().getString(R.string.android_start_title));
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200400
Fyodor Kupolov4c72df02017-11-14 11:43:40 -0800401 // Call onBeforeUnlockUser on a worker thread that allows disk I/O
402 FgThread.getHandler().post(() -> {
403 mInjector.getUserManager().onBeforeUnlockUser(userId);
404 synchronized (mLock) {
405 // Do not proceed if unexpected state
406 if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
407 return;
408 }
409 }
410 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
411
412 uss.mUnlockProgress.setProgress(20);
413
414 // Dispatch unlocked to system services; when fully dispatched,
415 // that calls through to the next "unlocked" phase
416 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
417 .sendToTarget();
418 });
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600419 }
420
421 /**
422 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
423 * {@link UserState#STATE_RUNNING_UNLOCKED}.
424 */
425 void finishUserUnlocked(final UserState uss) {
426 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700427 // Only keep marching forward if user is actually unlocked
428 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700429 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600430 // Bail if we ended up with a stale user
431 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
432
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700433 // Do not proceed if unexpected state
434 if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
435 return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600436 }
437 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700438 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
439 uss.mUnlockProgress.finish();
Jeff Sharkey26b0f352018-02-19 16:30:17 -0700440
441 // Get unaware persistent apps running and start any unaware providers
442 // in already-running apps that are partially aware
443 if (userId == UserHandle.USER_SYSTEM) {
444 mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
445 }
446 mInjector.installEncryptionUnawareProviders(userId);
447
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700448 // Dispatch unlocked to external apps
449 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
450 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
451 unlockedIntent.addFlags(
452 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
453 mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
454 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
455 userId);
456
457 if (getUserInfo(userId).isManagedProfile()) {
458 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
459 if (parent != null) {
460 final Intent profileUnlockedIntent = new Intent(
461 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
462 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
463 profileUnlockedIntent.addFlags(
464 Intent.FLAG_RECEIVER_REGISTERED_ONLY
465 | Intent.FLAG_RECEIVER_FOREGROUND);
466 mInjector.broadcastIntent(profileUnlockedIntent,
467 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
468 null, false, false, MY_PID, SYSTEM_UID,
469 parent.id);
470 }
471 }
472
473 // Send PRE_BOOT broadcasts if user fingerprint changed; we
474 // purposefully block sending BOOT_COMPLETED until after all
475 // PRE_BOOT receivers are finished to avoid ANR'ing apps
476 final UserInfo info = getUserInfo(userId);
477 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
478 // Suppress double notifications for managed profiles that
479 // were unlocked automatically as part of their parent user
480 // being unlocked.
481 final boolean quiet;
482 if (info.isManagedProfile()) {
483 quiet = !uss.tokenProvided
484 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
485 } else {
486 quiet = false;
487 }
488 mInjector.sendPreBootBroadcast(userId, quiet,
489 () -> finishUserUnlockedCompleted(uss));
490 } else {
491 finishUserUnlockedCompleted(uss);
492 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600493 }
494
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600495 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600496 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700497 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600498 // Bail if we ended up with a stale user
499 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700500 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700501 UserInfo userInfo = getUserInfo(userId);
502 if (userInfo == null) {
503 return;
504 }
505 // Only keep marching forward if user is actually unlocked
506 if (!StorageManager.isUserKeyUnlocked(userId)) return;
507
508 // Remember that we logged in
509 mInjector.getUserManager().onUserLoggedIn(userId);
510
511 if (!userInfo.isInitialized()) {
512 if (userId != UserHandle.USER_SYSTEM) {
513 Slog.d(TAG, "Initializing user #" + userId);
514 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
515 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
516 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
517 mInjector.broadcastIntent(intent, null,
518 new IIntentReceiver.Stub() {
519 @Override
520 public void performReceive(Intent intent, int resultCode,
521 String data, Bundle extras, boolean ordered,
522 boolean sticky, int sendingUser) {
523 // Note: performReceive is called with mService lock held
524 mInjector.getUserManager().makeInitialized(userInfo.id);
525 }
526 }, 0, null, null, null, AppOpsManager.OP_NONE,
527 null, true, false, MY_PID, SYSTEM_UID, userId);
528 }
529 }
530
531 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
532 // Do not report secondary users, runtime restarts or first boot/upgrade
533 if (userId == UserHandle.USER_SYSTEM
534 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
535 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
536 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
537 uptimeSeconds);
538 }
539 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
540 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
541 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
542 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
543 mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
544 @Override
545 public void performReceive(Intent intent, int resultCode, String data,
546 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
547 throws RemoteException {
548 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
549 }
550 }, 0, null, null,
551 new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
552 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700553 }
554
Andrew Scull85a63bc2016-10-24 13:47:47 +0100555 int restartUser(final int userId, final boolean foreground) {
556 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
557 @Override
558 public void userStopped(final int userId) {
559 // Post to the same handler that this callback is called from to ensure the user
560 // cleanup is complete before restarting.
561 mHandler.post(() -> startUser(userId, foreground));
562 }
563 @Override
564 public void userStopAborted(final int userId) {}
565 });
566 }
567
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700568 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700569 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700570 != PackageManager.PERMISSION_GRANTED) {
571 String msg = "Permission Denial: switchUser() from pid="
572 + Binder.getCallingPid()
573 + ", uid=" + Binder.getCallingUid()
574 + " requires " + INTERACT_ACROSS_USERS_FULL;
575 Slog.w(TAG, msg);
576 throw new SecurityException(msg);
577 }
578 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
579 throw new IllegalArgumentException("Can't stop system user " + userId);
580 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700581 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700582 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700583 return stopUsersLU(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700584 }
585 }
586
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700587 /**
588 * Stops the user along with its related users. The method calls
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700589 * {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700590 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700591 private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700592 if (userId == UserHandle.USER_SYSTEM) {
593 return USER_OP_ERROR_IS_SYSTEM;
594 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700595 if (isCurrentUserLU(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700596 return USER_OP_IS_CURRENT;
597 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700598 int[] usersToStop = getUsersToStopLU(userId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700599 // If one of related users is system or current, no related users should be stopped
600 for (int i = 0; i < usersToStop.length; i++) {
601 int relatedUserId = usersToStop[i];
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700602 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLU(relatedUserId)) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700603 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
604 + relatedUserId);
605 // We still need to stop the requested user if it's a force stop.
606 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800607 Slog.i(TAG,
608 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700609 stopSingleUserLU(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800610 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700611 }
612 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
613 }
614 }
615 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
616 for (int userIdToStop : usersToStop) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700617 stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700618 }
619 return USER_OP_SUCCESS;
620 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700621
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700622 private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700623 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700624 final UserState uss = mStartedUsers.get(userId);
625 if (uss == null) {
626 // User is not started, nothing to do... but we do need to
627 // callback if requested.
628 if (callback != null) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700629 mHandler.post(() -> {
630 try {
631 callback.userStopped(userId);
632 } catch (RemoteException e) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700633 }
634 });
635 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700636 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700637 }
638
639 if (callback != null) {
640 uss.mStopCallbacks.add(callback);
641 }
642
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700643 if (uss.state != UserState.STATE_STOPPING
644 && uss.state != UserState.STATE_SHUTDOWN) {
645 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700646 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700647 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700648
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700649 // Post to handler to obtain amLock
650 mHandler.post(() -> {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700651 // We are going to broadcast ACTION_USER_STOPPING and then
652 // once that is done send a final ACTION_SHUTDOWN and then
653 // stop the user.
654 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
655 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
656 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
657 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700658 // This is the result receiver for the initial stopping broadcast.
659 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
660 @Override
661 public void performReceive(Intent intent, int resultCode, String data,
662 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700663 mHandler.post(() -> finishUserStopping(userId, uss));
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700664 }
665 };
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700666
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700667 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700668 mInjector.clearBroadcastQueueForUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700669 // Kick things off.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700670 mInjector.broadcastIntent(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700671 null, stoppingReceiver, 0, null, null,
672 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700673 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700674 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700675 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700676 }
677
Amith Yamasani98c05562016-03-30 13:15:26 -0700678 void finishUserStopping(final int userId, final UserState uss) {
679 // On to the next.
680 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
681 // This is the result receiver for the final shutdown broadcast.
682 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
683 @Override
684 public void performReceive(Intent intent, int resultCode, String data,
685 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
686 mHandler.post(new Runnable() {
687 @Override
688 public void run() {
689 finishUserStopped(uss);
690 }
691 });
692 }
693 };
694
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700695 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700696 if (uss.state != UserState.STATE_STOPPING) {
697 // Whoops, we are being started back up. Abort, abort!
698 return;
699 }
700 uss.setState(UserState.STATE_SHUTDOWN);
701 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700702 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700703
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700704 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700705 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
706 Integer.toString(userId), userId);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700707 mInjector.getSystemServiceManager().stopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700708
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700709 mInjector.broadcastIntent(shutdownIntent,
710 null, shutdownReceiver, 0, null, null, null,
711 AppOpsManager.OP_NONE,
712 null, true, false, MY_PID, SYSTEM_UID, userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700713 }
714
715 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700716 final int userId = uss.mHandle.getIdentifier();
717 boolean stopped;
718 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700719 boolean forceStopUser = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700720 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700721 callbacks = new ArrayList<>(uss.mStopCallbacks);
722 if (mStartedUsers.get(userId) != uss) {
723 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700724 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700725 stopped = false;
726 } else {
727 stopped = true;
728 // User can no longer run.
729 mStartedUsers.remove(userId);
730 mUserLru.remove(Integer.valueOf(userId));
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700731 updateStartedUserArrayLU();
732 forceStopUser = true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700733 }
734 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700735 if (forceStopUser) {
736 mInjector.getUserManagerInternal().removeUserState(userId);
737 mInjector.activityManagerOnUserStopped(userId);
738 // Clean up all state and processes associated with the user.
739 // Kill all the processes for the user.
740 forceStopUser(userId, "finish user");
741 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700742
743 for (int i = 0; i < callbacks.size(); i++) {
744 try {
745 if (stopped) callbacks.get(i).userStopped(userId);
746 else callbacks.get(i).userStopAborted(userId);
747 } catch (RemoteException e) {
748 }
749 }
750
751 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700752 mInjector.systemServiceManagerCleanupUser(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700753 mInjector.stackSupervisorRemoveUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100754 // Remove the user if it is ephemeral.
755 if (getUserInfo(userId).isEphemeral()) {
Alex Chau1df89812018-02-06 14:41:47 +0000756 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100757 }
Pavel Grafov0502a4c2017-07-27 17:27:35 +0100758 // Evict the user's credential encryption key.
759 try {
760 getStorageManager().lockUserKey(userId);
761 } catch (RemoteException re) {
762 throw re.rethrowAsRuntimeException();
763 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700764 }
765 }
766
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700767 /**
768 * Determines the list of users that should be stopped together with the specified
769 * {@code userId}. The returned list includes {@code userId}.
770 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700771 private @NonNull int[] getUsersToStopLU(int userId) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700772 int startedUsersSize = mStartedUsers.size();
773 IntArray userIds = new IntArray();
774 userIds.add(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700775 int userGroupId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
776 for (int i = 0; i < startedUsersSize; i++) {
777 UserState uss = mStartedUsers.valueAt(i);
778 int startedUserId = uss.mHandle.getIdentifier();
779 // Skip unrelated users (profileGroupId mismatch)
780 int startedUserGroupId = mUserProfileGroupIds.get(startedUserId,
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700781 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700782 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
783 && (userGroupId == startedUserGroupId);
784 // userId has already been added
785 boolean sameUserId = startedUserId == userId;
786 if (!sameGroup || sameUserId) {
787 continue;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700788 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700789 userIds.add(startedUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700790 }
791 return userIds.toArray();
792 }
793
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700794 private void forceStopUser(int userId, String reason) {
795 mInjector.activityManagerForceStopPackage(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700796 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
797 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
798 | Intent.FLAG_RECEIVER_FOREGROUND);
799 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700800 mInjector.broadcastIntent(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700801 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700802 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700803 }
804
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700805 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100806 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700807 */
Alex Chaub6ef8692018-01-09 14:16:36 +0000808 private void stopGuestOrEphemeralUserIfBackground(int oldUserId) {
809 if (DEBUG_MU) Slog.i(TAG, "Stop guest or ephemeral user if background: " + oldUserId);
Alex Chaufbc77172018-01-18 18:43:35 +0000810 synchronized(mLock) {
811 UserState oldUss = mStartedUsers.get(oldUserId);
812 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId || oldUss == null
813 || oldUss.state == UserState.STATE_STOPPING
814 || oldUss.state == UserState.STATE_SHUTDOWN) {
815 return;
816 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700817 }
Alex Chaub6ef8692018-01-09 14:16:36 +0000818
819 UserInfo userInfo = getUserInfo(oldUserId);
820 if (userInfo.isEphemeral()) {
821 LocalServices.getService(UserManagerInternal.class).onEphemeralUserStop(oldUserId);
822 }
823 if (userInfo.isGuest() || userInfo.isEphemeral()) {
824 // This is a user to be stopped.
825 synchronized (mLock) {
826 stopUsersLU(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700827 }
828 }
829 }
830
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700831 void scheduleStartProfiles() {
Fyodor Kupolov58e732d2017-09-12 17:35:41 -0700832 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
833 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
834 DateUtils.SECOND_IN_MILLIS);
835 }
836 }
837
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700838 void startProfiles() {
839 int currentUserId = getCurrentUserId();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700840 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700841 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700842 currentUserId, false /* enabledOnly */);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700843 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
844 for (UserInfo user : profiles) {
845 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700846 && user.id != currentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700847 profilesToStart.add(user);
848 }
849 }
850 final int profilesToStartSize = profilesToStart.size();
851 int i = 0;
Fyodor Kupolov53cba302017-10-25 18:11:48 -0700852 for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700853 startUser(profilesToStart.get(i).id, /* foreground= */ false);
854 }
855 if (i < profilesToStartSize) {
856 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
857 }
858 }
859
Sudheer Shanka2250d562016-11-07 15:41:02 -0800860 private IStorageManager getStorageManager() {
861 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700862 }
Tony Mak64fd8c02017-12-01 19:11:59 +0000863 boolean startUser(final int userId, final boolean foreground) {
864 return startUser(userId, foreground, null);
865 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700866
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700867 /**
868 * Start user, if its not already running.
869 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
870 * When starting the user, multiple intents will be broadcast in the following order:</p>
871 * <ul>
872 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
873 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
874 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
875 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
876 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
877 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
878 * Sent only if {@code foreground} parameter is true
879 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
880 * of the new fg user
881 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
882 * the new user
883 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
884 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
885 * new user. Sent only when the user is booting after a system update.
886 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
887 * new user. Sent only the first time a user is starting.
888 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
889 * user. Indicates that the user has finished booting.
890 * </ul>
891 *
892 * @param userId ID of the user to start
893 * @param foreground true if user should be brought to the foreground
894 * @return true if the user has been successfully started
895 */
Tony Mak64fd8c02017-12-01 19:11:59 +0000896 boolean startUser(
897 final int userId,
898 final boolean foreground,
899 @Nullable IProgressListener unlockListener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700900 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700901 != PackageManager.PERMISSION_GRANTED) {
902 String msg = "Permission Denial: switchUser() from pid="
903 + Binder.getCallingPid()
904 + ", uid=" + Binder.getCallingUid()
905 + " requires " + INTERACT_ACROSS_USERS_FULL;
906 Slog.w(TAG, msg);
907 throw new SecurityException(msg);
908 }
909
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700910 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700911
912 final long ident = Binder.clearCallingIdentity();
913 try {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700914 final int oldUserId = getCurrentUserId();
915 if (oldUserId == userId) {
916 return true;
917 }
918
919 if (foreground) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100920 mInjector.clearAllLockedTasks("startUser");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700921 }
922
923 final UserInfo userInfo = getUserInfo(userId);
924 if (userInfo == null) {
925 Slog.w(TAG, "No user info for user #" + userId);
926 return false;
927 }
928 if (foreground && userInfo.isManagedProfile()) {
929 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
930 return false;
931 }
932
933 if (foreground && mUserSwitchUiEnabled) {
934 mInjector.getWindowManager().startFreezingScreen(
935 R.anim.screen_user_exit, R.anim.screen_user_enter);
936 }
937
938 boolean needStart = false;
939 boolean updateUmState = false;
940 UserState uss;
941
942 // If the user we are switching to is not currently started, then
943 // we need to start it now.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700944 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700945 uss = mStartedUsers.get(userId);
946 if (uss == null) {
947 uss = new UserState(UserHandle.of(userId));
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -0700948 uss.mUnlockProgress.addListener(new UserProgressListener());
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700949 mStartedUsers.put(userId, uss);
950 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700951 needStart = true;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700952 updateUmState = true;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700953 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700954 final Integer userIdInt = userId;
955 mUserLru.remove(userIdInt);
956 mUserLru.add(userIdInt);
Tony Mak553b9972017-12-12 19:50:57 +0000957 }
958 if (unlockListener != null) {
959 uss.mUnlockProgress.addListener(unlockListener);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700960 }
961 if (updateUmState) {
962 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
963 }
964 if (foreground) {
Dianne Hackbornced54392018-02-26 13:07:42 -0800965 // Make sure the old user is no longer considering the display to be on.
966 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700967 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700968 mCurrentUserId = userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700969 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700970 }
971 mInjector.updateUserConfiguration();
972 updateCurrentProfileIds();
973 mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
Dianne Hackbornced54392018-02-26 13:07:42 -0800974 mInjector.reportCurWakefulnessUsageEvent();
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700975 // Once the internal notion of the active user has switched, we lock the device
976 // with the option to show the user switcher on the keyguard.
977 if (mUserSwitchUiEnabled) {
978 mInjector.getWindowManager().setSwitchingUser(true);
979 mInjector.getWindowManager().lockNow(null);
980 }
981 } else {
982 final Integer currentUserIdInt = mCurrentUserId;
983 updateCurrentProfileIds();
984 mInjector.getWindowManager().setCurrentProfileIds(getCurrentProfileIds());
985 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700986 mUserLru.remove(currentUserIdInt);
987 mUserLru.add(currentUserIdInt);
988 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700989 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700990
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700991 // Make sure user is in the started state. If it is currently
992 // stopping, we need to knock that off.
993 if (uss.state == UserState.STATE_STOPPING) {
994 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
995 // so we can just fairly silently bring the user back from
996 // the almost-dead.
997 uss.setState(uss.lastState);
998 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
999 synchronized (mLock) {
1000 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001001 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001002 needStart = true;
1003 } else if (uss.state == UserState.STATE_SHUTDOWN) {
1004 // This means ACTION_SHUTDOWN has been sent, so we will
1005 // need to treat this as a new boot of the user.
1006 uss.setState(UserState.STATE_BOOTING);
1007 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
1008 synchronized (mLock) {
1009 updateStartedUserArrayLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001010 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001011 needStart = true;
1012 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001013
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001014 if (uss.state == UserState.STATE_BOOTING) {
1015 // Give user manager a chance to propagate user restrictions
1016 // to other services and prepare app storage
1017 mInjector.getUserManager().onBeforeStartUser(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001018
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001019 // Booting up a new user, need to tell system services about it.
1020 // Note that this is on the same handler as scheduling of broadcasts,
1021 // which is important because it needs to go first.
1022 mHandler.sendMessage(
1023 mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
1024 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001025
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001026 if (foreground) {
1027 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
1028 oldUserId));
1029 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1030 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1031 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
1032 oldUserId, userId, uss));
1033 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
1034 oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
1035 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001036
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001037 if (needStart) {
1038 // Send USER_STARTED broadcast
1039 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
1040 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1041 | Intent.FLAG_RECEIVER_FOREGROUND);
1042 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1043 mInjector.broadcastIntent(intent,
1044 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1045 null, false, false, MY_PID, SYSTEM_UID, userId);
1046 }
1047
1048 if (foreground) {
1049 moveUserToForeground(uss, oldUserId, userId);
1050 } else {
1051 finishUserBoot(uss);
1052 }
1053
1054 if (needStart) {
1055 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
1056 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1057 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1058 mInjector.broadcastIntent(intent,
1059 null, new IIntentReceiver.Stub() {
1060 @Override
1061 public void performReceive(Intent intent, int resultCode,
1062 String data, Bundle extras, boolean ordered,
1063 boolean sticky,
1064 int sendingUser) throws RemoteException {
1065 }
1066 }, 0, null, null,
1067 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
1068 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001069 }
1070 } finally {
1071 Binder.restoreCallingIdentity(ident);
1072 }
1073
1074 return true;
1075 }
1076
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001077 /**
1078 * Start user, if its not already running, and bring it to foreground.
1079 */
Evan Rosky18396452016-07-27 15:19:37 -07001080 void startUserInForeground(final int targetUserId) {
1081 boolean success = startUser(targetUserId, /* foreground */ true);
1082 if (!success) {
1083 mInjector.getWindowManager().setSwitchingUser(false);
1084 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001085 }
1086
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001087 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001088 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -08001089 != PackageManager.PERMISSION_GRANTED) {
1090 String msg = "Permission Denial: unlockUser() from pid="
1091 + Binder.getCallingPid()
1092 + ", uid=" + Binder.getCallingUid()
1093 + " requires " + INTERACT_ACROSS_USERS_FULL;
1094 Slog.w(TAG, msg);
1095 throw new SecurityException(msg);
1096 }
1097
Jeff Sharkey8924e872015-11-30 12:52:10 -07001098 final long binderToken = Binder.clearCallingIdentity();
1099 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001100 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -07001101 } finally {
1102 Binder.restoreCallingIdentity(binderToken);
1103 }
1104 }
1105
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001106 /**
1107 * Attempt to unlock user without a credential token. This typically
1108 * succeeds when the device doesn't have credential-encrypted storage, or
1109 * when the the credential-encrypted storage isn't tied to a user-provided
1110 * PIN or pattern.
1111 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001112 private boolean maybeUnlockUser(final int userId) {
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001113 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001114 return unlockUserCleared(userId, null, null, null);
1115 }
1116
1117 private static void notifyFinished(int userId, IProgressListener listener) {
1118 if (listener == null) return;
1119 try {
1120 listener.onFinished(userId, null);
1121 } catch (RemoteException ignored) {
1122 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001123 }
1124
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001125 private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001126 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001127 UserState uss;
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001128 if (!StorageManager.isUserKeyUnlocked(userId)) {
1129 final UserInfo userInfo = getUserInfo(userId);
1130 final IStorageManager storageManager = getStorageManager();
1131 try {
1132 // We always want to unlock user storage, even user is not started yet
1133 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
1134 } catch (RemoteException | RuntimeException e) {
1135 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
Ricky Wai4266fee2016-05-23 15:33:04 +01001136 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001137 }
1138 synchronized (mLock) {
1139 // Register the given listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001140 uss = mStartedUsers.get(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001141 if (uss != null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001142 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001143 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001144 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001145 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001146 // Bail if user isn't actually running
1147 if (uss == null) {
1148 notifyFinished(userId, listener);
1149 return false;
1150 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001151
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001152 finishUserUnlocking(uss);
1153
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001154 // We just unlocked a user, so let's now attempt to unlock any
1155 // managed profiles under that user.
Jeff Sharkeyba512352015-11-12 20:17:45 -08001156
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001157 // First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
1158 int[] userIds;
1159 synchronized (mLock) {
1160 userIds = new int[mStartedUsers.size()];
1161 for (int i = 0; i < userIds.length; i++) {
1162 userIds[i] = mStartedUsers.keyAt(i);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001163 }
1164 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001165 for (int testUserId : userIds) {
1166 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
1167 if (parent != null && parent.id == userId && testUserId != userId) {
1168 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1169 + "): attempting unlock because parent was just unlocked");
1170 maybeUnlockUser(testUserId);
1171 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001172 }
1173
Jeff Sharkeyba512352015-11-12 20:17:45 -08001174 return true;
1175 }
1176
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001177 boolean switchUser(final int targetUserId) {
1178 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001179 int currentUserId = getCurrentUserId();
1180 UserInfo targetUserInfo = getUserInfo(targetUserId);
1181 if (targetUserId == currentUserId) {
1182 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
1183 return true;
1184 }
1185 if (targetUserInfo == null) {
1186 Slog.w(TAG, "No user info for user #" + targetUserId);
1187 return false;
1188 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001189 if (!targetUserInfo.supportsSwitchTo()) {
1190 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
1191 return false;
1192 }
1193 if (targetUserInfo.isManagedProfile()) {
1194 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
1195 return false;
1196 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001197 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001198 mTargetUserId = targetUserId;
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001199 }
1200 if (mUserSwitchUiEnabled) {
1201 UserInfo currentUserInfo = getUserInfo(currentUserId);
1202 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
1203 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
1204 mUiHandler.sendMessage(mHandler.obtainMessage(
1205 START_USER_SWITCH_UI_MSG, userNames));
1206 } else {
1207 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
1208 mHandler.sendMessage(mHandler.obtainMessage(
1209 START_USER_SWITCH_FG_MSG, targetUserId, 0));
1210 }
1211 return true;
1212 }
1213
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001214 private void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001215 // The dialog will show and then initiate the user switch by calling startUserInForeground
Alex Chau93ae42b2018-01-11 15:10:12 +00001216 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second,
1217 getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001218 }
1219
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001220 private void dispatchForegroundProfileChanged(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001221 final int observerCount = mUserSwitchObservers.beginBroadcast();
1222 for (int i = 0; i < observerCount; i++) {
1223 try {
1224 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1225 } catch (RemoteException e) {
1226 // Ignore
1227 }
1228 }
1229 mUserSwitchObservers.finishBroadcast();
1230 }
1231
1232 /** Called on handler thread */
1233 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001234 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001235 final int observerCount = mUserSwitchObservers.beginBroadcast();
1236 for (int i = 0; i < observerCount; i++) {
1237 try {
1238 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1239 } catch (RemoteException e) {
1240 }
1241 }
1242 mUserSwitchObservers.finishBroadcast();
1243 }
1244
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001245 private void dispatchLockedBootComplete(int userId) {
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001246 final int observerCount = mUserSwitchObservers.beginBroadcast();
1247 for (int i = 0; i < observerCount; i++) {
1248 try {
1249 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1250 } catch (RemoteException e) {
1251 // Ignore
1252 }
1253 }
1254 mUserSwitchObservers.finishBroadcast();
1255 }
1256
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001257 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1258 // Never stop system user
1259 if (oldUserId == UserHandle.USER_SYSTEM) {
1260 return;
1261 }
1262 // For now, only check for user restriction. Additional checks can be added here
1263 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1264 oldUserId);
1265 if (!disallowRunInBg) {
1266 return;
1267 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001268 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001269 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1270 + " and related users");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001271 stopUsersLU(oldUserId, false, null);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001272 }
1273 }
1274
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001275 private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001276 synchronized (mLock) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001277 Slog.e(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
1278 mTimeoutUserSwitchCallbacks = mCurWaitingUserSwitchCallbacks;
1279 mHandler.removeMessages(USER_SWITCH_CALLBACKS_TIMEOUT_MSG);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001280 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001281 // Report observers that never called back (USER_SWITCH_CALLBACKS_TIMEOUT)
1282 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_CALLBACKS_TIMEOUT_MSG,
1283 oldUserId, newUserId), USER_SWITCH_CALLBACKS_TIMEOUT_MS);
1284 }
1285 }
1286
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001287 private void timeoutUserSwitchCallbacks(int oldUserId, int newUserId) {
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001288 synchronized (mLock) {
1289 if (mTimeoutUserSwitchCallbacks != null && !mTimeoutUserSwitchCallbacks.isEmpty()) {
1290 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId
1291 + ". Observers that didn't respond: " + mTimeoutUserSwitchCallbacks);
1292 mTimeoutUserSwitchCallbacks = null;
1293 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001294 }
1295 }
1296
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001297 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1298 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001299 final int observerCount = mUserSwitchObservers.beginBroadcast();
1300 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001301 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001302 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001303 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001304 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001305 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001306 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001307 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001308 for (int i = 0; i < observerCount; i++) {
1309 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001310 // Prepend with unique prefix to guarantee that keys are unique
1311 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001312 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001313 curWaitingUserSwitchCallbacks.add(name);
1314 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001315 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1316 @Override
1317 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001318 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001319 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001320 if (delay > USER_SWITCH_TIMEOUT_MS) {
1321 Slog.e(TAG, "User switch timeout: observer " + name
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001322 + " sent result after " + delay + " ms");
1323 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001324 curWaitingUserSwitchCallbacks.remove(name);
Fyodor Kupolov807e6502017-08-21 16:07:14 -07001325 // Continue switching if all callbacks have been notified and
1326 // user switching session is still valid
1327 if (waitingCallbacksCount.decrementAndGet() == 0
1328 && (curWaitingUserSwitchCallbacks
1329 == mCurWaitingUserSwitchCallbacks)) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001330 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001331 }
1332 }
1333 }
1334 };
1335 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001336 } catch (RemoteException e) {
1337 }
1338 }
1339 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001340 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001341 sendContinueUserSwitchLU(uss, oldUserId, newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001342 }
1343 }
1344 mUserSwitchObservers.finishBroadcast();
1345 }
1346
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001347 void sendContinueUserSwitchLU(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001348 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001349 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001350 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001351 oldUserId, newUserId, uss));
1352 }
1353
1354 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001355 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001356 if (mUserSwitchUiEnabled) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001357 mInjector.getWindowManager().stopFreezingScreen();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001358 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001359 uss.switching = false;
1360 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1361 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1362 newUserId, 0));
Alex Chaub6ef8692018-01-09 14:16:36 +00001363 stopGuestOrEphemeralUserIfBackground(oldUserId);
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001364 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001365 }
1366
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001367 private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
1368 boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001369 if (homeInFront) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001370 mInjector.startHomeActivity(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001371 } else {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001372 mInjector.stackSupervisorResumeFocusedStackTopActivity();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001373 }
1374 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001375 sendUserSwitchBroadcasts(oldUserId, newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001376 }
1377
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001378 void sendUserSwitchBroadcasts(int oldUserId, int newUserId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001379 long ident = Binder.clearCallingIdentity();
1380 try {
1381 Intent intent;
1382 if (oldUserId >= 0) {
1383 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001384 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001385 int count = profiles.size();
1386 for (int i = 0; i < count; i++) {
1387 int profileUserId = profiles.get(i).id;
1388 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1390 | Intent.FLAG_RECEIVER_FOREGROUND);
1391 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001392 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001393 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1394 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1395 }
1396 }
1397 if (newUserId >= 0) {
1398 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001399 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001400 int count = profiles.size();
1401 for (int i = 0; i < count; i++) {
1402 int profileUserId = profiles.get(i).id;
1403 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1404 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1405 | Intent.FLAG_RECEIVER_FOREGROUND);
1406 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001407 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001408 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1409 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1410 }
1411 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1413 | Intent.FLAG_RECEIVER_FOREGROUND);
1414 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001415 mInjector.broadcastIntent(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001416 null, null, 0, null, null,
1417 new String[] {android.Manifest.permission.MANAGE_USERS},
1418 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1419 UserHandle.USER_ALL);
1420 }
1421 } finally {
1422 Binder.restoreCallingIdentity(ident);
1423 }
1424 }
1425
1426
1427 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1428 int allowMode, String name, String callerPackage) {
1429 final int callingUserId = UserHandle.getUserId(callingUid);
1430 if (callingUserId == userId) {
1431 return userId;
1432 }
1433
1434 // Note that we may be accessing mCurrentUserId outside of a lock...
1435 // shouldn't be a big deal, if this is being called outside
1436 // of a locked context there is intrinsically a race with
1437 // the value the caller will receive and someone else changing it.
1438 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1439 // we will switch to the calling user if access to the current user fails.
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001440 int targetUserId = unsafeConvertIncomingUser(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001441
1442 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1443 final boolean allow;
Tony Make839d702018-01-22 15:34:46 +00001444 if (mInjector.isCallerRecents(callingUid)
1445 && callingUserId == getCurrentUserId()
1446 && isSameProfileGroup(callingUserId, targetUserId)) {
1447 // If the caller is Recents and it is running in the current user, we then allow it
1448 // to access its profiles.
1449 allow = true;
1450 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001451 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1452 // If the caller has this permission, they always pass go. And collect $200.
1453 allow = true;
1454 } else if (allowMode == ALLOW_FULL_ONLY) {
1455 // We require full access, sucks to be you.
1456 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001457 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001458 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1459 // If the caller does not have either permission, they are always doomed.
1460 allow = false;
1461 } else if (allowMode == ALLOW_NON_FULL) {
1462 // We are blanket allowing non-full access, you lucky caller!
1463 allow = true;
1464 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1465 // We may or may not allow this depending on whether the two users are
1466 // in the same profile.
1467 allow = isSameProfileGroup(callingUserId, targetUserId);
1468 } else {
1469 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1470 }
1471 if (!allow) {
1472 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1473 // In this case, they would like to just execute as their
1474 // owner user instead of failing.
1475 targetUserId = callingUserId;
1476 } else {
1477 StringBuilder builder = new StringBuilder(128);
1478 builder.append("Permission Denial: ");
1479 builder.append(name);
1480 if (callerPackage != null) {
1481 builder.append(" from ");
1482 builder.append(callerPackage);
1483 }
1484 builder.append(" asks to run as user ");
1485 builder.append(userId);
1486 builder.append(" but is calling from user ");
1487 builder.append(UserHandle.getUserId(callingUid));
1488 builder.append("; this requires ");
1489 builder.append(INTERACT_ACROSS_USERS_FULL);
1490 if (allowMode != ALLOW_FULL_ONLY) {
1491 builder.append(" or ");
1492 builder.append(INTERACT_ACROSS_USERS);
1493 }
1494 String msg = builder.toString();
1495 Slog.w(TAG, msg);
1496 throw new SecurityException(msg);
1497 }
1498 }
1499 }
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001500 if (!allowAll) {
1501 ensureNotSpecialUser(targetUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001502 }
1503 // Check shell permission
1504 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1505 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1506 throw new SecurityException("Shell does not have permission to access user "
1507 + targetUserId + "\n " + Debug.getCallers(3));
1508 }
1509 }
1510 return targetUserId;
1511 }
1512
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001513 int unsafeConvertIncomingUser(int userId) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001514 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001515 ? getCurrentUserId(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001516 }
1517
Makoto Onuki7041c4b2018-02-06 13:36:34 -08001518 void ensureNotSpecialUser(int userId) {
1519 if (userId >= 0) {
1520 return;
1521 }
1522 throw new IllegalArgumentException("Call does not support special user #" + userId);
1523 }
1524
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001525 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1526 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001527 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001528 != PackageManager.PERMISSION_GRANTED) {
1529 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1530 + Binder.getCallingPid()
1531 + ", uid=" + Binder.getCallingUid()
1532 + " requires " + INTERACT_ACROSS_USERS_FULL;
1533 Slog.w(TAG, msg);
1534 throw new SecurityException(msg);
1535 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001536 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001537 }
1538
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001539 void sendForegroundProfileChanged(int userId) {
1540 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
1541 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
1542 }
1543
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001544 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1545 mUserSwitchObservers.unregister(observer);
1546 }
1547
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001548 UserState getStartedUserState(int userId) {
1549 synchronized (mLock) {
1550 return mStartedUsers.get(userId);
1551 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001552 }
1553
1554 boolean hasStartedUserState(int userId) {
1555 return mStartedUsers.get(userId) != null;
1556 }
1557
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001558 private void updateStartedUserArrayLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001559 int num = 0;
1560 for (int i = 0; i < mStartedUsers.size(); i++) {
1561 UserState uss = mStartedUsers.valueAt(i);
1562 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001563 if (uss.state != UserState.STATE_STOPPING
1564 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001565 num++;
1566 }
1567 }
1568 mStartedUserArray = new int[num];
1569 num = 0;
1570 for (int i = 0; i < mStartedUsers.size(); i++) {
1571 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001572 if (uss.state != UserState.STATE_STOPPING
1573 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001574 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001575 }
1576 }
1577 }
1578
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001579 void sendBootCompleted(IIntentReceiver resultTo) {
1580 // Get a copy of mStartedUsers to use outside of lock
1581 SparseArray<UserState> startedUsers;
1582 synchronized (mLock) {
1583 startedUsers = mStartedUsers.clone();
1584 }
1585 for (int i = 0; i < startedUsers.size(); i++) {
1586 UserState uss = startedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001587 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001588 }
1589 }
1590
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001591 void onSystemReady() {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001592 updateCurrentProfileIds();
Dianne Hackborn3378aa92018-03-30 17:43:49 -07001593 mInjector.reportCurWakefulnessUsageEvent();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001594 }
1595
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001596 /**
1597 * Refreshes the list of users related to the current user when either a
1598 * user switch happens or when a new related user is started in the
1599 * background.
1600 */
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001601 private void updateCurrentProfileIds() {
1602 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(getCurrentUserId(),
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001603 false /* enabledOnly */);
1604 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1605 for (int i = 0; i < currentProfileIds.length; i++) {
1606 currentProfileIds[i] = profiles.get(i).id;
1607 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001608 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
1609 synchronized (mLock) {
1610 mCurrentProfileIds = currentProfileIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001611
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001612 mUserProfileGroupIds.clear();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001613 for (int i = 0; i < users.size(); i++) {
1614 UserInfo user = users.get(i);
1615 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001616 mUserProfileGroupIds.put(user.id, user.profileGroupId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001617 }
1618 }
1619 }
1620 }
1621
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001622 int[] getStartedUserArray() {
1623 synchronized (mLock) {
1624 return mStartedUserArray;
1625 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001626 }
1627
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001628 boolean isUserRunning(int userId, int flags) {
1629 UserState state = getStartedUserState(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001630 if (state == null) {
1631 return false;
1632 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001633 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001634 return true;
1635 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001636 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001637 switch (state.state) {
1638 case UserState.STATE_BOOTING:
1639 case UserState.STATE_RUNNING_LOCKED:
1640 return true;
1641 default:
1642 return false;
1643 }
1644 }
1645 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1646 switch (state.state) {
1647 case UserState.STATE_RUNNING_UNLOCKING:
1648 case UserState.STATE_RUNNING_UNLOCKED:
1649 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001650 // In the stopping/shutdown state return unlock state of the user key
1651 case UserState.STATE_STOPPING:
1652 case UserState.STATE_SHUTDOWN:
1653 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001654 default:
1655 return false;
1656 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001657 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001658 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001659 switch (state.state) {
1660 case UserState.STATE_RUNNING_UNLOCKED:
1661 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001662 // In the stopping/shutdown state return unlock state of the user key
1663 case UserState.STATE_STOPPING:
1664 case UserState.STATE_SHUTDOWN:
1665 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001666 default:
1667 return false;
1668 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001669 }
1670
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001671 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001672 }
1673
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001674 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001675 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001676 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001677 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001678 != PackageManager.PERMISSION_GRANTED)) {
1679 String msg = "Permission Denial: getCurrentUser() from pid="
1680 + Binder.getCallingPid()
1681 + ", uid=" + Binder.getCallingUid()
1682 + " requires " + INTERACT_ACROSS_USERS;
1683 Slog.w(TAG, msg);
1684 throw new SecurityException(msg);
1685 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001686
1687 // Optimization - if there is no pending user switch, return current id
1688 if (mTargetUserId == UserHandle.USER_NULL) {
1689 return getUserInfo(mCurrentUserId);
1690 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001691 synchronized (mLock) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001692 return getCurrentUserLU();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001693 }
1694 }
1695
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001696 UserInfo getCurrentUserLU() {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001697 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001698 return getUserInfo(userId);
1699 }
1700
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001701 int getCurrentOrTargetUserId() {
1702 synchronized (mLock) {
1703 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
1704 }
1705 }
1706
1707 int getCurrentOrTargetUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001708 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001709 }
1710
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001711
1712 int getCurrentUserIdLU() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001713 return mCurrentUserId;
1714 }
1715
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001716 int getCurrentUserId() {
1717 synchronized (mLock) {
1718 return mCurrentUserId;
1719 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001720 }
1721
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001722 private boolean isCurrentUserLU(int userId) {
1723 return userId == getCurrentOrTargetUserIdLU();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001724 }
1725
1726 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001727 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001728 return ums != null ? ums.getUserIds() : new int[] { 0 };
1729 }
1730
1731 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001732 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001733 }
1734
1735 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001736 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001737 }
1738
Makoto Onuki6569c362018-02-27 15:52:01 -08001739 /**
1740 * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
1741 * IDs. Otherwise return an array whose only element is the given user id.
1742 *
1743 * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
1744 */
1745 int[] expandUserId(int userId) {
1746 if (userId != UserHandle.USER_ALL) {
1747 return new int[] {userId};
1748 } else {
1749 return getUsers();
1750 }
1751 }
1752
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001753 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001754 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001755 }
1756
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001757 void enforceShellRestriction(String restriction, int userHandle) {
1758 if (Binder.getCallingUid() == SHELL_UID) {
1759 if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
1760 throw new SecurityException("Shell does not have permission to access user "
1761 + userHandle);
1762 }
1763 }
1764 }
1765
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001766 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001767 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001768 }
1769
1770 Set<Integer> getProfileIds(int userId) {
1771 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001772 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001773 false /* enabledOnly */);
1774 for (UserInfo user : profiles) {
1775 userIds.add(user.id);
1776 }
1777 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001778 }
1779
1780 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001781 if (callingUserId == targetUserId) {
1782 return true;
1783 }
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001784 synchronized (mLock) {
1785 int callingProfile = mUserProfileGroupIds.get(callingUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001786 UserInfo.NO_PROFILE_GROUP_ID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001787 int targetProfile = mUserProfileGroupIds.get(targetUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001788 UserInfo.NO_PROFILE_GROUP_ID);
1789 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1790 && callingProfile == targetProfile;
1791 }
1792 }
1793
Tony Mak60f53e62017-12-21 20:03:29 +00001794 boolean isUserOrItsParentRunning(int userId) {
1795 synchronized (mLock) {
1796 if (isUserRunning(userId, 0)) {
1797 return true;
1798 }
1799 final int parentUserId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
1800 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1801 return false;
1802 }
1803 return isUserRunning(parentUserId, 0);
1804 }
1805 }
1806
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001807 boolean isCurrentProfile(int userId) {
1808 synchronized (mLock) {
1809 return ArrayUtils.contains(mCurrentProfileIds, userId);
1810 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001811 }
1812
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001813 int[] getCurrentProfileIds() {
1814 synchronized (mLock) {
1815 return mCurrentProfileIds;
1816 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001817 }
1818
Fyodor Kupolov8d2faf02018-01-09 18:51:59 -08001819 void onUserRemoved(int userId) {
1820 synchronized (mLock) {
1821 int size = mUserProfileGroupIds.size();
1822 for (int i = size - 1; i >= 0; i--) {
1823 if (mUserProfileGroupIds.keyAt(i) == userId
1824 || mUserProfileGroupIds.valueAt(i) == userId) {
1825 mUserProfileGroupIds.removeAt(i);
1826
1827 }
1828 }
1829 mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
1830 }
1831 }
1832
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001833 /**
1834 * Returns whether the given user requires credential entry at this time. This is used to
1835 * intercept activity launches for work apps when the Work Challenge is present.
1836 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001837 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001838 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001839 if (mStartedUsers.get(userId) == null) {
1840 return false;
1841 }
1842 }
Clara Bayarria1771112015-12-18 16:29:18 +00001843 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001844 return false;
1845 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001846 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001847 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001848 }
1849
Tony Mak8c536f92016-03-21 12:20:41 +00001850 boolean isLockScreenDisabled(@UserIdInt int userId) {
1851 return mLockPatternUtils.isLockScreenDisabled(userId);
1852 }
1853
Alex Chau93ae42b2018-01-11 15:10:12 +00001854 void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
1855 synchronized (mLock) {
1856 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
1857 }
1858 }
1859
1860 void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
1861 synchronized (mLock) {
1862 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
1863 }
1864 }
1865
1866 private String getSwitchingFromSystemUserMessage() {
1867 synchronized (mLock) {
1868 return mSwitchingFromSystemUserMessage;
1869 }
1870 }
1871
1872 private String getSwitchingToSystemUserMessage() {
1873 synchronized (mLock) {
1874 return mSwitchingToSystemUserMessage;
1875 }
1876 }
1877
Yi Jin148d7f42017-11-28 14:23:56 -08001878 void writeToProto(ProtoOutputStream proto, long fieldId) {
1879 synchronized (mLock) {
1880 long token = proto.start(fieldId);
1881 for (int i = 0; i < mStartedUsers.size(); i++) {
1882 UserState uss = mStartedUsers.valueAt(i);
1883 final long uToken = proto.start(UserControllerProto.STARTED_USERS);
1884 proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
1885 uss.writeToProto(proto, UserControllerProto.User.STATE);
1886 proto.end(uToken);
1887 }
1888 for (int i = 0; i < mStartedUserArray.length; i++) {
1889 proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
1890 }
1891 for (int i = 0; i < mUserLru.size(); i++) {
1892 proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
1893 }
1894 if (mUserProfileGroupIds.size() > 0) {
1895 for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
1896 final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
1897 proto.write(UserControllerProto.UserProfile.USER,
1898 mUserProfileGroupIds.keyAt(i));
1899 proto.write(UserControllerProto.UserProfile.PROFILE,
1900 mUserProfileGroupIds.valueAt(i));
1901 proto.end(uToken);
1902 }
1903 }
1904 proto.end(token);
1905 }
1906 }
1907
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001908 void dump(PrintWriter pw, boolean dumpAll) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001909 synchronized (mLock) {
1910 pw.println(" mStartedUsers:");
1911 for (int i = 0; i < mStartedUsers.size(); i++) {
1912 UserState uss = mStartedUsers.valueAt(i);
1913 pw.print(" User #");
1914 pw.print(uss.mHandle.getIdentifier());
1915 pw.print(": ");
1916 uss.dump("", pw);
1917 }
1918 pw.print(" mStartedUserArray: [");
1919 for (int i = 0; i < mStartedUserArray.length; i++) {
1920 if (i > 0)
1921 pw.print(", ");
1922 pw.print(mStartedUserArray[i]);
1923 }
1924 pw.println("]");
1925 pw.print(" mUserLru: [");
1926 for (int i = 0; i < mUserLru.size(); i++) {
1927 if (i > 0)
1928 pw.print(", ");
1929 pw.print(mUserLru.get(i));
1930 }
1931 pw.println("]");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001932 if (mUserProfileGroupIds.size() > 0) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001933 pw.println(" mUserProfileGroupIds:");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001934 for (int i=0; i< mUserProfileGroupIds.size(); i++) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001935 pw.print(" User #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001936 pw.print(mUserProfileGroupIds.keyAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001937 pw.print(" -> profile #");
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001938 pw.println(mUserProfileGroupIds.valueAt(i));
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001939 }
1940 }
1941 }
1942 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001943
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001944 public boolean handleMessage(Message msg) {
1945 switch (msg.what) {
1946 case START_USER_SWITCH_FG_MSG:
1947 startUserInForeground(msg.arg1);
1948 break;
1949 case REPORT_USER_SWITCH_MSG:
1950 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1951 break;
1952 case CONTINUE_USER_SWITCH_MSG:
1953 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1954 break;
1955 case USER_SWITCH_TIMEOUT_MSG:
1956 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1957 break;
1958 case USER_SWITCH_CALLBACKS_TIMEOUT_MSG:
1959 timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
1960 break;
1961 case START_PROFILES_MSG:
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07001962 startProfiles();
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001963 break;
1964 case SYSTEM_USER_START_MSG:
1965 mInjector.batteryStatsServiceNoteEvent(
1966 BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1967 Integer.toString(msg.arg1), msg.arg1);
1968 mInjector.getSystemServiceManager().startUser(msg.arg1);
1969 break;
1970 case SYSTEM_USER_UNLOCK_MSG:
1971 final int userId = msg.arg1;
1972 mInjector.getSystemServiceManager().unlockUser(userId);
Fyodor Kupolov4c72df02017-11-14 11:43:40 -08001973 // Loads recents on a worker thread that allows disk I/O
1974 FgThread.getHandler().post(() -> {
1975 mInjector.loadUserRecents(userId);
1976 });
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07001977 finishUserUnlocked((UserState) msg.obj);
1978 break;
1979 case SYSTEM_USER_CURRENT_MSG:
1980 mInjector.batteryStatsServiceNoteEvent(
1981 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1982 Integer.toString(msg.arg2), msg.arg2);
1983 mInjector.batteryStatsServiceNoteEvent(
1984 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1985 Integer.toString(msg.arg1), msg.arg1);
1986
1987 mInjector.getSystemServiceManager().switchUser(msg.arg1);
1988 break;
1989 case FOREGROUND_PROFILE_CHANGED_MSG:
1990 dispatchForegroundProfileChanged(msg.arg1);
1991 break;
1992 case REPORT_USER_SWITCH_COMPLETE_MSG:
1993 dispatchUserSwitchComplete(msg.arg1);
1994 break;
1995 case REPORT_LOCKED_BOOT_COMPLETE_MSG:
1996 dispatchLockedBootComplete(msg.arg1);
1997 break;
1998 case START_USER_SWITCH_UI_MSG:
1999 showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
2000 break;
2001 }
2002 return false;
2003 }
2004
Fyodor Kupolov0d77c6d2017-10-11 17:53:23 -07002005 private static class UserProgressListener extends IProgressListener.Stub {
2006 private volatile long mUnlockStarted;
2007 @Override
2008 public void onStarted(int id, Bundle extras) throws RemoteException {
2009 Slog.d(TAG, "Started unlocking user " + id);
2010 mUnlockStarted = SystemClock.uptimeMillis();
2011 }
2012
2013 @Override
2014 public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
2015 Slog.d(TAG, "Unlocking user " + id + " progress " + progress);
2016 }
2017
2018 @Override
2019 public void onFinished(int id, Bundle extras) throws RemoteException {
2020 long unlockTime = SystemClock.uptimeMillis() - mUnlockStarted;
2021
2022 // Report system user unlock time to perf dashboard
2023 if (id == UserHandle.USER_SYSTEM) {
2024 new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
2025 .logDuration("SystemUserUnlock", unlockTime);
2026 } else {
2027 Slog.d(TAG, "Unlocking user " + id + " took " + unlockTime + " ms");
2028 }
2029 }
2030 };
2031
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002032 @VisibleForTesting
2033 static class Injector {
2034 private final ActivityManagerService mService;
2035 private UserManagerService mUserManager;
2036 private UserManagerInternal mUserManagerInternal;
2037
2038 Injector(ActivityManagerService service) {
2039 mService = service;
2040 }
2041
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002042 protected Handler getHandler(Handler.Callback callback) {
2043 return new Handler(mService.mHandlerThread.getLooper(), callback);
2044 }
2045
2046 protected Handler getUiHandler(Handler.Callback callback) {
2047 return new Handler(mService.mUiHandler.getLooper(), callback);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002048 }
2049
2050 protected Context getContext() {
2051 return mService.mContext;
2052 }
2053
2054 protected LockPatternUtils getLockPatternUtils() {
2055 return new LockPatternUtils(getContext());
2056 }
2057
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002058 protected int broadcastIntent(Intent intent, String resolvedType,
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002059 IIntentReceiver resultTo, int resultCode, String resultData,
2060 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
2061 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002062 // TODO b/64165549 Verify that mLock is not held before calling AMS methods
2063 synchronized (mService) {
2064 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
2065 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
2066 ordered, sticky, callingPid, callingUid, userId);
2067 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002068 }
2069
2070 int checkCallingPermission(String permission) {
2071 return mService.checkCallingPermission(permission);
2072 }
2073
2074 WindowManagerService getWindowManager() {
2075 return mService.mWindowManager;
2076 }
2077 void activityManagerOnUserStopped(int userId) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002078 synchronized (mService) {
2079 mService.onUserStoppedLocked(userId);
2080 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002081 }
2082
2083 void systemServiceManagerCleanupUser(int userId) {
2084 mService.mSystemServiceManager.cleanupUser(userId);
2085 }
2086
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002087 protected UserManagerService getUserManager() {
2088 if (mUserManager == null) {
2089 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
2090 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
2091 }
2092 return mUserManager;
2093 }
2094
2095 UserManagerInternal getUserManagerInternal() {
2096 if (mUserManagerInternal == null) {
2097 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2098 }
2099 return mUserManagerInternal;
2100 }
2101
2102 KeyguardManager getKeyguardManager() {
2103 return mService.mContext.getSystemService(KeyguardManager.class);
2104 }
2105
2106 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
2107 mService.mBatteryStatsService.noteEvent(code, name, uid);
2108 }
2109
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002110 boolean isRuntimeRestarted() {
2111 return mService.mSystemServiceManager.isRuntimeRestarted();
2112 }
2113
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002114 SystemServiceManager getSystemServiceManager() {
2115 return mService.mSystemServiceManager;
2116 }
2117
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08002118 boolean isFirstBootOrUpgrade() {
2119 IPackageManager pm = AppGlobals.getPackageManager();
2120 try {
2121 return pm.isFirstBoot() || pm.isUpgrade();
2122 } catch (RemoteException e) {
2123 throw e.rethrowFromSystemServer();
2124 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08002125 }
2126
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002127 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
2128 new PreBootBroadcaster(mService, userId, null, quiet) {
2129 @Override
2130 public void onFinished() {
2131 onFinish.run();
2132 }
2133 }.sendNext();
2134 }
2135
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002136 void activityManagerForceStopPackage(int userId, String reason) {
2137 synchronized (mService) {
2138 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
2139 userId, reason);
2140 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002141 };
2142
2143 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
2144 boolean exported) {
2145 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
2146 }
2147
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002148 protected void startHomeActivity(int userId, String reason) {
2149 synchronized (mService) {
2150 mService.startHomeActivityLocked(userId, reason);
2151 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002152 }
2153
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002154 void updateUserConfiguration() {
2155 synchronized (mService) {
2156 mService.updateUserConfigurationLocked();
2157 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002158 }
2159
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002160 void clearBroadcastQueueForUser(int userId) {
2161 synchronized (mService) {
2162 mService.clearBroadcastQueueForUserLocked(userId);
2163 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002164 }
2165
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002166 void loadUserRecents(int userId) {
2167 synchronized (mService) {
Winson Chung3f0e59a2017-10-25 10:19:05 -07002168 mService.getRecentTasks().loadUserRecentsLocked(userId);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002169 }
Fyodor Kupolov58e732d2017-09-12 17:35:41 -07002170 }
2171
2172 void startPersistentApps(int matchFlags) {
2173 mService.startPersistentApps(matchFlags);
2174 }
2175
2176 void installEncryptionUnawareProviders(int userId) {
2177 mService.installEncryptionUnawareProviders(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002178 }
2179
Alex Chau93ae42b2018-01-11 15:10:12 +00002180 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
2181 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002182 Dialog d;
2183 if (!mService.mContext.getPackageManager()
2184 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
2185 d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
Alex Chau93ae42b2018-01-11 15:10:12 +00002186 true /* above system */, switchingFromSystemUserMessage,
2187 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07002188 } else {
2189 d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
2190 true /* above system */, switchingFromSystemUserMessage,
2191 switchingToSystemUserMessage);
2192 }
2193
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002194 d.show();
2195 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002196
Dianne Hackbornced54392018-02-26 13:07:42 -08002197 void reportGlobalUsageEventLocked(int event) {
2198 synchronized (mService) {
2199 mService.reportGlobalUsageEventLocked(event);
2200 }
2201 }
2202
2203 void reportCurWakefulnessUsageEvent() {
2204 synchronized (mService) {
2205 mService.reportCurWakefulnessUsageEventLocked();
2206 }
2207 }
2208
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002209 void stackSupervisorRemoveUser(int userId) {
2210 synchronized (mService) {
2211 mService.mStackSupervisor.removeUserLocked(userId);
2212 }
Tony Mak5c2cf032017-04-03 18:38:23 +01002213 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002214
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002215 protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
2216 synchronized (mService) {
2217 return mService.mStackSupervisor.switchUserLocked(userId, uss);
2218 }
2219 }
2220
2221 protected void stackSupervisorResumeFocusedStackTopActivity() {
2222 synchronized (mService) {
2223 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
2224 }
2225 }
2226
Charles Heff9b4dff2017-09-22 10:18:37 +01002227 protected void clearAllLockedTasks(String reason) {
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002228 synchronized (mService) {
Bryce Lee2b8e0372018-04-05 17:01:37 -07002229 mService.getLockTaskController().clearLockedTasks(reason);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -07002230 }
Benjamin Franza83859f2017-07-03 16:34:14 +01002231 }
Tony Make839d702018-01-22 15:34:46 +00002232
2233 protected boolean isCallerRecents(int callingUid) {
2234 return mService.getRecentTasks().isCallerRecents(callingUid);
2235 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07002236 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07002237}