blob: 7e9a2ac911273a266450cb073199fd4bd53f983d [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 Kupolovf63b89c2015-10-27 18:08:56 -070025import static android.os.Process.SYSTEM_UID;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070026import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
27import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
28import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070029import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
30import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
31import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
32import static com.android.server.am.ActivityManagerService.MY_PID;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070033import static com.android.server.am.ActivityManagerService.REPORT_LOCKED_BOOT_COMPLETE_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070034import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
35import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
36import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
37import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -070038import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070039import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060040import static com.android.server.am.UserState.STATE_BOOTING;
41import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
42import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
43import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070044
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070045import android.annotation.NonNull;
Tony Mak8c536f92016-03-21 12:20:41 +000046import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070047import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080048import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070049import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070050import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070051import android.app.IStopUserCallback;
52import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000053import android.app.KeyguardManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070054import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070055import android.content.IIntentReceiver;
56import android.content.Intent;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080057import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070058import android.content.pm.PackageManager;
59import android.content.pm.UserInfo;
60import android.os.BatteryStats;
61import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060062import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070063import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070064import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070065import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070066import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060067import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070068import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070069import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070070import android.os.Process;
71import android.os.RemoteCallbackList;
72import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070073import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070074import android.os.SystemClock;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070075import android.os.UserHandle;
76import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010077import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080078import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080079import android.os.storage.StorageManager;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070080import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070081import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080082import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070083import android.util.Slog;
84import android.util.SparseArray;
85import android.util.SparseIntArray;
86
87import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080088import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070089import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070090import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070091import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070092import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000093import com.android.internal.widget.LockPatternUtils;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010094import com.android.server.LocalServices;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070095import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070096import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070097
98import java.io.PrintWriter;
99import java.util.ArrayList;
100import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700101import java.util.HashSet;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700102import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600103import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700104import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700105import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700106
107/**
108 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
109 */
Benjamin Franz563707b2017-06-29 15:06:13 +0100110class UserController {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700111 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600112
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700113 // Maximum number of users we allow to be running at a time.
114 static final int MAX_RUNNING_USERS = 3;
115
116 // Amount of time we wait for observers to handle a user switch before
117 // giving up on them and unfreezing the screen.
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -0700118 static final int USER_SWITCH_TIMEOUT = 3 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700119
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700120 private final Object mLock;
121 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700122 private final Handler mHandler;
123
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700124 // Holds the current foreground user's id. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700125 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700126 private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
127 // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
128 // once target user goes into the foreground. Use mLock when updating
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700129 @GuardedBy("mLock")
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -0700130 private volatile int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700131
132 /**
133 * Which users have been started, so are allowed to run code.
134 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700135 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700136 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800137
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700138 /**
139 * LRU list of history of current users. Most recently current is at the end.
140 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700141 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700142 private final ArrayList<Integer> mUserLru = new ArrayList<>();
143
144 /**
145 * Constant array of the users that are currently started.
146 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700147 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700148 private int[] mStartedUserArray = new int[] { 0 };
149
150 // If there are multiple profiles for the current user, their ids are here
151 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700152 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700153 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700154
155 /**
156 * Mapping from each known user ID to the profile group ID it is associated with.
157 */
158 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
159
160 /**
161 * Registered observers of the user switching mechanics.
162 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700163 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700164 = new RemoteCallbackList<>();
165
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700166 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700167
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700168 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700169 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700170 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700171 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700172 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700173
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700174 private volatile UserManagerService mUserManager;
175
Clara Bayarria1771112015-12-18 16:29:18 +0000176 private final LockPatternUtils mLockPatternUtils;
177
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700178 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700179 this(new Injector(service));
180 }
181
182 @VisibleForTesting
183 UserController(Injector injector) {
184 mInjector = injector;
185 mLock = injector.getLock();
186 mHandler = injector.getHandler();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700187 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800188 final UserState uss = new UserState(UserHandle.SYSTEM);
189 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700190 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700191 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700192 updateStartedUserArrayLocked();
193 }
194
195 void finishUserSwitch(UserState uss) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700196 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700197 finishUserBoot(uss);
198
199 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700200 stopRunningUsersLocked(MAX_RUNNING_USERS);
201 }
202 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700203
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700204 void stopRunningUsersLocked(int maxRunningUsers) {
205 int num = mUserLru.size();
206 int i = 0;
207 while (num > maxRunningUsers && i < mUserLru.size()) {
208 Integer oldUserId = mUserLru.get(i);
209 UserState oldUss = mStartedUsers.get(oldUserId);
210 if (oldUss == null) {
211 // Shouldn't happen, but be sane if it does.
212 mUserLru.remove(i);
213 num--;
214 continue;
215 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700216 if (oldUss.state == UserState.STATE_STOPPING
217 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700218 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700219 num--;
220 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700221 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700222 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700223 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
224 // Owner/System user and current user can't be stopped. We count it as running
225 // when it is not a pure system user.
226 if (UserInfo.isSystemOnly(oldUserId)) {
227 num--;
228 }
229 i++;
230 continue;
231 }
232 // This is a user to be stopped.
233 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
234 num--;
235 }
236 num--;
237 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700238 }
239 }
240
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800241 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700242 finishUserBoot(uss, null);
243 }
244
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800245 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700246 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700247
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700248 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700249 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700250 // Bail if we ended up with a stale user
251 if (mStartedUsers.get(userId) != uss) return;
252
253 // We always walk through all the user lifecycle states to send
254 // consistent developer events. We step into RUNNING_LOCKED here,
255 // but we might immediately step into RUNNING below if the user
256 // storage is already unlocked.
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600257 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700258 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -0800259 // Do not report secondary users, runtime restarts or first boot/upgrade
260 if (userId == UserHandle.USER_SYSTEM
261 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800262 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
263 MetricsLogger.histogram(mInjector.getContext(),
264 "framework_locked_boot_completed", uptimeSeconds);
Fyodor Kupolov24e12dc2017-01-17 12:20:36 -0800265 final int MAX_UPTIME_SECONDS = 120;
266 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
267 Slog.wtf("SystemServerTiming",
268 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
269 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800270 }
James Hawkins899608a2016-05-27 11:15:06 -0700271
Sudheer Shanka2c4522c2016-08-27 20:53:28 -0700272 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
273 userId, 0));
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700274 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700275 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700276 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
277 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700278 mInjector.broadcastIntentLocked(intent, null, resultTo, 0, null, null,
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700279 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
280 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
281 }
282
Jeff Sharkey7661a312016-04-07 12:39:57 -0600283 // We need to delay unlocking managed profiles until the parent user
284 // is also unlocked.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700285 if (mInjector.getUserManager().isManagedProfile(userId)) {
286 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey7661a312016-04-07 12:39:57 -0600287 if (parent != null
288 && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
289 Slog.d(TAG, "User " + userId + " (parent " + parent.id
290 + "): attempting unlock because parent is unlocked");
291 maybeUnlockUser(userId);
292 } else {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700293 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
294 Slog.d(TAG, "User " + userId + " (parent " + parentId
Jeff Sharkey7661a312016-04-07 12:39:57 -0600295 + "): delaying unlock because parent is locked");
296 }
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600297 } else {
298 maybeUnlockUser(userId);
299 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700300 }
301 }
302
303 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600304 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
305 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700306 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600307 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700308 final int userId = uss.mHandle.getIdentifier();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200309 boolean proceedWithUnlock = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700310 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700311 // Bail if we ended up with a stale user
312 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
313
314 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600315 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700316
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600317 if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700318 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200319 proceedWithUnlock = true;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600320 }
321 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200322
323 if (proceedWithUnlock) {
324 uss.mUnlockProgress.start();
325
326 // Prepare app storage before we go any further
327 uss.mUnlockProgress.setProgress(5,
Jorim Jaggi526694e2016-08-03 17:15:23 +0200328 mInjector.getContext().getString(R.string.android_start_title));
329 mInjector.getUserManager().onBeforeUnlockUser(userId);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200330 uss.mUnlockProgress.setProgress(20);
331
332 // Dispatch unlocked to system services; when fully dispatched,
333 // that calls through to the next "unlocked" phase
334 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
335 .sendToTarget();
336 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600337 }
338
339 /**
340 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
341 * {@link UserState#STATE_RUNNING_UNLOCKED}.
342 */
343 void finishUserUnlocked(final UserState uss) {
344 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700345 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600346 // Bail if we ended up with a stale user
347 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
348
349 // Only keep marching forward if user is actually unlocked
350 if (!StorageManager.isUserKeyUnlocked(userId)) return;
351
352 if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700353 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600354 uss.mUnlockProgress.finish();
Jeff Sharkey083807d2016-04-06 14:07:09 -0600355
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600356 // Dispatch unlocked to external apps
357 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
358 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
359 unlockedIntent.addFlags(
360 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700361 mInjector.broadcastIntentLocked(unlockedIntent, null, null, 0, null,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600362 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
363 userId);
364
365 if (getUserInfo(userId).isManagedProfile()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700366 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600367 if (parent != null) {
368 final Intent profileUnlockedIntent = new Intent(
369 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
370 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
371 profileUnlockedIntent.addFlags(
372 Intent.FLAG_RECEIVER_REGISTERED_ONLY
373 | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700374 mInjector.broadcastIntentLocked(profileUnlockedIntent,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600375 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
376 null, false, false, MY_PID, SYSTEM_UID,
377 parent.id);
378 }
379 }
380
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600381 // Send PRE_BOOT broadcasts if user fingerprint changed; we
382 // purposefully block sending BOOT_COMPLETED until after all
383 // PRE_BOOT receivers are finished to avoid ANR'ing apps
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600384 final UserInfo info = getUserInfo(userId);
385 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
Jeff Sharkey24d94912016-07-07 12:33:48 -0600386 // Suppress double notifications for managed profiles that
Jeff Sharkeyba066572016-07-18 10:11:36 -0600387 // were unlocked automatically as part of their parent user
388 // being unlocked.
389 final boolean quiet;
390 if (info.isManagedProfile()) {
391 quiet = !uss.tokenProvided
392 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
393 } else {
394 quiet = false;
395 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700396 mInjector.sendPreBootBroadcast(userId, quiet,
397 () -> finishUserUnlockedCompleted(uss));
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600398 } else {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600399 finishUserUnlockedCompleted(uss);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600400 }
401 }
402 }
403 }
404
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600405 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600406 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700407 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600408 // Bail if we ended up with a stale user
409 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700410 final UserInfo userInfo = getUserInfo(userId);
411 if (userInfo == null) {
412 return;
413 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600414
415 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600416 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600417
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600418 // Remember that we logged in
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700419 mInjector.getUserManager().onUserLoggedIn(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600420
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600421 if (!userInfo.isInitialized()) {
422 if (userId != UserHandle.USER_SYSTEM) {
423 Slog.d(TAG, "Initializing user #" + userId);
424 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
Christopher Tate42a386b2016-11-07 12:21:21 -0800425 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
426 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700427 mInjector.broadcastIntentLocked(intent, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600428 new IIntentReceiver.Stub() {
429 @Override
430 public void performReceive(Intent intent, int resultCode,
431 String data, Bundle extras, boolean ordered,
432 boolean sticky, int sendingUser) {
433 // Note: performReceive is called with mService lock held
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700434 mInjector.getUserManager().makeInitialized(userInfo.id);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600435 }
436 }, 0, null, null, null, AppOpsManager.OP_NONE,
437 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700438 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700439 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600440
Fyodor Kupolov5ddcca72017-04-28 17:38:10 -0700441 Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -0800442 // Do not report secondary users, runtime restarts or first boot/upgrade
443 if (userId == UserHandle.USER_SYSTEM
444 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800445 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
446 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
447 uptimeSeconds);
448 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600449 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
450 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
451 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
452 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolov5ddcca72017-04-28 17:38:10 -0700453 mInjector.broadcastIntentLocked(bootIntent, null, new IIntentReceiver.Stub() {
454 @Override
455 public void performReceive(Intent intent, int resultCode, String data,
456 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
457 throws RemoteException {
458 Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
459 }
460 }, 0, null, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600461 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
462 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700463 }
464 }
465
Andrew Scull85a63bc2016-10-24 13:47:47 +0100466 int restartUser(final int userId, final boolean foreground) {
467 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
468 @Override
469 public void userStopped(final int userId) {
470 // Post to the same handler that this callback is called from to ensure the user
471 // cleanup is complete before restarting.
472 mHandler.post(() -> startUser(userId, foreground));
473 }
474 @Override
475 public void userStopAborted(final int userId) {}
476 });
477 }
478
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700479 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700480 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700481 != PackageManager.PERMISSION_GRANTED) {
482 String msg = "Permission Denial: switchUser() from pid="
483 + Binder.getCallingPid()
484 + ", uid=" + Binder.getCallingUid()
485 + " requires " + INTERACT_ACROSS_USERS_FULL;
486 Slog.w(TAG, msg);
487 throw new SecurityException(msg);
488 }
489 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
490 throw new IllegalArgumentException("Can't stop system user " + userId);
491 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700492 mInjector.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
493 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700494 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700495 }
496 }
497
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700498 /**
499 * Stops the user along with its related users. The method calls
500 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
501 */
502 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
503 if (userId == UserHandle.USER_SYSTEM) {
504 return USER_OP_ERROR_IS_SYSTEM;
505 }
506 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700507 return USER_OP_IS_CURRENT;
508 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700509 int[] usersToStop = getUsersToStopLocked(userId);
510 // If one of related users is system or current, no related users should be stopped
511 for (int i = 0; i < usersToStop.length; i++) {
512 int relatedUserId = usersToStop[i];
513 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
514 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
515 + relatedUserId);
516 // We still need to stop the requested user if it's a force stop.
517 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800518 Slog.i(TAG,
519 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700520 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800521 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700522 }
523 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
524 }
525 }
526 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
527 for (int userIdToStop : usersToStop) {
528 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
529 }
530 return USER_OP_SUCCESS;
531 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700532
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700533 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
534 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700535 final UserState uss = mStartedUsers.get(userId);
536 if (uss == null) {
537 // User is not started, nothing to do... but we do need to
538 // callback if requested.
539 if (callback != null) {
540 mHandler.post(new Runnable() {
541 @Override
542 public void run() {
543 try {
544 callback.userStopped(userId);
545 } catch (RemoteException e) {
546 }
547 }
548 });
549 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700550 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700551 }
552
553 if (callback != null) {
554 uss.mStopCallbacks.add(callback);
555 }
556
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700557 if (uss.state != UserState.STATE_STOPPING
558 && uss.state != UserState.STATE_SHUTDOWN) {
559 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700560 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700561 updateStartedUserArrayLocked();
562
563 long ident = Binder.clearCallingIdentity();
564 try {
565 // We are going to broadcast ACTION_USER_STOPPING and then
566 // once that is done send a final ACTION_SHUTDOWN and then
567 // stop the user.
568 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
569 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
570 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
571 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700572 // This is the result receiver for the initial stopping broadcast.
573 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
574 @Override
575 public void performReceive(Intent intent, int resultCode, String data,
576 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700577 mHandler.post(new Runnable() {
578 @Override
579 public void run() {
580 finishUserStopping(userId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700581 }
Amith Yamasani98c05562016-03-30 13:15:26 -0700582 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700583 }
584 };
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700585 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700586 mInjector.clearBroadcastQueueForUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700587 // Kick things off.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700588 mInjector.broadcastIntentLocked(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700589 null, stoppingReceiver, 0, null, null,
590 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700591 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700592 } finally {
593 Binder.restoreCallingIdentity(ident);
594 }
595 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700596 }
597
Amith Yamasani98c05562016-03-30 13:15:26 -0700598 void finishUserStopping(final int userId, final UserState uss) {
599 // On to the next.
600 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
Christopher Tate98946b92017-06-13 12:11:09 -0700601 shutdownIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Amith Yamasani98c05562016-03-30 13:15:26 -0700602 // This is the result receiver for the final shutdown broadcast.
603 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
604 @Override
605 public void performReceive(Intent intent, int resultCode, String data,
606 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
607 mHandler.post(new Runnable() {
608 @Override
609 public void run() {
610 finishUserStopped(uss);
611 }
612 });
613 }
614 };
615
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700616 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700617 if (uss.state != UserState.STATE_STOPPING) {
618 // Whoops, we are being started back up. Abort, abort!
619 return;
620 }
621 uss.setState(UserState.STATE_SHUTDOWN);
622 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700623 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700624
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700625 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700626 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
627 Integer.toString(userId), userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700628 mInjector.systemServiceManagerStopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700629
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700630 synchronized (mLock) {
631 mInjector.broadcastIntentLocked(shutdownIntent,
Amith Yamasani98c05562016-03-30 13:15:26 -0700632 null, shutdownReceiver, 0, null, null, null,
633 AppOpsManager.OP_NONE,
634 null, true, false, MY_PID, SYSTEM_UID, userId);
635 }
636 }
637
638 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700639 final int userId = uss.mHandle.getIdentifier();
640 boolean stopped;
641 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700642 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700643 callbacks = new ArrayList<>(uss.mStopCallbacks);
644 if (mStartedUsers.get(userId) != uss) {
645 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700646 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700647 stopped = false;
648 } else {
649 stopped = true;
650 // User can no longer run.
651 mStartedUsers.remove(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700652 mInjector.getUserManagerInternal().removeUserState(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700653 mUserLru.remove(Integer.valueOf(userId));
654 updateStartedUserArrayLocked();
655
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700656 mInjector.activityManagerOnUserStopped(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700657 // Clean up all state and processes associated with the user.
658 // Kill all the processes for the user.
659 forceStopUserLocked(userId, "finish user");
660 }
661 }
662
663 for (int i = 0; i < callbacks.size(); i++) {
664 try {
665 if (stopped) callbacks.get(i).userStopped(userId);
666 else callbacks.get(i).userStopAborted(userId);
667 } catch (RemoteException e) {
668 }
669 }
670
671 if (stopped) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700672 mInjector.systemServiceManagerCleanupUser(userId);
673 synchronized (mLock) {
Tony Mak5c2cf032017-04-03 18:38:23 +0100674 mInjector.getActivityStackSupervisor().removeUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700675 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100676 // Remove the user if it is ephemeral.
677 if (getUserInfo(userId).isEphemeral()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700678 mInjector.getUserManager().removeUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100679 }
Pavel Grafov0502a4c2017-07-27 17:27:35 +0100680 // Evict the user's credential encryption key.
681 try {
682 getStorageManager().lockUserKey(userId);
683 } catch (RemoteException re) {
684 throw re.rethrowAsRuntimeException();
685 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700686 }
687 }
688
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700689 /**
690 * Determines the list of users that should be stopped together with the specified
691 * {@code userId}. The returned list includes {@code userId}.
692 */
693 private @NonNull int[] getUsersToStopLocked(int userId) {
694 int startedUsersSize = mStartedUsers.size();
695 IntArray userIds = new IntArray();
696 userIds.add(userId);
697 synchronized (mUserProfileGroupIdsSelfLocked) {
698 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
699 UserInfo.NO_PROFILE_GROUP_ID);
700 for (int i = 0; i < startedUsersSize; i++) {
701 UserState uss = mStartedUsers.valueAt(i);
702 int startedUserId = uss.mHandle.getIdentifier();
703 // Skip unrelated users (profileGroupId mismatch)
704 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
705 UserInfo.NO_PROFILE_GROUP_ID);
706 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
707 && (userGroupId == startedUserGroupId);
708 // userId has already been added
709 boolean sameUserId = startedUserId == userId;
710 if (!sameGroup || sameUserId) {
711 continue;
712 }
713 userIds.add(startedUserId);
714 }
715 }
716 return userIds.toArray();
717 }
718
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700719 private void forceStopUserLocked(int userId, String reason) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700720 mInjector.activityManagerForceStopPackageLocked(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700721 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
722 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
723 | Intent.FLAG_RECEIVER_FOREGROUND);
724 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700725 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700726 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700727 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700728 }
729
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700730 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100731 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700732 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100733 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700734 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700735 final int num = mUserLru.size();
736 for (int i = 0; i < num; i++) {
737 Integer oldUserId = mUserLru.get(i);
738 UserState oldUss = mStartedUsers.get(oldUserId);
739 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700740 || oldUss.state == UserState.STATE_STOPPING
741 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700742 continue;
743 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700744 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100745 if (userInfo.isEphemeral()) {
746 LocalServices.getService(UserManagerInternal.class)
747 .onEphemeralUserStop(oldUserId);
748 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100749 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700750 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700751 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700752 break;
753 }
754 }
755 }
756 }
757
758 void startProfilesLocked() {
759 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700760 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700761 mCurrentUserId, false /* enabledOnly */);
762 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
763 for (UserInfo user : profiles) {
764 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000765 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700766 profilesToStart.add(user);
767 }
768 }
769 final int profilesToStartSize = profilesToStart.size();
770 int i = 0;
771 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
772 startUser(profilesToStart.get(i).id, /* foreground= */ false);
773 }
774 if (i < profilesToStartSize) {
775 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
776 }
777 }
778
Sudheer Shanka2250d562016-11-07 15:41:02 -0800779 private IStorageManager getStorageManager() {
780 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700781 }
782
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700783 /**
784 * Start user, if its not already running.
785 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
786 * When starting the user, multiple intents will be broadcast in the following order:</p>
787 * <ul>
788 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
789 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
790 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
791 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
792 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
793 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
794 * Sent only if {@code foreground} parameter is true
795 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
796 * of the new fg user
797 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
798 * the new user
799 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
800 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
801 * new user. Sent only when the user is booting after a system update.
802 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
803 * new user. Sent only the first time a user is starting.
804 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
805 * user. Indicates that the user has finished booting.
806 * </ul>
807 *
808 * @param userId ID of the user to start
809 * @param foreground true if user should be brought to the foreground
810 * @return true if the user has been successfully started
811 */
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700812 boolean startUser(final int userId, final boolean foreground) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700813 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700814 != PackageManager.PERMISSION_GRANTED) {
815 String msg = "Permission Denial: switchUser() from pid="
816 + Binder.getCallingPid()
817 + ", uid=" + Binder.getCallingUid()
818 + " requires " + INTERACT_ACROSS_USERS_FULL;
819 Slog.w(TAG, msg);
820 throw new SecurityException(msg);
821 }
822
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700823 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700824
825 final long ident = Binder.clearCallingIdentity();
826 try {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700827 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700828 final int oldUserId = mCurrentUserId;
829 if (oldUserId == userId) {
830 return true;
831 }
832
Tony Mak5c2cf032017-04-03 18:38:23 +0100833 if (foreground) {
834 mInjector.getActivityStackSupervisor().setLockTaskModeLocked(
835 null, ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
836 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700837
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700838 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700839 if (userInfo == null) {
840 Slog.w(TAG, "No user info for user #" + userId);
841 return false;
842 }
843 if (foreground && userInfo.isManagedProfile()) {
844 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
845 return false;
846 }
847
Evan Rosky18396452016-07-27 15:19:37 -0700848 if (foreground && mUserSwitchUiEnabled) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700849 mInjector.getWindowManager().startFreezingScreen(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700850 R.anim.screen_user_exit, R.anim.screen_user_enter);
851 }
852
853 boolean needStart = false;
854
855 // If the user we are switching to is not currently started, then
856 // we need to start it now.
857 if (mStartedUsers.get(userId) == null) {
Amith Yamasaniea1b9d72016-05-27 15:57:38 +0000858 UserState userState = new UserState(UserHandle.of(userId));
859 mStartedUsers.put(userId, userState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700860 mInjector.getUserManagerInternal().setUserState(userId, userState.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700861 updateStartedUserArrayLocked();
862 needStart = true;
863 }
864
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800865 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700866 final Integer userIdInt = userId;
867 mUserLru.remove(userIdInt);
868 mUserLru.add(userIdInt);
869
870 if (foreground) {
871 mCurrentUserId = userId;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700872 mInjector.updateUserConfigurationLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700873 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
874 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700875 mInjector.getWindowManager().setCurrentUser(userId, mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700876 // Once the internal notion of the active user has switched, we lock the device
877 // with the option to show the user switcher on the keyguard.
Evan Rosky18396452016-07-27 15:19:37 -0700878 if (mUserSwitchUiEnabled) {
879 mInjector.getWindowManager().setSwitchingUser(true);
880 mInjector.getWindowManager().lockNow(null);
881 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700882 } else {
883 final Integer currentUserIdInt = mCurrentUserId;
884 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700885 mInjector.getWindowManager().setCurrentProfileIds(mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700886 mUserLru.remove(currentUserIdInt);
887 mUserLru.add(currentUserIdInt);
888 }
889
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700890 // Make sure user is in the started state. If it is currently
891 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700892 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700893 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
894 // so we can just fairly silently bring the user back from
895 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700896 uss.setState(uss.lastState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700897 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700898 updateStartedUserArrayLocked();
899 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700900 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700901 // This means ACTION_SHUTDOWN has been sent, so we will
902 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700903 uss.setState(UserState.STATE_BOOTING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700904 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700905 updateStartedUserArrayLocked();
906 needStart = true;
907 }
908
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700909 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700910 // Give user manager a chance to propagate user restrictions
911 // to other services and prepare app storage
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700912 mInjector.getUserManager().onBeforeStartUser(userId);
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800913
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700914 // Booting up a new user, need to tell system services about it.
915 // Note that this is on the same handler as scheduling of broadcasts,
916 // which is important because it needs to go first.
917 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
918 }
919
920 if (foreground) {
921 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
922 oldUserId));
923 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
924 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
925 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
926 oldUserId, userId, uss));
927 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
928 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
929 }
930
931 if (needStart) {
932 // Send USER_STARTED broadcast
933 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
934 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
935 | Intent.FLAG_RECEIVER_FOREGROUND);
936 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700937 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700938 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700939 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700940 }
941
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700942 if (foreground) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700943 moveUserToForegroundLocked(uss, oldUserId, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700944 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700945 finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700946 }
947
948 if (needStart) {
949 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
950 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
951 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700952 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700953 null, new IIntentReceiver.Stub() {
954 @Override
955 public void performReceive(Intent intent, int resultCode,
956 String data, Bundle extras, boolean ordered, boolean sticky,
957 int sendingUser) throws RemoteException {
958 }
959 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700960 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
961 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700962 }
963 }
964 } finally {
965 Binder.restoreCallingIdentity(ident);
966 }
967
968 return true;
969 }
970
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700971 /**
972 * Start user, if its not already running, and bring it to foreground.
973 */
Evan Rosky18396452016-07-27 15:19:37 -0700974 void startUserInForeground(final int targetUserId) {
975 boolean success = startUser(targetUserId, /* foreground */ true);
976 if (!success) {
977 mInjector.getWindowManager().setSwitchingUser(false);
978 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700979 }
980
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600981 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700982 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -0800983 != PackageManager.PERMISSION_GRANTED) {
984 String msg = "Permission Denial: unlockUser() from pid="
985 + Binder.getCallingPid()
986 + ", uid=" + Binder.getCallingUid()
987 + " requires " + INTERACT_ACROSS_USERS_FULL;
988 Slog.w(TAG, msg);
989 throw new SecurityException(msg);
990 }
991
Jeff Sharkey8924e872015-11-30 12:52:10 -0700992 final long binderToken = Binder.clearCallingIdentity();
993 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600994 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700995 } finally {
996 Binder.restoreCallingIdentity(binderToken);
997 }
998 }
999
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001000 /**
1001 * Attempt to unlock user without a credential token. This typically
1002 * succeeds when the device doesn't have credential-encrypted storage, or
1003 * when the the credential-encrypted storage isn't tied to a user-provided
1004 * PIN or pattern.
1005 */
1006 boolean maybeUnlockUser(final int userId) {
1007 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001008 return unlockUserCleared(userId, null, null, null);
1009 }
1010
1011 private static void notifyFinished(int userId, IProgressListener listener) {
1012 if (listener == null) return;
1013 try {
1014 listener.onFinished(userId, null);
1015 } catch (RemoteException ignored) {
1016 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001017 }
1018
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001019 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001020 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001021 UserState uss;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001022 synchronized (mLock) {
Ricky Wai4266fee2016-05-23 15:33:04 +01001023 // TODO Move this block outside of synchronized if it causes lock contention
1024 if (!StorageManager.isUserKeyUnlocked(userId)) {
1025 final UserInfo userInfo = getUserInfo(userId);
Sudheer Shanka2250d562016-11-07 15:41:02 -08001026 final IStorageManager storageManager = getStorageManager();
Ricky Wai4266fee2016-05-23 15:33:04 +01001027 try {
1028 // We always want to unlock user storage, even user is not started yet
Sudheer Shanka2250d562016-11-07 15:41:02 -08001029 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Ricky Wai4266fee2016-05-23 15:33:04 +01001030 } catch (RemoteException | RuntimeException e) {
1031 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
1032 }
1033 }
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001034 // Bail if user isn't actually running, otherwise register the given
1035 // listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001036 uss = mStartedUsers.get(userId);
Ricky Waif6ef8282016-04-14 10:00:22 +01001037 if (uss == null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001038 notifyFinished(userId, listener);
Ricky Waif6ef8282016-04-14 10:00:22 +01001039 return false;
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001040 } else {
1041 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001042 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001043 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001044 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001045
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001046 finishUserUnlocking(uss);
1047
1048 final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
Jorim Jaggi526694e2016-08-03 17:15:23 +02001049 synchronized (mLock) {
Jeff Sharkeyba512352015-11-12 20:17:45 -08001050
Jeff Sharkey7661a312016-04-07 12:39:57 -06001051 // We just unlocked a user, so let's now attempt to unlock any
1052 // managed profiles under that user.
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001053 for (int i = 0; i < mStartedUsers.size(); i++) {
1054 final int testUserId = mStartedUsers.keyAt(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001055 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001056 if (parent != null && parent.id == userId && testUserId != userId) {
Jeff Sharkey7661a312016-04-07 12:39:57 -06001057 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1058 + "): attempting unlock because parent was just unlocked");
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001059 childProfilesToUnlock.add(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001060 }
1061 }
1062 }
1063
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001064 final int size = childProfilesToUnlock.size();
1065 for (int i = 0; i < size; i++) {
1066 maybeUnlockUser(childProfilesToUnlock.valueAt(i));
1067 }
1068
Jeff Sharkeyba512352015-11-12 20:17:45 -08001069 return true;
1070 }
1071
Suprabh Shukla4fe508b2015-11-20 18:22:57 -08001072 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001073 // The dialog will show and then initiate the user switch by calling startUserInForeground
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001074 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001075 }
1076
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001077 void dispatchForegroundProfileChanged(int userId) {
1078 final int observerCount = mUserSwitchObservers.beginBroadcast();
1079 for (int i = 0; i < observerCount; i++) {
1080 try {
1081 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1082 } catch (RemoteException e) {
1083 // Ignore
1084 }
1085 }
1086 mUserSwitchObservers.finishBroadcast();
1087 }
1088
1089 /** Called on handler thread */
1090 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001091 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001092 final int observerCount = mUserSwitchObservers.beginBroadcast();
1093 for (int i = 0; i < observerCount; i++) {
1094 try {
1095 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1096 } catch (RemoteException e) {
1097 }
1098 }
1099 mUserSwitchObservers.finishBroadcast();
1100 }
1101
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001102 void dispatchLockedBootComplete(int userId) {
1103 final int observerCount = mUserSwitchObservers.beginBroadcast();
1104 for (int i = 0; i < observerCount; i++) {
1105 try {
1106 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1107 } catch (RemoteException e) {
1108 // Ignore
1109 }
1110 }
1111 mUserSwitchObservers.finishBroadcast();
1112 }
1113
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001114 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1115 // Never stop system user
1116 if (oldUserId == UserHandle.USER_SYSTEM) {
1117 return;
1118 }
1119 // For now, only check for user restriction. Additional checks can be added here
1120 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1121 oldUserId);
1122 if (!disallowRunInBg) {
1123 return;
1124 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001125 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001126 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1127 + " and related users");
1128 stopUsersLocked(oldUserId, false, null);
1129 }
1130 }
1131
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001132 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001133 synchronized (mLock) {
1134 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001135 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1136 }
1137 }
1138
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001139 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1140 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001141 final int observerCount = mUserSwitchObservers.beginBroadcast();
1142 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001143 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001144 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001145 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001146 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001147 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001148 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001149 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001150 for (int i = 0; i < observerCount; i++) {
1151 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001152 // Prepend with unique prefix to guarantee that keys are unique
1153 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001154 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001155 curWaitingUserSwitchCallbacks.add(name);
1156 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001157 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1158 @Override
1159 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001160 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001161 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
1162 if (delay > USER_SWITCH_TIMEOUT) {
1163 Slog.wtf(TAG, "User switch timeout: observer " + name
1164 + " sent result after " + delay + " ms");
1165 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001166 // Early return if this session is no longer valid
1167 if (curWaitingUserSwitchCallbacks
1168 != mCurWaitingUserSwitchCallbacks) {
1169 return;
1170 }
1171 curWaitingUserSwitchCallbacks.remove(name);
1172 // Continue switching if all callbacks have been notified
Fyodor Kupolov38641832016-06-28 17:37:09 -07001173 if (waitingCallbacksCount.decrementAndGet() == 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001174 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1175 }
1176 }
1177 }
1178 };
1179 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001180 } catch (RemoteException e) {
1181 }
1182 }
1183 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001184 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001185 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1186 }
1187 }
1188 mUserSwitchObservers.finishBroadcast();
1189 }
1190
1191 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001192 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001193 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1194 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
1195 oldUserId, newUserId, uss));
1196 }
1197
1198 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001199 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001200 if (mUserSwitchUiEnabled) {
1201 synchronized (mLock) {
1202 mInjector.getWindowManager().stopFreezingScreen();
1203 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001204 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001205 uss.switching = false;
1206 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1207 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1208 newUserId, 0));
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001209 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001210 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001211 }
1212
1213 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
Tony Mak5c2cf032017-04-03 18:38:23 +01001214 boolean homeInFront =
1215 mInjector.getActivityStackSupervisor().switchUserLocked(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001216 if (homeInFront) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001217 mInjector.startHomeActivityLocked(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001218 } else {
Tony Mak5c2cf032017-04-03 18:38:23 +01001219 mInjector.getActivityStackSupervisor().resumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001220 }
1221 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001222 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
1223 }
1224
1225 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1226 long ident = Binder.clearCallingIdentity();
1227 try {
1228 Intent intent;
1229 if (oldUserId >= 0) {
1230 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001231 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001232 int count = profiles.size();
1233 for (int i = 0; i < count; i++) {
1234 int profileUserId = profiles.get(i).id;
1235 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1237 | Intent.FLAG_RECEIVER_FOREGROUND);
1238 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001239 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001240 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1241 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1242 }
1243 }
1244 if (newUserId >= 0) {
1245 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001246 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001247 int count = profiles.size();
1248 for (int i = 0; i < count; i++) {
1249 int profileUserId = profiles.get(i).id;
1250 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1252 | Intent.FLAG_RECEIVER_FOREGROUND);
1253 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001254 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001255 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1256 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1257 }
1258 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1259 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1260 | Intent.FLAG_RECEIVER_FOREGROUND);
1261 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001262 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001263 null, null, 0, null, null,
1264 new String[] {android.Manifest.permission.MANAGE_USERS},
1265 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1266 UserHandle.USER_ALL);
1267 }
1268 } finally {
1269 Binder.restoreCallingIdentity(ident);
1270 }
1271 }
1272
1273
1274 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1275 int allowMode, String name, String callerPackage) {
1276 final int callingUserId = UserHandle.getUserId(callingUid);
1277 if (callingUserId == userId) {
1278 return userId;
1279 }
1280
1281 // Note that we may be accessing mCurrentUserId outside of a lock...
1282 // shouldn't be a big deal, if this is being called outside
1283 // of a locked context there is intrinsically a race with
1284 // the value the caller will receive and someone else changing it.
1285 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1286 // we will switch to the calling user if access to the current user fails.
1287 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1288
1289 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1290 final boolean allow;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001291 if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001292 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1293 // If the caller has this permission, they always pass go. And collect $200.
1294 allow = true;
1295 } else if (allowMode == ALLOW_FULL_ONLY) {
1296 // We require full access, sucks to be you.
1297 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001298 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001299 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1300 // If the caller does not have either permission, they are always doomed.
1301 allow = false;
1302 } else if (allowMode == ALLOW_NON_FULL) {
1303 // We are blanket allowing non-full access, you lucky caller!
1304 allow = true;
1305 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1306 // We may or may not allow this depending on whether the two users are
1307 // in the same profile.
1308 allow = isSameProfileGroup(callingUserId, targetUserId);
1309 } else {
1310 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1311 }
1312 if (!allow) {
1313 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1314 // In this case, they would like to just execute as their
1315 // owner user instead of failing.
1316 targetUserId = callingUserId;
1317 } else {
1318 StringBuilder builder = new StringBuilder(128);
1319 builder.append("Permission Denial: ");
1320 builder.append(name);
1321 if (callerPackage != null) {
1322 builder.append(" from ");
1323 builder.append(callerPackage);
1324 }
1325 builder.append(" asks to run as user ");
1326 builder.append(userId);
1327 builder.append(" but is calling from user ");
1328 builder.append(UserHandle.getUserId(callingUid));
1329 builder.append("; this requires ");
1330 builder.append(INTERACT_ACROSS_USERS_FULL);
1331 if (allowMode != ALLOW_FULL_ONLY) {
1332 builder.append(" or ");
1333 builder.append(INTERACT_ACROSS_USERS);
1334 }
1335 String msg = builder.toString();
1336 Slog.w(TAG, msg);
1337 throw new SecurityException(msg);
1338 }
1339 }
1340 }
1341 if (!allowAll && targetUserId < 0) {
1342 throw new IllegalArgumentException(
1343 "Call does not support special user #" + targetUserId);
1344 }
1345 // Check shell permission
1346 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1347 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1348 throw new SecurityException("Shell does not have permission to access user "
1349 + targetUserId + "\n " + Debug.getCallers(3));
1350 }
1351 }
1352 return targetUserId;
1353 }
1354
1355 int unsafeConvertIncomingUserLocked(int userId) {
1356 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1357 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001358 }
1359
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001360 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1361 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001362 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001363 != PackageManager.PERMISSION_GRANTED) {
1364 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1365 + Binder.getCallingPid()
1366 + ", uid=" + Binder.getCallingUid()
1367 + " requires " + INTERACT_ACROSS_USERS_FULL;
1368 Slog.w(TAG, msg);
1369 throw new SecurityException(msg);
1370 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001371 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001372 }
1373
1374 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1375 mUserSwitchObservers.unregister(observer);
1376 }
1377
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001378 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001379 return mStartedUsers.get(userId);
1380 }
1381
1382 boolean hasStartedUserState(int userId) {
1383 return mStartedUsers.get(userId) != null;
1384 }
1385
1386 private void updateStartedUserArrayLocked() {
1387 int num = 0;
1388 for (int i = 0; i < mStartedUsers.size(); i++) {
1389 UserState uss = mStartedUsers.valueAt(i);
1390 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001391 if (uss.state != UserState.STATE_STOPPING
1392 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001393 num++;
1394 }
1395 }
1396 mStartedUserArray = new int[num];
1397 num = 0;
1398 for (int i = 0; i < mStartedUsers.size(); i++) {
1399 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001400 if (uss.state != UserState.STATE_STOPPING
1401 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001402 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001403 }
1404 }
1405 }
1406
1407 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1408 for (int i = 0; i < mStartedUsers.size(); i++) {
1409 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001410 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001411 }
1412 }
1413
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001414 void onSystemReady() {
1415 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001416 }
1417
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001418 /**
1419 * Refreshes the list of users related to the current user when either a
1420 * user switch happens or when a new related user is started in the
1421 * background.
1422 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001423 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001424 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001425 false /* enabledOnly */);
1426 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1427 for (int i = 0; i < currentProfileIds.length; i++) {
1428 currentProfileIds[i] = profiles.get(i).id;
1429 }
1430 mCurrentProfileIds = currentProfileIds;
1431
1432 synchronized (mUserProfileGroupIdsSelfLocked) {
1433 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001434 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001435 for (int i = 0; i < users.size(); i++) {
1436 UserInfo user = users.get(i);
1437 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1438 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1439 }
1440 }
1441 }
1442 }
1443
1444 int[] getStartedUserArrayLocked() {
1445 return mStartedUserArray;
1446 }
1447
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001448 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001449 UserState state = getStartedUserStateLocked(userId);
1450 if (state == null) {
1451 return false;
1452 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001453 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001454 return true;
1455 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001456 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001457 switch (state.state) {
1458 case UserState.STATE_BOOTING:
1459 case UserState.STATE_RUNNING_LOCKED:
1460 return true;
1461 default:
1462 return false;
1463 }
1464 }
1465 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1466 switch (state.state) {
1467 case UserState.STATE_RUNNING_UNLOCKING:
1468 case UserState.STATE_RUNNING_UNLOCKED:
1469 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001470 // In the stopping/shutdown state return unlock state of the user key
1471 case UserState.STATE_STOPPING:
1472 case UserState.STATE_SHUTDOWN:
1473 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001474 default:
1475 return false;
1476 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001477 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001478 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001479 switch (state.state) {
1480 case UserState.STATE_RUNNING_UNLOCKED:
1481 return true;
Fyodor Kupolov0468ee92017-05-25 17:06:17 -07001482 // In the stopping/shutdown state return unlock state of the user key
1483 case UserState.STATE_STOPPING:
1484 case UserState.STATE_SHUTDOWN:
1485 return StorageManager.isUserKeyUnlocked(userId);
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001486 default:
1487 return false;
1488 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001489 }
1490
Fyodor Kupolova24e81219f2017-06-23 12:28:39 -07001491 return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001492 }
1493
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001494 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001495 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001496 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001497 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001498 != PackageManager.PERMISSION_GRANTED)) {
1499 String msg = "Permission Denial: getCurrentUser() from pid="
1500 + Binder.getCallingPid()
1501 + ", uid=" + Binder.getCallingUid()
1502 + " requires " + INTERACT_ACROSS_USERS;
1503 Slog.w(TAG, msg);
1504 throw new SecurityException(msg);
1505 }
Fyodor Kupolovdcb26bb2017-05-09 17:06:52 -07001506
1507 // Optimization - if there is no pending user switch, return current id
1508 if (mTargetUserId == UserHandle.USER_NULL) {
1509 return getUserInfo(mCurrentUserId);
1510 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001511 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001512 return getCurrentUserLocked();
1513 }
1514 }
1515
1516 UserInfo getCurrentUserLocked() {
1517 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001518 return getUserInfo(userId);
1519 }
1520
1521 int getCurrentOrTargetUserIdLocked() {
1522 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001523 }
1524
1525 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001526 return mCurrentUserId;
1527 }
1528
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001529 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001530 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001531 }
1532
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001533 int setTargetUserIdLocked(int targetUserId) {
1534 return mTargetUserId = targetUserId;
1535 }
1536
1537 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001538 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001539 return ums != null ? ums.getUserIds() : new int[] { 0 };
1540 }
1541
1542 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001543 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001544 }
1545
1546 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001547 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001548 }
1549
1550 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001551 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001552 }
1553
1554 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001555 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001556 }
1557
1558 Set<Integer> getProfileIds(int userId) {
1559 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001560 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001561 false /* enabledOnly */);
1562 for (UserInfo user : profiles) {
1563 userIds.add(user.id);
1564 }
1565 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001566 }
1567
1568 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001569 if (callingUserId == targetUserId) {
1570 return true;
1571 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001572 synchronized (mUserProfileGroupIdsSelfLocked) {
1573 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1574 UserInfo.NO_PROFILE_GROUP_ID);
1575 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1576 UserInfo.NO_PROFILE_GROUP_ID);
1577 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1578 && callingProfile == targetProfile;
1579 }
1580 }
1581
1582 boolean isCurrentProfileLocked(int userId) {
1583 return ArrayUtils.contains(mCurrentProfileIds, userId);
1584 }
1585
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001586 int[] getCurrentProfileIdsLocked() {
1587 return mCurrentProfileIds;
1588 }
1589
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001590 /**
1591 * Returns whether the given user requires credential entry at this time. This is used to
1592 * intercept activity launches for work apps when the Work Challenge is present.
1593 */
Benjamin Franz563707b2017-06-29 15:06:13 +01001594 protected boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001595 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001596 if (mStartedUsers.get(userId) == null) {
1597 return false;
1598 }
1599 }
Clara Bayarria1771112015-12-18 16:29:18 +00001600 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001601 return false;
1602 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001603 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001604 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001605 }
1606
Tony Mak8c536f92016-03-21 12:20:41 +00001607 boolean isLockScreenDisabled(@UserIdInt int userId) {
1608 return mLockPatternUtils.isLockScreenDisabled(userId);
1609 }
1610
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001611 void dump(PrintWriter pw, boolean dumpAll) {
1612 pw.println(" mStartedUsers:");
1613 for (int i = 0; i < mStartedUsers.size(); i++) {
1614 UserState uss = mStartedUsers.valueAt(i);
1615 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1616 pw.print(": "); uss.dump("", pw);
1617 }
1618 pw.print(" mStartedUserArray: [");
1619 for (int i = 0; i < mStartedUserArray.length; i++) {
1620 if (i > 0) pw.print(", ");
1621 pw.print(mStartedUserArray[i]);
1622 }
1623 pw.println("]");
1624 pw.print(" mUserLru: [");
1625 for (int i = 0; i < mUserLru.size(); i++) {
1626 if (i > 0) pw.print(", ");
1627 pw.print(mUserLru.get(i));
1628 }
1629 pw.println("]");
1630 if (dumpAll) {
1631 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1632 }
1633 synchronized (mUserProfileGroupIdsSelfLocked) {
1634 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1635 pw.println(" mUserProfileGroupIds:");
1636 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1637 pw.print(" User #");
1638 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1639 pw.print(" -> profile #");
1640 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1641 }
1642 }
1643 }
1644 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001645
1646 @VisibleForTesting
1647 static class Injector {
1648 private final ActivityManagerService mService;
1649 private UserManagerService mUserManager;
1650 private UserManagerInternal mUserManagerInternal;
1651
1652 Injector(ActivityManagerService service) {
1653 mService = service;
1654 }
1655
1656 protected Object getLock() {
1657 return mService;
1658 }
1659
1660 protected Handler getHandler() {
1661 return mService.mHandler;
1662 }
1663
1664 protected Context getContext() {
1665 return mService.mContext;
1666 }
1667
1668 protected LockPatternUtils getLockPatternUtils() {
1669 return new LockPatternUtils(getContext());
1670 }
1671
1672 protected int broadcastIntentLocked(Intent intent, String resolvedType,
1673 IIntentReceiver resultTo, int resultCode, String resultData,
1674 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
1675 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
1676 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
1677 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
1678 ordered, sticky, callingPid, callingUid, userId);
1679 }
1680
1681 int checkCallingPermission(String permission) {
1682 return mService.checkCallingPermission(permission);
1683 }
1684
1685 WindowManagerService getWindowManager() {
1686 return mService.mWindowManager;
1687 }
1688 void activityManagerOnUserStopped(int userId) {
1689 mService.onUserStoppedLocked(userId);
1690 }
1691
1692 void systemServiceManagerCleanupUser(int userId) {
1693 mService.mSystemServiceManager.cleanupUser(userId);
1694 }
1695
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001696 protected UserManagerService getUserManager() {
1697 if (mUserManager == null) {
1698 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
1699 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
1700 }
1701 return mUserManager;
1702 }
1703
1704 UserManagerInternal getUserManagerInternal() {
1705 if (mUserManagerInternal == null) {
1706 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1707 }
1708 return mUserManagerInternal;
1709 }
1710
1711 KeyguardManager getKeyguardManager() {
1712 return mService.mContext.getSystemService(KeyguardManager.class);
1713 }
1714
1715 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
1716 mService.mBatteryStatsService.noteEvent(code, name, uid);
1717 }
1718
1719 void systemServiceManagerStopUser(int userId) {
1720 mService.mSystemServiceManager.stopUser(userId);
1721 }
1722
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08001723 boolean isRuntimeRestarted() {
1724 return mService.mSystemServiceManager.isRuntimeRestarted();
1725 }
1726
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08001727 boolean isFirstBootOrUpgrade() {
1728 IPackageManager pm = AppGlobals.getPackageManager();
1729 try {
1730 return pm.isFirstBoot() || pm.isUpgrade();
1731 } catch (RemoteException e) {
1732 throw e.rethrowFromSystemServer();
1733 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08001734 }
1735
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001736 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
1737 new PreBootBroadcaster(mService, userId, null, quiet) {
1738 @Override
1739 public void onFinished() {
1740 onFinish.run();
1741 }
1742 }.sendNext();
1743 }
1744
1745 void activityManagerForceStopPackageLocked(int userId, String reason) {
1746 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
1747 userId, reason);
1748 };
1749
1750 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
1751 boolean exported) {
1752 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
1753 }
1754
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001755 void startHomeActivityLocked(int userId, String reason) {
1756 mService.startHomeActivityLocked(userId, reason);
1757 }
1758
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001759 void updateUserConfigurationLocked() {
1760 mService.updateUserConfigurationLocked();
1761 }
1762
1763 void clearBroadcastQueueForUserLocked(int userId) {
1764 mService.clearBroadcastQueueForUserLocked(userId);
1765 }
1766
1767 void enforceShellRestriction(String restriction, int userId) {
1768 mService.enforceShellRestriction(restriction, userId);
1769 }
1770
1771 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser) {
1772 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
1773 true /* above system */);
1774 d.show();
1775 }
Tony Mak5c2cf032017-04-03 18:38:23 +01001776
1777 ActivityStackSupervisor getActivityStackSupervisor() {
1778 return mService.mStackSupervisor;
1779 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001780 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001781}