blob: 3b5e5bcce7aeb0fa458d79933f6809fce69dc796 [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;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000025import static android.content.Context.KEYGUARD_SERVICE;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070026import static android.os.Process.SYSTEM_UID;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060027
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;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070035import static com.android.server.am.ActivityManagerService.REPORT_LOCKED_BOOT_COMPLETE_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070036import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
37import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
38import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
39import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -070040import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070041import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060042import static com.android.server.am.UserState.STATE_BOOTING;
43import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
44import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
45import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070046
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070047import android.annotation.NonNull;
Tony Mak8c536f92016-03-21 12:20:41 +000048import android.annotation.UserIdInt;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070049import android.app.ActivityManager;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080050import android.app.AppGlobals;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070051import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070052import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070053import android.app.IStopUserCallback;
54import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000055import android.app.KeyguardManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070056import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070057import android.content.IIntentReceiver;
58import android.content.Intent;
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -080059import android.content.pm.IPackageManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070060import android.content.pm.PackageManager;
61import android.content.pm.UserInfo;
62import android.os.BatteryStats;
63import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060064import android.os.Build;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070065import android.os.Bundle;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070066import android.os.Debug;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070067import android.os.Handler;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070068import android.os.IBinder;
Jeff Sharkey84a4c972016-04-18 15:36:39 -060069import android.os.IProgressListener;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070070import android.os.IRemoteCallback;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070071import android.os.IUserManager;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070072import android.os.Process;
73import android.os.RemoteCallbackList;
74import android.os.RemoteException;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070075import android.os.ServiceManager;
James Hawkins899608a2016-05-27 11:15:06 -070076import android.os.SystemClock;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070077import android.os.UserHandle;
78import android.os.UserManager;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010079import android.os.UserManagerInternal;
Sudheer Shanka2250d562016-11-07 15:41:02 -080080import android.os.storage.IStorageManager;
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -080081import android.os.storage.StorageManager;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070082import android.util.ArraySet;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -070083import android.util.IntArray;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080084import android.util.Pair;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070085import android.util.Slog;
86import android.util.SparseArray;
87import android.util.SparseIntArray;
88
89import com.android.internal.R;
Jeff Sharkeyba512352015-11-12 20:17:45 -080090import com.android.internal.annotations.GuardedBy;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070091import com.android.internal.annotations.VisibleForTesting;
James Hawkins899608a2016-05-27 11:15:06 -070092import com.android.internal.logging.MetricsLogger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070093import com.android.internal.util.ArrayUtils;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -070094import com.android.internal.util.Preconditions;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000095import com.android.internal.widget.LockPatternUtils;
Lenka Trochtova1ddda472016-02-12 10:42:12 +010096import com.android.server.LocalServices;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070097import com.android.server.pm.UserManagerService;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -070098import com.android.server.wm.WindowManagerService;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070099
100import java.io.PrintWriter;
101import java.util.ArrayList;
102import java.util.Arrays;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700103import java.util.HashSet;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700104import java.util.List;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600105import java.util.Objects;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700106import java.util.Set;
Fyodor Kupolov38641832016-06-28 17:37:09 -0700107import java.util.concurrent.atomic.AtomicInteger;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700108
109/**
110 * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
111 */
112final class UserController {
113 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
Jeff Sharkeyfd241082016-04-19 15:58:24 -0600114
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700115 // Maximum number of users we allow to be running at a time.
116 static final int MAX_RUNNING_USERS = 3;
117
118 // Amount of time we wait for observers to handle a user switch before
119 // giving up on them and unfreezing the screen.
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -0700120 static final int USER_SWITCH_TIMEOUT = 3 * 1000;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700121
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700122 private final Object mLock;
123 private final Injector mInjector;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700124 private final Handler mHandler;
125
126 // Holds the current foreground user's id
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700127 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700128 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700129 // Holds the target user's id during a user switch
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700130 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700131 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700132
133 /**
134 * Which users have been started, so are allowed to run code.
135 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700136 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700137 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800138
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700139 /**
140 * LRU list of history of current users. Most recently current is at the end.
141 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700142 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700143 private final ArrayList<Integer> mUserLru = new ArrayList<>();
144
145 /**
146 * Constant array of the users that are currently started.
147 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700148 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700149 private int[] mStartedUserArray = new int[] { 0 };
150
151 // If there are multiple profiles for the current user, their ids are here
152 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700153 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700154 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700155
156 /**
157 * Mapping from each known user ID to the profile group ID it is associated with.
158 */
159 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
160
161 /**
162 * Registered observers of the user switching mechanics.
163 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700164 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700165 = new RemoteCallbackList<>();
166
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700167 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700168
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700169 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700170 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700171 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700172 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700173 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700174
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700175 private volatile UserManagerService mUserManager;
176
Clara Bayarria1771112015-12-18 16:29:18 +0000177 private final LockPatternUtils mLockPatternUtils;
178
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700179 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700180 this(new Injector(service));
181 }
182
183 @VisibleForTesting
184 UserController(Injector injector) {
185 mInjector = injector;
186 mLock = injector.getLock();
187 mHandler = injector.getHandler();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700188 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800189 final UserState uss = new UserState(UserHandle.SYSTEM);
190 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700191 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700192 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700193 updateStartedUserArrayLocked();
194 }
195
196 void finishUserSwitch(UserState uss) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700197 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700198 finishUserBoot(uss);
199
200 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700201 stopRunningUsersLocked(MAX_RUNNING_USERS);
202 }
203 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700204
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700205 void stopRunningUsersLocked(int maxRunningUsers) {
206 int num = mUserLru.size();
207 int i = 0;
208 while (num > maxRunningUsers && i < mUserLru.size()) {
209 Integer oldUserId = mUserLru.get(i);
210 UserState oldUss = mStartedUsers.get(oldUserId);
211 if (oldUss == null) {
212 // Shouldn't happen, but be sane if it does.
213 mUserLru.remove(i);
214 num--;
215 continue;
216 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700217 if (oldUss.state == UserState.STATE_STOPPING
218 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700219 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700220 num--;
221 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700222 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700223 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700224 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
225 // Owner/System user and current user can't be stopped. We count it as running
226 // when it is not a pure system user.
227 if (UserInfo.isSystemOnly(oldUserId)) {
228 num--;
229 }
230 i++;
231 continue;
232 }
233 // This is a user to be stopped.
234 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
235 num--;
236 }
237 num--;
238 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700239 }
240 }
241
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800242 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700243 finishUserBoot(uss, null);
244 }
245
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800246 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700247 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700248
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700249 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700250 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700251 // Bail if we ended up with a stale user
252 if (mStartedUsers.get(userId) != uss) return;
253
254 // We always walk through all the user lifecycle states to send
255 // consistent developer events. We step into RUNNING_LOCKED here,
256 // but we might immediately step into RUNNING below if the user
257 // storage is already unlocked.
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600258 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700259 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -0800260 // Do not report secondary users, runtime restarts or first boot/upgrade
261 if (userId == UserHandle.USER_SYSTEM
262 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800263 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
264 MetricsLogger.histogram(mInjector.getContext(),
265 "framework_locked_boot_completed", uptimeSeconds);
Fyodor Kupolov24e12dc2017-01-17 12:20:36 -0800266 final int MAX_UPTIME_SECONDS = 120;
267 if (uptimeSeconds > MAX_UPTIME_SECONDS) {
268 Slog.wtf("SystemServerTiming",
269 "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
270 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800271 }
James Hawkins899608a2016-05-27 11:15:06 -0700272
Sudheer Shanka2c4522c2016-08-27 20:53:28 -0700273 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
274 userId, 0));
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700275 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700276 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700277 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
278 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700279 mInjector.broadcastIntentLocked(intent, null, resultTo, 0, null, null,
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700280 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
281 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
282 }
283
Jeff Sharkey7661a312016-04-07 12:39:57 -0600284 // We need to delay unlocking managed profiles until the parent user
285 // is also unlocked.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700286 if (mInjector.getUserManager().isManagedProfile(userId)) {
287 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey7661a312016-04-07 12:39:57 -0600288 if (parent != null
289 && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
290 Slog.d(TAG, "User " + userId + " (parent " + parent.id
291 + "): attempting unlock because parent is unlocked");
292 maybeUnlockUser(userId);
293 } else {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700294 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
295 Slog.d(TAG, "User " + userId + " (parent " + parentId
Jeff Sharkey7661a312016-04-07 12:39:57 -0600296 + "): delaying unlock because parent is locked");
297 }
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600298 } else {
299 maybeUnlockUser(userId);
300 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700301 }
302 }
303
304 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600305 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
306 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700307 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600308 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700309 final int userId = uss.mHandle.getIdentifier();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200310 boolean proceedWithUnlock = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700311 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700312 // Bail if we ended up with a stale user
313 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
314
315 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600316 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700317
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600318 if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700319 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200320 proceedWithUnlock = true;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600321 }
322 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200323
324 if (proceedWithUnlock) {
325 uss.mUnlockProgress.start();
326
327 // Prepare app storage before we go any further
328 uss.mUnlockProgress.setProgress(5,
Jorim Jaggi526694e2016-08-03 17:15:23 +0200329 mInjector.getContext().getString(R.string.android_start_title));
330 mInjector.getUserManager().onBeforeUnlockUser(userId);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200331 uss.mUnlockProgress.setProgress(20);
332
333 // Dispatch unlocked to system services; when fully dispatched,
334 // that calls through to the next "unlocked" phase
335 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
336 .sendToTarget();
337 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600338 }
339
340 /**
341 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
342 * {@link UserState#STATE_RUNNING_UNLOCKED}.
343 */
344 void finishUserUnlocked(final UserState uss) {
345 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700346 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600347 // Bail if we ended up with a stale user
348 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
349
350 // Only keep marching forward if user is actually unlocked
351 if (!StorageManager.isUserKeyUnlocked(userId)) return;
352
353 if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700354 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600355 uss.mUnlockProgress.finish();
Jeff Sharkey083807d2016-04-06 14:07:09 -0600356
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600357 // Dispatch unlocked to external apps
358 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
359 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
360 unlockedIntent.addFlags(
361 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700362 mInjector.broadcastIntentLocked(unlockedIntent, null, null, 0, null,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600363 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
364 userId);
365
366 if (getUserInfo(userId).isManagedProfile()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700367 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600368 if (parent != null) {
369 final Intent profileUnlockedIntent = new Intent(
370 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
371 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
372 profileUnlockedIntent.addFlags(
373 Intent.FLAG_RECEIVER_REGISTERED_ONLY
374 | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700375 mInjector.broadcastIntentLocked(profileUnlockedIntent,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600376 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
377 null, false, false, MY_PID, SYSTEM_UID,
378 parent.id);
379 }
380 }
381
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600382 // Send PRE_BOOT broadcasts if user fingerprint changed; we
383 // purposefully block sending BOOT_COMPLETED until after all
384 // PRE_BOOT receivers are finished to avoid ANR'ing apps
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600385 final UserInfo info = getUserInfo(userId);
386 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
Jeff Sharkey24d94912016-07-07 12:33:48 -0600387 // Suppress double notifications for managed profiles that
Jeff Sharkeyba066572016-07-18 10:11:36 -0600388 // were unlocked automatically as part of their parent user
389 // being unlocked.
390 final boolean quiet;
391 if (info.isManagedProfile()) {
392 quiet = !uss.tokenProvided
393 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
394 } else {
395 quiet = false;
396 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700397 mInjector.sendPreBootBroadcast(userId, quiet,
398 () -> finishUserUnlockedCompleted(uss));
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600399 } else {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600400 finishUserUnlockedCompleted(uss);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600401 }
402 }
403 }
404 }
405
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600406 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600407 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700408 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600409 // Bail if we ended up with a stale user
410 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700411 final UserInfo userInfo = getUserInfo(userId);
412 if (userInfo == null) {
413 return;
414 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600415
416 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600417 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600418
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600419 // Remember that we logged in
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700420 mInjector.getUserManager().onUserLoggedIn(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600421
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600422 if (!userInfo.isInitialized()) {
423 if (userId != UserHandle.USER_SYSTEM) {
424 Slog.d(TAG, "Initializing user #" + userId);
425 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
Christopher Tate42a386b2016-11-07 12:21:21 -0800426 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
427 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700428 mInjector.broadcastIntentLocked(intent, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600429 new IIntentReceiver.Stub() {
430 @Override
431 public void performReceive(Intent intent, int resultCode,
432 String data, Bundle extras, boolean ordered,
433 boolean sticky, int sendingUser) {
434 // Note: performReceive is called with mService lock held
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700435 mInjector.getUserManager().makeInitialized(userInfo.id);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600436 }
437 }, 0, null, null, null, AppOpsManager.OP_NONE,
438 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700439 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700440 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600441
442 Slog.d(TAG, "Sending BOOT_COMPLETE user #" + userId);
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -0800443 // Do not report secondary users, runtime restarts or first boot/upgrade
444 if (userId == UserHandle.USER_SYSTEM
445 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
Fyodor Kupolov1d87e402017-01-10 18:34:10 -0800446 int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
447 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
448 uptimeSeconds);
449 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600450 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
451 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
452 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
453 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700454 mInjector.broadcastIntentLocked(bootIntent, null, null, 0, null, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600455 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
456 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700457 }
458 }
459
Andrew Scull85a63bc2016-10-24 13:47:47 +0100460 int restartUser(final int userId, final boolean foreground) {
461 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
462 @Override
463 public void userStopped(final int userId) {
464 // Post to the same handler that this callback is called from to ensure the user
465 // cleanup is complete before restarting.
466 mHandler.post(() -> startUser(userId, foreground));
467 }
468 @Override
469 public void userStopAborted(final int userId) {}
470 });
471 }
472
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700473 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700474 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700475 != PackageManager.PERMISSION_GRANTED) {
476 String msg = "Permission Denial: switchUser() from pid="
477 + Binder.getCallingPid()
478 + ", uid=" + Binder.getCallingUid()
479 + " requires " + INTERACT_ACROSS_USERS_FULL;
480 Slog.w(TAG, msg);
481 throw new SecurityException(msg);
482 }
483 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
484 throw new IllegalArgumentException("Can't stop system user " + userId);
485 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700486 mInjector.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
487 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700488 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700489 }
490 }
491
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700492 /**
493 * Stops the user along with its related users. The method calls
494 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
495 */
496 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
497 if (userId == UserHandle.USER_SYSTEM) {
498 return USER_OP_ERROR_IS_SYSTEM;
499 }
500 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700501 return USER_OP_IS_CURRENT;
502 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700503 int[] usersToStop = getUsersToStopLocked(userId);
504 // If one of related users is system or current, no related users should be stopped
505 for (int i = 0; i < usersToStop.length; i++) {
506 int relatedUserId = usersToStop[i];
507 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
508 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
509 + relatedUserId);
510 // We still need to stop the requested user if it's a force stop.
511 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800512 Slog.i(TAG,
513 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700514 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800515 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700516 }
517 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
518 }
519 }
520 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
521 for (int userIdToStop : usersToStop) {
522 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
523 }
524 return USER_OP_SUCCESS;
525 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700526
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700527 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
528 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700529 final UserState uss = mStartedUsers.get(userId);
530 if (uss == null) {
531 // User is not started, nothing to do... but we do need to
532 // callback if requested.
533 if (callback != null) {
534 mHandler.post(new Runnable() {
535 @Override
536 public void run() {
537 try {
538 callback.userStopped(userId);
539 } catch (RemoteException e) {
540 }
541 }
542 });
543 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700544 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700545 }
546
547 if (callback != null) {
548 uss.mStopCallbacks.add(callback);
549 }
550
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700551 if (uss.state != UserState.STATE_STOPPING
552 && uss.state != UserState.STATE_SHUTDOWN) {
553 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700554 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700555 updateStartedUserArrayLocked();
556
557 long ident = Binder.clearCallingIdentity();
558 try {
559 // We are going to broadcast ACTION_USER_STOPPING and then
560 // once that is done send a final ACTION_SHUTDOWN and then
561 // stop the user.
562 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
563 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
564 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
565 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700566 // This is the result receiver for the initial stopping broadcast.
567 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
568 @Override
569 public void performReceive(Intent intent, int resultCode, String data,
570 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700571 mHandler.post(new Runnable() {
572 @Override
573 public void run() {
574 finishUserStopping(userId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700575 }
Amith Yamasani98c05562016-03-30 13:15:26 -0700576 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700577 }
578 };
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700579 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700580 mInjector.clearBroadcastQueueForUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700581 // Kick things off.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700582 mInjector.broadcastIntentLocked(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700583 null, stoppingReceiver, 0, null, null,
584 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700585 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700586 } finally {
587 Binder.restoreCallingIdentity(ident);
588 }
589 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700590 }
591
Amith Yamasani98c05562016-03-30 13:15:26 -0700592 void finishUserStopping(final int userId, final UserState uss) {
593 // On to the next.
594 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
595 // This is the result receiver for the final shutdown broadcast.
596 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
597 @Override
598 public void performReceive(Intent intent, int resultCode, String data,
599 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
600 mHandler.post(new Runnable() {
601 @Override
602 public void run() {
603 finishUserStopped(uss);
604 }
605 });
606 }
607 };
608
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700609 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700610 if (uss.state != UserState.STATE_STOPPING) {
611 // Whoops, we are being started back up. Abort, abort!
612 return;
613 }
614 uss.setState(UserState.STATE_SHUTDOWN);
615 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700616 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700617
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700618 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700619 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
620 Integer.toString(userId), userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700621 mInjector.systemServiceManagerStopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700622
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700623 synchronized (mLock) {
624 mInjector.broadcastIntentLocked(shutdownIntent,
Amith Yamasani98c05562016-03-30 13:15:26 -0700625 null, shutdownReceiver, 0, null, null, null,
626 AppOpsManager.OP_NONE,
627 null, true, false, MY_PID, SYSTEM_UID, userId);
628 }
629 }
630
631 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700632 final int userId = uss.mHandle.getIdentifier();
633 boolean stopped;
634 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700635 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700636 callbacks = new ArrayList<>(uss.mStopCallbacks);
637 if (mStartedUsers.get(userId) != uss) {
638 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700639 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700640 stopped = false;
641 } else {
642 stopped = true;
643 // User can no longer run.
644 mStartedUsers.remove(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700645 mInjector.getUserManagerInternal().removeUserState(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700646 mUserLru.remove(Integer.valueOf(userId));
647 updateStartedUserArrayLocked();
648
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700649 mInjector.activityManagerOnUserStopped(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700650 // Clean up all state and processes associated with the user.
651 // Kill all the processes for the user.
652 forceStopUserLocked(userId, "finish user");
653 }
654 }
655
656 for (int i = 0; i < callbacks.size(); i++) {
657 try {
658 if (stopped) callbacks.get(i).userStopped(userId);
659 else callbacks.get(i).userStopAborted(userId);
660 } catch (RemoteException e) {
661 }
662 }
663
664 if (stopped) {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100665 // Evict the user's credential encryption key
666 try {
667 getStorageManager().lockUserKey(userId);
668 } catch (RemoteException re) {
669 throw re.rethrowAsRuntimeException();
670 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700671 mInjector.systemServiceManagerCleanupUser(userId);
672 synchronized (mLock) {
Tony Mak5c2cf032017-04-03 18:38:23 +0100673 mInjector.getActivityStackSupervisor().removeUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700674 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100675 // Remove the user if it is ephemeral.
676 if (getUserInfo(userId).isEphemeral()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700677 mInjector.getUserManager().removeUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100678 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700679 }
680 }
681
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700682 /**
683 * Determines the list of users that should be stopped together with the specified
684 * {@code userId}. The returned list includes {@code userId}.
685 */
686 private @NonNull int[] getUsersToStopLocked(int userId) {
687 int startedUsersSize = mStartedUsers.size();
688 IntArray userIds = new IntArray();
689 userIds.add(userId);
690 synchronized (mUserProfileGroupIdsSelfLocked) {
691 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
692 UserInfo.NO_PROFILE_GROUP_ID);
693 for (int i = 0; i < startedUsersSize; i++) {
694 UserState uss = mStartedUsers.valueAt(i);
695 int startedUserId = uss.mHandle.getIdentifier();
696 // Skip unrelated users (profileGroupId mismatch)
697 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
698 UserInfo.NO_PROFILE_GROUP_ID);
699 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
700 && (userGroupId == startedUserGroupId);
701 // userId has already been added
702 boolean sameUserId = startedUserId == userId;
703 if (!sameGroup || sameUserId) {
704 continue;
705 }
706 userIds.add(startedUserId);
707 }
708 }
709 return userIds.toArray();
710 }
711
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700712 private void forceStopUserLocked(int userId, String reason) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700713 mInjector.activityManagerForceStopPackageLocked(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700714 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
715 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
716 | Intent.FLAG_RECEIVER_FOREGROUND);
717 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700718 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700719 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700720 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700721 }
722
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700723 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100724 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700725 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100726 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700727 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700728 final int num = mUserLru.size();
729 for (int i = 0; i < num; i++) {
730 Integer oldUserId = mUserLru.get(i);
731 UserState oldUss = mStartedUsers.get(oldUserId);
732 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700733 || oldUss.state == UserState.STATE_STOPPING
734 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700735 continue;
736 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700737 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100738 if (userInfo.isEphemeral()) {
739 LocalServices.getService(UserManagerInternal.class)
740 .onEphemeralUserStop(oldUserId);
741 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100742 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700743 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700744 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700745 break;
746 }
747 }
748 }
749 }
750
751 void startProfilesLocked() {
752 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700753 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700754 mCurrentUserId, false /* enabledOnly */);
755 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
756 for (UserInfo user : profiles) {
757 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000758 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700759 profilesToStart.add(user);
760 }
761 }
762 final int profilesToStartSize = profilesToStart.size();
763 int i = 0;
764 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
765 startUser(profilesToStart.get(i).id, /* foreground= */ false);
766 }
767 if (i < profilesToStartSize) {
768 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
769 }
770 }
771
Sudheer Shanka2250d562016-11-07 15:41:02 -0800772 private IStorageManager getStorageManager() {
773 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700774 }
775
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700776 /**
777 * Start user, if its not already running.
778 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
779 * When starting the user, multiple intents will be broadcast in the following order:</p>
780 * <ul>
781 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
782 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
783 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
784 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
785 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
786 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
787 * Sent only if {@code foreground} parameter is true
788 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
789 * of the new fg user
790 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
791 * the new user
792 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
793 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
794 * new user. Sent only when the user is booting after a system update.
795 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
796 * new user. Sent only the first time a user is starting.
797 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
798 * user. Indicates that the user has finished booting.
799 * </ul>
800 *
801 * @param userId ID of the user to start
802 * @param foreground true if user should be brought to the foreground
803 * @return true if the user has been successfully started
804 */
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700805 boolean startUser(final int userId, final boolean foreground) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700806 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700807 != PackageManager.PERMISSION_GRANTED) {
808 String msg = "Permission Denial: switchUser() from pid="
809 + Binder.getCallingPid()
810 + ", uid=" + Binder.getCallingUid()
811 + " requires " + INTERACT_ACROSS_USERS_FULL;
812 Slog.w(TAG, msg);
813 throw new SecurityException(msg);
814 }
815
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700816 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700817
818 final long ident = Binder.clearCallingIdentity();
819 try {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700820 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700821 final int oldUserId = mCurrentUserId;
822 if (oldUserId == userId) {
823 return true;
824 }
825
Tony Mak5c2cf032017-04-03 18:38:23 +0100826 if (foreground) {
827 mInjector.getActivityStackSupervisor().setLockTaskModeLocked(
828 null, ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
829 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700830
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700831 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700832 if (userInfo == null) {
833 Slog.w(TAG, "No user info for user #" + userId);
834 return false;
835 }
836 if (foreground && userInfo.isManagedProfile()) {
837 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
838 return false;
839 }
840
Evan Rosky18396452016-07-27 15:19:37 -0700841 if (foreground && mUserSwitchUiEnabled) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700842 mInjector.getWindowManager().startFreezingScreen(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700843 R.anim.screen_user_exit, R.anim.screen_user_enter);
844 }
845
846 boolean needStart = false;
847
848 // If the user we are switching to is not currently started, then
849 // we need to start it now.
850 if (mStartedUsers.get(userId) == null) {
Amith Yamasaniea1b9d72016-05-27 15:57:38 +0000851 UserState userState = new UserState(UserHandle.of(userId));
852 mStartedUsers.put(userId, userState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700853 mInjector.getUserManagerInternal().setUserState(userId, userState.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700854 updateStartedUserArrayLocked();
855 needStart = true;
856 }
857
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800858 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700859 final Integer userIdInt = userId;
860 mUserLru.remove(userIdInt);
861 mUserLru.add(userIdInt);
862
863 if (foreground) {
864 mCurrentUserId = userId;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700865 mInjector.updateUserConfigurationLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700866 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
867 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700868 mInjector.getWindowManager().setCurrentUser(userId, mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700869 // Once the internal notion of the active user has switched, we lock the device
870 // with the option to show the user switcher on the keyguard.
Evan Rosky18396452016-07-27 15:19:37 -0700871 if (mUserSwitchUiEnabled) {
872 mInjector.getWindowManager().setSwitchingUser(true);
873 mInjector.getWindowManager().lockNow(null);
874 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700875 } else {
876 final Integer currentUserIdInt = mCurrentUserId;
877 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700878 mInjector.getWindowManager().setCurrentProfileIds(mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700879 mUserLru.remove(currentUserIdInt);
880 mUserLru.add(currentUserIdInt);
881 }
882
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700883 // Make sure user is in the started state. If it is currently
884 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700885 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700886 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
887 // so we can just fairly silently bring the user back from
888 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700889 uss.setState(uss.lastState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700890 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700891 updateStartedUserArrayLocked();
892 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700893 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700894 // This means ACTION_SHUTDOWN has been sent, so we will
895 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700896 uss.setState(UserState.STATE_BOOTING);
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;
900 }
901
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700902 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700903 // Give user manager a chance to propagate user restrictions
904 // to other services and prepare app storage
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700905 mInjector.getUserManager().onBeforeStartUser(userId);
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800906
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700907 // Booting up a new user, need to tell system services about it.
908 // Note that this is on the same handler as scheduling of broadcasts,
909 // which is important because it needs to go first.
910 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
911 }
912
913 if (foreground) {
914 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
915 oldUserId));
916 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
917 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
918 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
919 oldUserId, userId, uss));
920 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
921 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
922 }
923
924 if (needStart) {
925 // Send USER_STARTED broadcast
926 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
927 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
928 | Intent.FLAG_RECEIVER_FOREGROUND);
929 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700930 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700931 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700932 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700933 }
934
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700935 if (foreground) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700936 moveUserToForegroundLocked(uss, oldUserId, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700937 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700938 finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700939 }
940
941 if (needStart) {
942 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
943 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
944 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700945 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700946 null, new IIntentReceiver.Stub() {
947 @Override
948 public void performReceive(Intent intent, int resultCode,
949 String data, Bundle extras, boolean ordered, boolean sticky,
950 int sendingUser) throws RemoteException {
951 }
952 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700953 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
954 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700955 }
956 }
957 } finally {
958 Binder.restoreCallingIdentity(ident);
959 }
960
961 return true;
962 }
963
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700964 /**
965 * Start user, if its not already running, and bring it to foreground.
966 */
Evan Rosky18396452016-07-27 15:19:37 -0700967 void startUserInForeground(final int targetUserId) {
968 boolean success = startUser(targetUserId, /* foreground */ true);
969 if (!success) {
970 mInjector.getWindowManager().setSwitchingUser(false);
971 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700972 }
973
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600974 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700975 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -0800976 != PackageManager.PERMISSION_GRANTED) {
977 String msg = "Permission Denial: unlockUser() from pid="
978 + Binder.getCallingPid()
979 + ", uid=" + Binder.getCallingUid()
980 + " requires " + INTERACT_ACROSS_USERS_FULL;
981 Slog.w(TAG, msg);
982 throw new SecurityException(msg);
983 }
984
Jeff Sharkey8924e872015-11-30 12:52:10 -0700985 final long binderToken = Binder.clearCallingIdentity();
986 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600987 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700988 } finally {
989 Binder.restoreCallingIdentity(binderToken);
990 }
991 }
992
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700993 /**
994 * Attempt to unlock user without a credential token. This typically
995 * succeeds when the device doesn't have credential-encrypted storage, or
996 * when the the credential-encrypted storage isn't tied to a user-provided
997 * PIN or pattern.
998 */
999 boolean maybeUnlockUser(final int userId) {
1000 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001001 return unlockUserCleared(userId, null, null, null);
1002 }
1003
1004 private static void notifyFinished(int userId, IProgressListener listener) {
1005 if (listener == null) return;
1006 try {
1007 listener.onFinished(userId, null);
1008 } catch (RemoteException ignored) {
1009 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -07001010 }
1011
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001012 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001013 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001014 UserState uss;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001015 synchronized (mLock) {
Ricky Wai4266fee2016-05-23 15:33:04 +01001016 // TODO Move this block outside of synchronized if it causes lock contention
1017 if (!StorageManager.isUserKeyUnlocked(userId)) {
1018 final UserInfo userInfo = getUserInfo(userId);
Sudheer Shanka2250d562016-11-07 15:41:02 -08001019 final IStorageManager storageManager = getStorageManager();
Ricky Wai4266fee2016-05-23 15:33:04 +01001020 try {
1021 // We always want to unlock user storage, even user is not started yet
Sudheer Shanka2250d562016-11-07 15:41:02 -08001022 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Ricky Wai4266fee2016-05-23 15:33:04 +01001023 } catch (RemoteException | RuntimeException e) {
1024 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
1025 }
1026 }
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001027 // Bail if user isn't actually running, otherwise register the given
1028 // listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001029 uss = mStartedUsers.get(userId);
Ricky Waif6ef8282016-04-14 10:00:22 +01001030 if (uss == null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001031 notifyFinished(userId, listener);
Ricky Waif6ef8282016-04-14 10:00:22 +01001032 return false;
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001033 } else {
1034 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001035 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001036 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001037 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001038
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001039 finishUserUnlocking(uss);
1040
1041 final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
Jorim Jaggi526694e2016-08-03 17:15:23 +02001042 synchronized (mLock) {
Jeff Sharkeyba512352015-11-12 20:17:45 -08001043
Jeff Sharkey7661a312016-04-07 12:39:57 -06001044 // We just unlocked a user, so let's now attempt to unlock any
1045 // managed profiles under that user.
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001046 for (int i = 0; i < mStartedUsers.size(); i++) {
1047 final int testUserId = mStartedUsers.keyAt(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001048 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001049 if (parent != null && parent.id == userId && testUserId != userId) {
Jeff Sharkey7661a312016-04-07 12:39:57 -06001050 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1051 + "): attempting unlock because parent was just unlocked");
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001052 childProfilesToUnlock.add(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001053 }
1054 }
1055 }
1056
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001057 final int size = childProfilesToUnlock.size();
1058 for (int i = 0; i < size; i++) {
1059 maybeUnlockUser(childProfilesToUnlock.valueAt(i));
1060 }
1061
Jeff Sharkeyba512352015-11-12 20:17:45 -08001062 return true;
1063 }
1064
Suprabh Shukla4fe508b2015-11-20 18:22:57 -08001065 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001066 // The dialog will show and then initiate the user switch by calling startUserInForeground
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001067 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001068 }
1069
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001070 void dispatchForegroundProfileChanged(int userId) {
1071 final int observerCount = mUserSwitchObservers.beginBroadcast();
1072 for (int i = 0; i < observerCount; i++) {
1073 try {
1074 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1075 } catch (RemoteException e) {
1076 // Ignore
1077 }
1078 }
1079 mUserSwitchObservers.finishBroadcast();
1080 }
1081
1082 /** Called on handler thread */
1083 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001084 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001085 final int observerCount = mUserSwitchObservers.beginBroadcast();
1086 for (int i = 0; i < observerCount; i++) {
1087 try {
1088 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1089 } catch (RemoteException e) {
1090 }
1091 }
1092 mUserSwitchObservers.finishBroadcast();
1093 }
1094
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001095 void dispatchLockedBootComplete(int userId) {
1096 final int observerCount = mUserSwitchObservers.beginBroadcast();
1097 for (int i = 0; i < observerCount; i++) {
1098 try {
1099 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1100 } catch (RemoteException e) {
1101 // Ignore
1102 }
1103 }
1104 mUserSwitchObservers.finishBroadcast();
1105 }
1106
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001107 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1108 // Never stop system user
1109 if (oldUserId == UserHandle.USER_SYSTEM) {
1110 return;
1111 }
1112 // For now, only check for user restriction. Additional checks can be added here
1113 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1114 oldUserId);
1115 if (!disallowRunInBg) {
1116 return;
1117 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001118 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001119 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1120 + " and related users");
1121 stopUsersLocked(oldUserId, false, null);
1122 }
1123 }
1124
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001125 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001126 synchronized (mLock) {
1127 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001128 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1129 }
1130 }
1131
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001132 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1133 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001134 final int observerCount = mUserSwitchObservers.beginBroadcast();
1135 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001136 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001137 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001138 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001139 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001140 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001141 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001142 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001143 for (int i = 0; i < observerCount; i++) {
1144 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001145 // Prepend with unique prefix to guarantee that keys are unique
1146 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001147 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001148 curWaitingUserSwitchCallbacks.add(name);
1149 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001150 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1151 @Override
1152 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001153 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001154 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
1155 if (delay > USER_SWITCH_TIMEOUT) {
1156 Slog.wtf(TAG, "User switch timeout: observer " + name
1157 + " sent result after " + delay + " ms");
1158 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001159 // Early return if this session is no longer valid
1160 if (curWaitingUserSwitchCallbacks
1161 != mCurWaitingUserSwitchCallbacks) {
1162 return;
1163 }
1164 curWaitingUserSwitchCallbacks.remove(name);
1165 // Continue switching if all callbacks have been notified
Fyodor Kupolov38641832016-06-28 17:37:09 -07001166 if (waitingCallbacksCount.decrementAndGet() == 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001167 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1168 }
1169 }
1170 }
1171 };
1172 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001173 } catch (RemoteException e) {
1174 }
1175 }
1176 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001177 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001178 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1179 }
1180 }
1181 mUserSwitchObservers.finishBroadcast();
1182 }
1183
1184 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001185 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001186 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1187 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
1188 oldUserId, newUserId, uss));
1189 }
1190
1191 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001192 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001193 if (mUserSwitchUiEnabled) {
1194 synchronized (mLock) {
1195 mInjector.getWindowManager().stopFreezingScreen();
1196 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001197 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001198 uss.switching = false;
1199 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1200 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1201 newUserId, 0));
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001202 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001203 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001204 }
1205
1206 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
Tony Mak5c2cf032017-04-03 18:38:23 +01001207 boolean homeInFront =
1208 mInjector.getActivityStackSupervisor().switchUserLocked(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001209 if (homeInFront) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001210 mInjector.startHomeActivityLocked(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001211 } else {
Tony Mak5c2cf032017-04-03 18:38:23 +01001212 mInjector.getActivityStackSupervisor().resumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001213 }
1214 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001215 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
1216 }
1217
1218 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1219 long ident = Binder.clearCallingIdentity();
1220 try {
1221 Intent intent;
1222 if (oldUserId >= 0) {
1223 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001224 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001225 int count = profiles.size();
1226 for (int i = 0; i < count; i++) {
1227 int profileUserId = profiles.get(i).id;
1228 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1229 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1230 | Intent.FLAG_RECEIVER_FOREGROUND);
1231 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001232 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001233 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1234 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1235 }
1236 }
1237 if (newUserId >= 0) {
1238 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001239 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001240 int count = profiles.size();
1241 for (int i = 0; i < count; i++) {
1242 int profileUserId = profiles.get(i).id;
1243 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245 | Intent.FLAG_RECEIVER_FOREGROUND);
1246 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001247 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001248 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1250 }
1251 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1253 | Intent.FLAG_RECEIVER_FOREGROUND);
1254 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001255 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001256 null, null, 0, null, null,
1257 new String[] {android.Manifest.permission.MANAGE_USERS},
1258 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1259 UserHandle.USER_ALL);
1260 }
1261 } finally {
1262 Binder.restoreCallingIdentity(ident);
1263 }
1264 }
1265
1266
1267 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1268 int allowMode, String name, String callerPackage) {
1269 final int callingUserId = UserHandle.getUserId(callingUid);
1270 if (callingUserId == userId) {
1271 return userId;
1272 }
1273
1274 // Note that we may be accessing mCurrentUserId outside of a lock...
1275 // shouldn't be a big deal, if this is being called outside
1276 // of a locked context there is intrinsically a race with
1277 // the value the caller will receive and someone else changing it.
1278 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1279 // we will switch to the calling user if access to the current user fails.
1280 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1281
1282 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1283 final boolean allow;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001284 if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001285 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1286 // If the caller has this permission, they always pass go. And collect $200.
1287 allow = true;
1288 } else if (allowMode == ALLOW_FULL_ONLY) {
1289 // We require full access, sucks to be you.
1290 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001291 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001292 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1293 // If the caller does not have either permission, they are always doomed.
1294 allow = false;
1295 } else if (allowMode == ALLOW_NON_FULL) {
1296 // We are blanket allowing non-full access, you lucky caller!
1297 allow = true;
1298 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1299 // We may or may not allow this depending on whether the two users are
1300 // in the same profile.
1301 allow = isSameProfileGroup(callingUserId, targetUserId);
1302 } else {
1303 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1304 }
1305 if (!allow) {
1306 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1307 // In this case, they would like to just execute as their
1308 // owner user instead of failing.
1309 targetUserId = callingUserId;
1310 } else {
1311 StringBuilder builder = new StringBuilder(128);
1312 builder.append("Permission Denial: ");
1313 builder.append(name);
1314 if (callerPackage != null) {
1315 builder.append(" from ");
1316 builder.append(callerPackage);
1317 }
1318 builder.append(" asks to run as user ");
1319 builder.append(userId);
1320 builder.append(" but is calling from user ");
1321 builder.append(UserHandle.getUserId(callingUid));
1322 builder.append("; this requires ");
1323 builder.append(INTERACT_ACROSS_USERS_FULL);
1324 if (allowMode != ALLOW_FULL_ONLY) {
1325 builder.append(" or ");
1326 builder.append(INTERACT_ACROSS_USERS);
1327 }
1328 String msg = builder.toString();
1329 Slog.w(TAG, msg);
1330 throw new SecurityException(msg);
1331 }
1332 }
1333 }
1334 if (!allowAll && targetUserId < 0) {
1335 throw new IllegalArgumentException(
1336 "Call does not support special user #" + targetUserId);
1337 }
1338 // Check shell permission
1339 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1340 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1341 throw new SecurityException("Shell does not have permission to access user "
1342 + targetUserId + "\n " + Debug.getCallers(3));
1343 }
1344 }
1345 return targetUserId;
1346 }
1347
1348 int unsafeConvertIncomingUserLocked(int userId) {
1349 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1350 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001351 }
1352
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001353 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1354 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001355 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001356 != PackageManager.PERMISSION_GRANTED) {
1357 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1358 + Binder.getCallingPid()
1359 + ", uid=" + Binder.getCallingUid()
1360 + " requires " + INTERACT_ACROSS_USERS_FULL;
1361 Slog.w(TAG, msg);
1362 throw new SecurityException(msg);
1363 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001364 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001365 }
1366
1367 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1368 mUserSwitchObservers.unregister(observer);
1369 }
1370
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001371 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001372 return mStartedUsers.get(userId);
1373 }
1374
1375 boolean hasStartedUserState(int userId) {
1376 return mStartedUsers.get(userId) != null;
1377 }
1378
1379 private void updateStartedUserArrayLocked() {
1380 int num = 0;
1381 for (int i = 0; i < mStartedUsers.size(); i++) {
1382 UserState uss = mStartedUsers.valueAt(i);
1383 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001384 if (uss.state != UserState.STATE_STOPPING
1385 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001386 num++;
1387 }
1388 }
1389 mStartedUserArray = new int[num];
1390 num = 0;
1391 for (int i = 0; i < mStartedUsers.size(); i++) {
1392 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001393 if (uss.state != UserState.STATE_STOPPING
1394 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001395 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001396 }
1397 }
1398 }
1399
1400 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1401 for (int i = 0; i < mStartedUsers.size(); i++) {
1402 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001403 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001404 }
1405 }
1406
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001407 void onSystemReady() {
1408 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001409 }
1410
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001411 /**
1412 * Refreshes the list of users related to the current user when either a
1413 * user switch happens or when a new related user is started in the
1414 * background.
1415 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001416 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001417 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001418 false /* enabledOnly */);
1419 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1420 for (int i = 0; i < currentProfileIds.length; i++) {
1421 currentProfileIds[i] = profiles.get(i).id;
1422 }
1423 mCurrentProfileIds = currentProfileIds;
1424
1425 synchronized (mUserProfileGroupIdsSelfLocked) {
1426 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001427 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001428 for (int i = 0; i < users.size(); i++) {
1429 UserInfo user = users.get(i);
1430 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1431 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1432 }
1433 }
1434 }
1435 }
1436
1437 int[] getStartedUserArrayLocked() {
1438 return mStartedUserArray;
1439 }
1440
Nicolas Prevot1219c922016-06-20 17:25:12 +01001441 boolean isUserStoppingOrShuttingDownLocked(int userId) {
1442 UserState state = getStartedUserStateLocked(userId);
1443 if (state == null) {
1444 return false;
1445 }
1446 return state.state == UserState.STATE_STOPPING
1447 || state.state == UserState.STATE_SHUTDOWN;
1448 }
1449
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001450 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001451 UserState state = getStartedUserStateLocked(userId);
1452 if (state == null) {
1453 return false;
1454 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001455 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001456 return true;
1457 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001458 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001459 switch (state.state) {
1460 case UserState.STATE_BOOTING:
1461 case UserState.STATE_RUNNING_LOCKED:
1462 return true;
1463 default:
1464 return false;
1465 }
1466 }
1467 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1468 switch (state.state) {
1469 case UserState.STATE_RUNNING_UNLOCKING:
1470 case UserState.STATE_RUNNING_UNLOCKED:
1471 return true;
1472 default:
1473 return false;
1474 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001475 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001476 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001477 switch (state.state) {
1478 case UserState.STATE_RUNNING_UNLOCKED:
1479 return true;
1480 default:
1481 return false;
1482 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001483 }
1484
1485 // One way or another, we're running!
1486 return true;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001487 }
1488
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001489 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001490 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001491 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001492 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001493 != PackageManager.PERMISSION_GRANTED)) {
1494 String msg = "Permission Denial: getCurrentUser() from pid="
1495 + Binder.getCallingPid()
1496 + ", uid=" + Binder.getCallingUid()
1497 + " requires " + INTERACT_ACROSS_USERS;
1498 Slog.w(TAG, msg);
1499 throw new SecurityException(msg);
1500 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001501 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001502 return getCurrentUserLocked();
1503 }
1504 }
1505
1506 UserInfo getCurrentUserLocked() {
1507 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001508 return getUserInfo(userId);
1509 }
1510
1511 int getCurrentOrTargetUserIdLocked() {
1512 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001513 }
1514
1515 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001516 return mCurrentUserId;
1517 }
1518
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001519 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001520 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001521 }
1522
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001523 int setTargetUserIdLocked(int targetUserId) {
1524 return mTargetUserId = targetUserId;
1525 }
1526
1527 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001528 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001529 return ums != null ? ums.getUserIds() : new int[] { 0 };
1530 }
1531
1532 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001533 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001534 }
1535
1536 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001537 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001538 }
1539
1540 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001541 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001542 }
1543
1544 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001545 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001546 }
1547
1548 Set<Integer> getProfileIds(int userId) {
1549 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001550 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001551 false /* enabledOnly */);
1552 for (UserInfo user : profiles) {
1553 userIds.add(user.id);
1554 }
1555 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001556 }
1557
1558 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001559 if (callingUserId == targetUserId) {
1560 return true;
1561 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001562 synchronized (mUserProfileGroupIdsSelfLocked) {
1563 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1564 UserInfo.NO_PROFILE_GROUP_ID);
1565 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1566 UserInfo.NO_PROFILE_GROUP_ID);
1567 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1568 && callingProfile == targetProfile;
1569 }
1570 }
1571
1572 boolean isCurrentProfileLocked(int userId) {
1573 return ArrayUtils.contains(mCurrentProfileIds, userId);
1574 }
1575
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001576 int[] getCurrentProfileIdsLocked() {
1577 return mCurrentProfileIds;
1578 }
1579
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001580 /**
1581 * Returns whether the given user requires credential entry at this time. This is used to
1582 * intercept activity launches for work apps when the Work Challenge is present.
1583 */
1584 boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001585 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001586 if (mStartedUsers.get(userId) == null) {
1587 return false;
1588 }
1589 }
Clara Bayarria1771112015-12-18 16:29:18 +00001590 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001591 return false;
1592 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001593 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001594 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001595 }
1596
Tony Mak8c536f92016-03-21 12:20:41 +00001597 boolean isLockScreenDisabled(@UserIdInt int userId) {
1598 return mLockPatternUtils.isLockScreenDisabled(userId);
1599 }
1600
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001601 void dump(PrintWriter pw, boolean dumpAll) {
1602 pw.println(" mStartedUsers:");
1603 for (int i = 0; i < mStartedUsers.size(); i++) {
1604 UserState uss = mStartedUsers.valueAt(i);
1605 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1606 pw.print(": "); uss.dump("", pw);
1607 }
1608 pw.print(" mStartedUserArray: [");
1609 for (int i = 0; i < mStartedUserArray.length; i++) {
1610 if (i > 0) pw.print(", ");
1611 pw.print(mStartedUserArray[i]);
1612 }
1613 pw.println("]");
1614 pw.print(" mUserLru: [");
1615 for (int i = 0; i < mUserLru.size(); i++) {
1616 if (i > 0) pw.print(", ");
1617 pw.print(mUserLru.get(i));
1618 }
1619 pw.println("]");
1620 if (dumpAll) {
1621 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1622 }
1623 synchronized (mUserProfileGroupIdsSelfLocked) {
1624 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1625 pw.println(" mUserProfileGroupIds:");
1626 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1627 pw.print(" User #");
1628 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1629 pw.print(" -> profile #");
1630 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1631 }
1632 }
1633 }
1634 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001635
1636 @VisibleForTesting
1637 static class Injector {
1638 private final ActivityManagerService mService;
1639 private UserManagerService mUserManager;
1640 private UserManagerInternal mUserManagerInternal;
1641
1642 Injector(ActivityManagerService service) {
1643 mService = service;
1644 }
1645
1646 protected Object getLock() {
1647 return mService;
1648 }
1649
1650 protected Handler getHandler() {
1651 return mService.mHandler;
1652 }
1653
1654 protected Context getContext() {
1655 return mService.mContext;
1656 }
1657
1658 protected LockPatternUtils getLockPatternUtils() {
1659 return new LockPatternUtils(getContext());
1660 }
1661
1662 protected int broadcastIntentLocked(Intent intent, String resolvedType,
1663 IIntentReceiver resultTo, int resultCode, String resultData,
1664 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
1665 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
1666 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
1667 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
1668 ordered, sticky, callingPid, callingUid, userId);
1669 }
1670
1671 int checkCallingPermission(String permission) {
1672 return mService.checkCallingPermission(permission);
1673 }
1674
1675 WindowManagerService getWindowManager() {
1676 return mService.mWindowManager;
1677 }
1678 void activityManagerOnUserStopped(int userId) {
1679 mService.onUserStoppedLocked(userId);
1680 }
1681
1682 void systemServiceManagerCleanupUser(int userId) {
1683 mService.mSystemServiceManager.cleanupUser(userId);
1684 }
1685
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001686 protected UserManagerService getUserManager() {
1687 if (mUserManager == null) {
1688 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
1689 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
1690 }
1691 return mUserManager;
1692 }
1693
1694 UserManagerInternal getUserManagerInternal() {
1695 if (mUserManagerInternal == null) {
1696 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1697 }
1698 return mUserManagerInternal;
1699 }
1700
1701 KeyguardManager getKeyguardManager() {
1702 return mService.mContext.getSystemService(KeyguardManager.class);
1703 }
1704
1705 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
1706 mService.mBatteryStatsService.noteEvent(code, name, uid);
1707 }
1708
1709 void systemServiceManagerStopUser(int userId) {
1710 mService.mSystemServiceManager.stopUser(userId);
1711 }
1712
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08001713 boolean isRuntimeRestarted() {
1714 return mService.mSystemServiceManager.isRuntimeRestarted();
1715 }
1716
Fyodor Kupolov4ba91b92017-01-20 18:12:35 -08001717 boolean isFirstBootOrUpgrade() {
1718 IPackageManager pm = AppGlobals.getPackageManager();
1719 try {
1720 return pm.isFirstBoot() || pm.isUpgrade();
1721 } catch (RemoteException e) {
1722 throw e.rethrowFromSystemServer();
1723 }
Fyodor Kupolov1d87e402017-01-10 18:34:10 -08001724 }
1725
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001726 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
1727 new PreBootBroadcaster(mService, userId, null, quiet) {
1728 @Override
1729 public void onFinished() {
1730 onFinish.run();
1731 }
1732 }.sendNext();
1733 }
1734
1735 void activityManagerForceStopPackageLocked(int userId, String reason) {
1736 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
1737 userId, reason);
1738 };
1739
1740 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
1741 boolean exported) {
1742 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
1743 }
1744
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001745 void startHomeActivityLocked(int userId, String reason) {
1746 mService.startHomeActivityLocked(userId, reason);
1747 }
1748
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001749 void updateUserConfigurationLocked() {
1750 mService.updateUserConfigurationLocked();
1751 }
1752
1753 void clearBroadcastQueueForUserLocked(int userId) {
1754 mService.clearBroadcastQueueForUserLocked(userId);
1755 }
1756
1757 void enforceShellRestriction(String restriction, int userId) {
1758 mService.enforceShellRestriction(restriction, userId);
1759 }
1760
1761 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser) {
1762 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
1763 true /* above system */);
1764 d.show();
1765 }
Tony Mak5c2cf032017-04-03 18:38:23 +01001766
1767 ActivityStackSupervisor getActivityStackSupervisor() {
1768 return mService.mStackSupervisor;
1769 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001770 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001771}