blob: 45e06b0743f426c5a99c22c715e0584bf59647b8 [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;
50import android.app.AppOpsManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070051import android.app.Dialog;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070052import android.app.IStopUserCallback;
53import android.app.IUserSwitchObserver;
Clara Bayarriea9b10e2015-12-04 15:36:26 +000054import android.app.KeyguardManager;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -070055import android.content.Context;
Fyodor Kupolov610acda2015-10-19 18:44:07 -070056import android.content.IIntentReceiver;
57import android.content.Intent;
58import 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 */
110final class UserController {
111 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
124 // Holds the current foreground user's id
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700125 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700126 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700127 // Holds the target user's id during a user switch
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700128 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700129 private int mTargetUserId = UserHandle.USER_NULL;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700130
131 /**
132 * Which users have been started, so are allowed to run code.
133 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700134 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700135 private final SparseArray<UserState> mStartedUsers = new SparseArray<>();
Jeff Sharkeyba512352015-11-12 20:17:45 -0800136
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700137 /**
138 * LRU list of history of current users. Most recently current is at the end.
139 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700140 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700141 private final ArrayList<Integer> mUserLru = new ArrayList<>();
142
143 /**
144 * Constant array of the users that are currently started.
145 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700146 @GuardedBy("mLock")
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700147 private int[] mStartedUserArray = new int[] { 0 };
148
149 // If there are multiple profiles for the current user, their ids are here
150 // Currently only the primary user can have managed profiles
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700151 @GuardedBy("mLock")
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700152 private int[] mCurrentProfileIds = new int[] {};
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700153
154 /**
155 * Mapping from each known user ID to the profile group ID it is associated with.
156 */
157 private final SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
158
159 /**
160 * Registered observers of the user switching mechanics.
161 */
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700162 private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700163 = new RemoteCallbackList<>();
164
Evan Rosky3e0c25b2016-08-09 12:43:33 -0700165 boolean mUserSwitchUiEnabled = true;
Evan Rosky18396452016-07-27 15:19:37 -0700166
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700167 /**
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700168 * Currently active user switch callbacks.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700169 */
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700170 @GuardedBy("mLock")
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -0700171 private volatile ArraySet<String> mCurWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700172
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700173 private volatile UserManagerService mUserManager;
174
Clara Bayarria1771112015-12-18 16:29:18 +0000175 private final LockPatternUtils mLockPatternUtils;
176
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700177 UserController(ActivityManagerService service) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700178 this(new Injector(service));
179 }
180
181 @VisibleForTesting
182 UserController(Injector injector) {
183 mInjector = injector;
184 mLock = injector.getLock();
185 mHandler = injector.getHandler();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700186 // User 0 is the first and only user that runs at boot.
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800187 final UserState uss = new UserState(UserHandle.SYSTEM);
188 mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700189 mUserLru.add(UserHandle.USER_SYSTEM);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700190 mLockPatternUtils = mInjector.getLockPatternUtils();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700191 updateStartedUserArrayLocked();
192 }
193
194 void finishUserSwitch(UserState uss) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700195 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700196 finishUserBoot(uss);
197
198 startProfilesLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700199 stopRunningUsersLocked(MAX_RUNNING_USERS);
200 }
201 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700202
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700203 void stopRunningUsersLocked(int maxRunningUsers) {
204 int num = mUserLru.size();
205 int i = 0;
206 while (num > maxRunningUsers && i < mUserLru.size()) {
207 Integer oldUserId = mUserLru.get(i);
208 UserState oldUss = mStartedUsers.get(oldUserId);
209 if (oldUss == null) {
210 // Shouldn't happen, but be sane if it does.
211 mUserLru.remove(i);
212 num--;
213 continue;
214 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700215 if (oldUss.state == UserState.STATE_STOPPING
216 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700217 // This user is already stopping, doesn't count.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700218 num--;
219 i++;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700220 continue;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700221 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700222 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId) {
223 // Owner/System user and current user can't be stopped. We count it as running
224 // when it is not a pure system user.
225 if (UserInfo.isSystemOnly(oldUserId)) {
226 num--;
227 }
228 i++;
229 continue;
230 }
231 // This is a user to be stopped.
232 if (stopUsersLocked(oldUserId, false, null) != USER_OP_SUCCESS) {
233 num--;
234 }
235 num--;
236 i++;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700237 }
238 }
239
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800240 private void finishUserBoot(UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700241 finishUserBoot(uss, null);
242 }
243
Fyodor Kupolov2e6acce2016-01-28 15:26:52 -0800244 private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700245 final int userId = uss.mHandle.getIdentifier();
Suprabh Shuklacc30b0e72016-05-20 14:41:22 -0700246
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700247 Slog.d(TAG, "Finishing user boot " + userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700248 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700249 // Bail if we ended up with a stale user
250 if (mStartedUsers.get(userId) != uss) return;
251
252 // We always walk through all the user lifecycle states to send
253 // consistent developer events. We step into RUNNING_LOCKED here,
254 // but we might immediately step into RUNNING below if the user
255 // storage is already unlocked.
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600256 if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700257 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
James Hawkins899608a2016-05-27 11:15:06 -0700258
259 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700260 MetricsLogger.histogram(mInjector.getContext(), "framework_locked_boot_completed",
James Hawkins899608a2016-05-27 11:15:06 -0700261 uptimeSeconds);
262
Sudheer Shanka2c4522c2016-08-27 20:53:28 -0700263 mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
264 userId, 0));
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700265 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700266 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Jeff Sharkeya242f822015-12-17 15:38:20 -0700267 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
268 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700269 mInjector.broadcastIntentLocked(intent, null, resultTo, 0, null, null,
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700270 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
271 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
272 }
273
Jeff Sharkey7661a312016-04-07 12:39:57 -0600274 // We need to delay unlocking managed profiles until the parent user
275 // is also unlocked.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700276 if (mInjector.getUserManager().isManagedProfile(userId)) {
277 final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey7661a312016-04-07 12:39:57 -0600278 if (parent != null
279 && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
280 Slog.d(TAG, "User " + userId + " (parent " + parent.id
281 + "): attempting unlock because parent is unlocked");
282 maybeUnlockUser(userId);
283 } else {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700284 String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
285 Slog.d(TAG, "User " + userId + " (parent " + parentId
Jeff Sharkey7661a312016-04-07 12:39:57 -0600286 + "): delaying unlock because parent is locked");
287 }
Jeff Sharkey5dab7132016-04-07 01:20:58 -0600288 } else {
289 maybeUnlockUser(userId);
290 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700291 }
292 }
293
294 /**
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600295 * Step from {@link UserState#STATE_RUNNING_LOCKED} to
296 * {@link UserState#STATE_RUNNING_UNLOCKING}.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700297 */
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600298 private void finishUserUnlocking(final UserState uss) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700299 final int userId = uss.mHandle.getIdentifier();
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200300 boolean proceedWithUnlock = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700301 synchronized (mLock) {
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700302 // Bail if we ended up with a stale user
303 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
304
305 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600306 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700307
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600308 if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700309 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200310 proceedWithUnlock = true;
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600311 }
312 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200313
314 if (proceedWithUnlock) {
315 uss.mUnlockProgress.start();
316
317 // Prepare app storage before we go any further
318 uss.mUnlockProgress.setProgress(5,
Jorim Jaggi526694e2016-08-03 17:15:23 +0200319 mInjector.getContext().getString(R.string.android_start_title));
320 mInjector.getUserManager().onBeforeUnlockUser(userId);
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200321 uss.mUnlockProgress.setProgress(20);
322
323 // Dispatch unlocked to system services; when fully dispatched,
324 // that calls through to the next "unlocked" phase
325 mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
326 .sendToTarget();
327 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600328 }
329
330 /**
331 * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
332 * {@link UserState#STATE_RUNNING_UNLOCKED}.
333 */
334 void finishUserUnlocked(final UserState uss) {
335 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700336 synchronized (mLock) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600337 // Bail if we ended up with a stale user
338 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
339
340 // Only keep marching forward if user is actually unlocked
341 if (!StorageManager.isUserKeyUnlocked(userId)) return;
342
343 if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700344 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600345 uss.mUnlockProgress.finish();
Jeff Sharkey083807d2016-04-06 14:07:09 -0600346
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600347 // Dispatch unlocked to external apps
348 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
349 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
350 unlockedIntent.addFlags(
351 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700352 mInjector.broadcastIntentLocked(unlockedIntent, null, null, 0, null,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600353 null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
354 userId);
355
356 if (getUserInfo(userId).isManagedProfile()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700357 UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600358 if (parent != null) {
359 final Intent profileUnlockedIntent = new Intent(
360 Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
361 profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
362 profileUnlockedIntent.addFlags(
363 Intent.FLAG_RECEIVER_REGISTERED_ONLY
364 | Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700365 mInjector.broadcastIntentLocked(profileUnlockedIntent,
Jeff Sharkey155e5d62016-04-11 12:13:06 -0600366 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
367 null, false, false, MY_PID, SYSTEM_UID,
368 parent.id);
369 }
370 }
371
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600372 // Send PRE_BOOT broadcasts if user fingerprint changed; we
373 // purposefully block sending BOOT_COMPLETED until after all
374 // PRE_BOOT receivers are finished to avoid ANR'ing apps
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600375 final UserInfo info = getUserInfo(userId);
376 if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
Jeff Sharkey24d94912016-07-07 12:33:48 -0600377 // Suppress double notifications for managed profiles that
Jeff Sharkeyba066572016-07-18 10:11:36 -0600378 // were unlocked automatically as part of their parent user
379 // being unlocked.
380 final boolean quiet;
381 if (info.isManagedProfile()) {
382 quiet = !uss.tokenProvided
383 || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
384 } else {
385 quiet = false;
386 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700387 mInjector.sendPreBootBroadcast(userId, quiet,
388 () -> finishUserUnlockedCompleted(uss));
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600389 } else {
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600390 finishUserUnlockedCompleted(uss);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600391 }
392 }
393 }
394 }
395
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600396 private void finishUserUnlockedCompleted(UserState uss) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600397 final int userId = uss.mHandle.getIdentifier();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700398 synchronized (mLock) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600399 // Bail if we ended up with a stale user
400 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700401 final UserInfo userInfo = getUserInfo(userId);
402 if (userInfo == null) {
403 return;
404 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600405
406 // Only keep marching forward if user is actually unlocked
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600407 if (!StorageManager.isUserKeyUnlocked(userId)) return;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600408
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600409 // Remember that we logged in
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700410 mInjector.getUserManager().onUserLoggedIn(userId);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600411
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600412 if (!userInfo.isInitialized()) {
413 if (userId != UserHandle.USER_SYSTEM) {
414 Slog.d(TAG, "Initializing user #" + userId);
415 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
416 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700417 mInjector.broadcastIntentLocked(intent, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600418 new IIntentReceiver.Stub() {
419 @Override
420 public void performReceive(Intent intent, int resultCode,
421 String data, Bundle extras, boolean ordered,
422 boolean sticky, int sendingUser) {
423 // Note: performReceive is called with mService lock held
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700424 mInjector.getUserManager().makeInitialized(userInfo.id);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600425 }
426 }, 0, null, null, null, AppOpsManager.OP_NONE,
427 null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700428 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700429 }
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600430
431 Slog.d(TAG, "Sending BOOT_COMPLETE user #" + userId);
James Hawkins899608a2016-05-27 11:15:06 -0700432 int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700433 MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
434 uptimeSeconds);
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600435 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
436 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
437 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
438 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700439 mInjector.broadcastIntentLocked(bootIntent, null, null, 0, null, null,
Jeff Sharkeyce18c812016-04-27 16:00:41 -0600440 new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
441 AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700442 }
443 }
444
Andrew Scull85a63bc2016-10-24 13:47:47 +0100445 int restartUser(final int userId, final boolean foreground) {
446 return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
447 @Override
448 public void userStopped(final int userId) {
449 // Post to the same handler that this callback is called from to ensure the user
450 // cleanup is complete before restarting.
451 mHandler.post(() -> startUser(userId, foreground));
452 }
453 @Override
454 public void userStopAborted(final int userId) {}
455 });
456 }
457
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700458 int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700459 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700460 != PackageManager.PERMISSION_GRANTED) {
461 String msg = "Permission Denial: switchUser() from pid="
462 + Binder.getCallingPid()
463 + ", uid=" + Binder.getCallingUid()
464 + " requires " + INTERACT_ACROSS_USERS_FULL;
465 Slog.w(TAG, msg);
466 throw new SecurityException(msg);
467 }
468 if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
469 throw new IllegalArgumentException("Can't stop system user " + userId);
470 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700471 mInjector.enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
472 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700473 return stopUsersLocked(userId, force, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700474 }
475 }
476
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700477 /**
478 * Stops the user along with its related users. The method calls
479 * {@link #getUsersToStopLocked(int)} to determine the list of users that should be stopped.
480 */
481 private int stopUsersLocked(final int userId, boolean force, final IStopUserCallback callback) {
482 if (userId == UserHandle.USER_SYSTEM) {
483 return USER_OP_ERROR_IS_SYSTEM;
484 }
485 if (isCurrentUserLocked(userId)) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700486 return USER_OP_IS_CURRENT;
487 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700488 int[] usersToStop = getUsersToStopLocked(userId);
489 // If one of related users is system or current, no related users should be stopped
490 for (int i = 0; i < usersToStop.length; i++) {
491 int relatedUserId = usersToStop[i];
492 if ((UserHandle.USER_SYSTEM == relatedUserId) || isCurrentUserLocked(relatedUserId)) {
493 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked cannot stop related user "
494 + relatedUserId);
495 // We still need to stop the requested user if it's a force stop.
496 if (force) {
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800497 Slog.i(TAG,
498 "Force stop user " + userId + ". Related users will not be stopped");
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700499 stopSingleUserLocked(userId, callback);
Fyodor Kupolov7b4a8a42016-01-04 12:47:22 -0800500 return USER_OP_SUCCESS;
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700501 }
502 return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
503 }
504 }
505 if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
506 for (int userIdToStop : usersToStop) {
507 stopSingleUserLocked(userIdToStop, userIdToStop == userId ? callback : null);
508 }
509 return USER_OP_SUCCESS;
510 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700511
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700512 private void stopSingleUserLocked(final int userId, final IStopUserCallback callback) {
513 if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700514 final UserState uss = mStartedUsers.get(userId);
515 if (uss == null) {
516 // User is not started, nothing to do... but we do need to
517 // callback if requested.
518 if (callback != null) {
519 mHandler.post(new Runnable() {
520 @Override
521 public void run() {
522 try {
523 callback.userStopped(userId);
524 } catch (RemoteException e) {
525 }
526 }
527 });
528 }
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700529 return;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700530 }
531
532 if (callback != null) {
533 uss.mStopCallbacks.add(callback);
534 }
535
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700536 if (uss.state != UserState.STATE_STOPPING
537 && uss.state != UserState.STATE_SHUTDOWN) {
538 uss.setState(UserState.STATE_STOPPING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700539 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700540 updateStartedUserArrayLocked();
541
542 long ident = Binder.clearCallingIdentity();
543 try {
544 // We are going to broadcast ACTION_USER_STOPPING and then
545 // once that is done send a final ACTION_SHUTDOWN and then
546 // stop the user.
547 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
548 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
549 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
550 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700551 // This is the result receiver for the initial stopping broadcast.
552 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
553 @Override
554 public void performReceive(Intent intent, int resultCode, String data,
555 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700556 mHandler.post(new Runnable() {
557 @Override
558 public void run() {
559 finishUserStopping(userId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700560 }
Amith Yamasani98c05562016-03-30 13:15:26 -0700561 });
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700562 }
563 };
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -0700564 // Clear broadcast queue for the user to avoid delivering stale broadcasts
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700565 mInjector.clearBroadcastQueueForUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700566 // Kick things off.
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700567 mInjector.broadcastIntentLocked(stoppingIntent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700568 null, stoppingReceiver, 0, null, null,
569 new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700570 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700571 } finally {
572 Binder.restoreCallingIdentity(ident);
573 }
574 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700575 }
576
Amith Yamasani98c05562016-03-30 13:15:26 -0700577 void finishUserStopping(final int userId, final UserState uss) {
578 // On to the next.
579 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
580 // This is the result receiver for the final shutdown broadcast.
581 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
582 @Override
583 public void performReceive(Intent intent, int resultCode, String data,
584 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
585 mHandler.post(new Runnable() {
586 @Override
587 public void run() {
588 finishUserStopped(uss);
589 }
590 });
591 }
592 };
593
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700594 synchronized (mLock) {
Amith Yamasani98c05562016-03-30 13:15:26 -0700595 if (uss.state != UserState.STATE_STOPPING) {
596 // Whoops, we are being started back up. Abort, abort!
597 return;
598 }
599 uss.setState(UserState.STATE_SHUTDOWN);
600 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700601 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Amith Yamasani98c05562016-03-30 13:15:26 -0700602
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700603 mInjector.batteryStatsServiceNoteEvent(
Amith Yamasani98c05562016-03-30 13:15:26 -0700604 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
605 Integer.toString(userId), userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700606 mInjector.systemServiceManagerStopUser(userId);
Amith Yamasani98c05562016-03-30 13:15:26 -0700607
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700608 synchronized (mLock) {
609 mInjector.broadcastIntentLocked(shutdownIntent,
Amith Yamasani98c05562016-03-30 13:15:26 -0700610 null, shutdownReceiver, 0, null, null, null,
611 AppOpsManager.OP_NONE,
612 null, true, false, MY_PID, SYSTEM_UID, userId);
613 }
614 }
615
616 void finishUserStopped(UserState uss) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700617 final int userId = uss.mHandle.getIdentifier();
618 boolean stopped;
619 ArrayList<IStopUserCallback> callbacks;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700620 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700621 callbacks = new ArrayList<>(uss.mStopCallbacks);
622 if (mStartedUsers.get(userId) != uss) {
623 stopped = false;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700624 } else if (uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700625 stopped = false;
626 } else {
627 stopped = true;
628 // User can no longer run.
629 mStartedUsers.remove(userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700630 mInjector.getUserManagerInternal().removeUserState(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700631 mUserLru.remove(Integer.valueOf(userId));
632 updateStartedUserArrayLocked();
633
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700634 mInjector.activityManagerOnUserStopped(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700635 // Clean up all state and processes associated with the user.
636 // Kill all the processes for the user.
637 forceStopUserLocked(userId, "finish user");
638 }
639 }
640
641 for (int i = 0; i < callbacks.size(); i++) {
642 try {
643 if (stopped) callbacks.get(i).userStopped(userId);
644 else callbacks.get(i).userStopAborted(userId);
645 } catch (RemoteException e) {
646 }
647 }
648
649 if (stopped) {
Andrew Scull85a63bc2016-10-24 13:47:47 +0100650 // Evict the user's credential encryption key
651 try {
652 getStorageManager().lockUserKey(userId);
653 } catch (RemoteException re) {
654 throw re.rethrowAsRuntimeException();
655 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700656 mInjector.systemServiceManagerCleanupUser(userId);
657 synchronized (mLock) {
658 mInjector.stackSupervisorRemoveUserLocked(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700659 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100660 // Remove the user if it is ephemeral.
661 if (getUserInfo(userId).isEphemeral()) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700662 mInjector.getUserManager().removeUser(userId);
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100663 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700664 }
665 }
666
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700667 /**
668 * Determines the list of users that should be stopped together with the specified
669 * {@code userId}. The returned list includes {@code userId}.
670 */
671 private @NonNull int[] getUsersToStopLocked(int userId) {
672 int startedUsersSize = mStartedUsers.size();
673 IntArray userIds = new IntArray();
674 userIds.add(userId);
675 synchronized (mUserProfileGroupIdsSelfLocked) {
676 int userGroupId = mUserProfileGroupIdsSelfLocked.get(userId,
677 UserInfo.NO_PROFILE_GROUP_ID);
678 for (int i = 0; i < startedUsersSize; i++) {
679 UserState uss = mStartedUsers.valueAt(i);
680 int startedUserId = uss.mHandle.getIdentifier();
681 // Skip unrelated users (profileGroupId mismatch)
682 int startedUserGroupId = mUserProfileGroupIdsSelfLocked.get(startedUserId,
683 UserInfo.NO_PROFILE_GROUP_ID);
684 boolean sameGroup = (userGroupId != UserInfo.NO_PROFILE_GROUP_ID)
685 && (userGroupId == startedUserGroupId);
686 // userId has already been added
687 boolean sameUserId = startedUserId == userId;
688 if (!sameGroup || sameUserId) {
689 continue;
690 }
691 userIds.add(startedUserId);
692 }
693 }
694 return userIds.toArray();
695 }
696
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700697 private void forceStopUserLocked(int userId, String reason) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700698 mInjector.activityManagerForceStopPackageLocked(userId, reason);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700699 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
700 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
701 | Intent.FLAG_RECEIVER_FOREGROUND);
702 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700703 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700704 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700705 null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700706 }
707
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700708 /**
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100709 * Stops the guest or ephemeral user if it has gone to the background.
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700710 */
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100711 private void stopGuestOrEphemeralUserIfBackground() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700712 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700713 final int num = mUserLru.size();
714 for (int i = 0; i < num; i++) {
715 Integer oldUserId = mUserLru.get(i);
716 UserState oldUss = mStartedUsers.get(oldUserId);
717 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700718 || oldUss.state == UserState.STATE_STOPPING
719 || oldUss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700720 continue;
721 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700722 UserInfo userInfo = getUserInfo(oldUserId);
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100723 if (userInfo.isEphemeral()) {
724 LocalServices.getService(UserManagerInternal.class)
725 .onEphemeralUserStop(oldUserId);
726 }
Lenka Trochtovab4484ba2015-12-16 12:32:31 +0100727 if (userInfo.isGuest() || userInfo.isEphemeral()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700728 // This is a user to be stopped.
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -0700729 stopUsersLocked(oldUserId, true, null);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700730 break;
731 }
732 }
733 }
734 }
735
736 void startProfilesLocked() {
737 if (DEBUG_MU) Slog.i(TAG, "startProfilesLocked");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700738 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700739 mCurrentUserId, false /* enabledOnly */);
740 List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
741 for (UserInfo user : profiles) {
742 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
Rubin Xuf13c9802016-01-21 18:06:00 +0000743 && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700744 profilesToStart.add(user);
745 }
746 }
747 final int profilesToStartSize = profilesToStart.size();
748 int i = 0;
749 for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) {
750 startUser(profilesToStart.get(i).id, /* foreground= */ false);
751 }
752 if (i < profilesToStartSize) {
753 Slog.w(TAG, "More profiles than MAX_RUNNING_USERS");
754 }
755 }
756
Sudheer Shanka2250d562016-11-07 15:41:02 -0800757 private IStorageManager getStorageManager() {
758 return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700759 }
760
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700761 /**
762 * Start user, if its not already running.
763 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
764 * When starting the user, multiple intents will be broadcast in the following order:</p>
765 * <ul>
766 * <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
767 * <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
768 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
769 * <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
770 * user and all profiles of this user. Sent only if {@code foreground} parameter is true
771 * <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
772 * Sent only if {@code foreground} parameter is true
773 * <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
774 * of the new fg user
775 * <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
776 * the new user
777 * <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
778 * <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
779 * new user. Sent only when the user is booting after a system update.
780 * <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
781 * new user. Sent only the first time a user is starting.
782 * <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
783 * user. Indicates that the user has finished booting.
784 * </ul>
785 *
786 * @param userId ID of the user to start
787 * @param foreground true if user should be brought to the foreground
788 * @return true if the user has been successfully started
789 */
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700790 boolean startUser(final int userId, final boolean foreground) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700791 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700792 != PackageManager.PERMISSION_GRANTED) {
793 String msg = "Permission Denial: switchUser() from pid="
794 + Binder.getCallingPid()
795 + ", uid=" + Binder.getCallingUid()
796 + " requires " + INTERACT_ACROSS_USERS_FULL;
797 Slog.w(TAG, msg);
798 throw new SecurityException(msg);
799 }
800
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700801 Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700802
803 final long ident = Binder.clearCallingIdentity();
804 try {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700805 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700806 final int oldUserId = mCurrentUserId;
807 if (oldUserId == userId) {
808 return true;
809 }
810
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700811 mInjector.stackSupervisorSetLockTaskModeLocked(null,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700812 ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
813
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700814 final UserInfo userInfo = getUserInfo(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700815 if (userInfo == null) {
816 Slog.w(TAG, "No user info for user #" + userId);
817 return false;
818 }
819 if (foreground && userInfo.isManagedProfile()) {
820 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
821 return false;
822 }
823
Evan Rosky18396452016-07-27 15:19:37 -0700824 if (foreground && mUserSwitchUiEnabled) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700825 mInjector.getWindowManager().startFreezingScreen(
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700826 R.anim.screen_user_exit, R.anim.screen_user_enter);
827 }
828
829 boolean needStart = false;
830
831 // If the user we are switching to is not currently started, then
832 // we need to start it now.
833 if (mStartedUsers.get(userId) == null) {
Amith Yamasaniea1b9d72016-05-27 15:57:38 +0000834 UserState userState = new UserState(UserHandle.of(userId));
835 mStartedUsers.put(userId, userState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700836 mInjector.getUserManagerInternal().setUserState(userId, userState.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700837 updateStartedUserArrayLocked();
838 needStart = true;
839 }
840
Jeff Sharkeyf9fc6d62015-11-08 16:46:05 -0800841 final UserState uss = mStartedUsers.get(userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700842 final Integer userIdInt = userId;
843 mUserLru.remove(userIdInt);
844 mUserLru.add(userIdInt);
845
846 if (foreground) {
847 mCurrentUserId = userId;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700848 mInjector.updateUserConfigurationLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700849 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
850 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700851 mInjector.getWindowManager().setCurrentUser(userId, mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700852 // Once the internal notion of the active user has switched, we lock the device
853 // with the option to show the user switcher on the keyguard.
Evan Rosky18396452016-07-27 15:19:37 -0700854 if (mUserSwitchUiEnabled) {
855 mInjector.getWindowManager().setSwitchingUser(true);
856 mInjector.getWindowManager().lockNow(null);
857 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700858 } else {
859 final Integer currentUserIdInt = mCurrentUserId;
860 updateCurrentProfileIdsLocked();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700861 mInjector.getWindowManager().setCurrentProfileIds(mCurrentProfileIds);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700862 mUserLru.remove(currentUserIdInt);
863 mUserLru.add(currentUserIdInt);
864 }
865
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700866 // Make sure user is in the started state. If it is currently
867 // stopping, we need to knock that off.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700868 if (uss.state == UserState.STATE_STOPPING) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700869 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
870 // so we can just fairly silently bring the user back from
871 // the almost-dead.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700872 uss.setState(uss.lastState);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700873 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700874 updateStartedUserArrayLocked();
875 needStart = true;
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700876 } else if (uss.state == UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700877 // This means ACTION_SHUTDOWN has been sent, so we will
878 // need to treat this as a new boot of the user.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700879 uss.setState(UserState.STATE_BOOTING);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700880 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700881 updateStartedUserArrayLocked();
882 needStart = true;
883 }
884
Jeff Sharkeybedbaa92015-12-02 16:42:25 -0700885 if (uss.state == UserState.STATE_BOOTING) {
Jeff Sharkey0e62384c2016-01-13 18:52:55 -0700886 // Give user manager a chance to propagate user restrictions
887 // to other services and prepare app storage
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700888 mInjector.getUserManager().onBeforeStartUser(userId);
Makoto Onuki1a2cd742015-11-16 13:51:27 -0800889
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700890 // Booting up a new user, need to tell system services about it.
891 // Note that this is on the same handler as scheduling of broadcasts,
892 // which is important because it needs to go first.
893 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
894 }
895
896 if (foreground) {
897 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
898 oldUserId));
899 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
900 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
901 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
902 oldUserId, userId, uss));
903 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
904 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
905 }
906
907 if (needStart) {
908 // Send USER_STARTED broadcast
909 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
910 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
911 | Intent.FLAG_RECEIVER_FOREGROUND);
912 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700913 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700914 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700915 null, false, false, MY_PID, SYSTEM_UID, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700916 }
917
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700918 if (foreground) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -0700919 moveUserToForegroundLocked(uss, oldUserId, userId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700920 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700921 finishUserBoot(uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700922 }
923
924 if (needStart) {
925 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
926 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
927 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700928 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700929 null, new IIntentReceiver.Stub() {
930 @Override
931 public void performReceive(Intent intent, int resultCode,
932 String data, Bundle extras, boolean ordered, boolean sticky,
933 int sendingUser) throws RemoteException {
934 }
935 }, 0, null, null,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700936 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
937 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700938 }
939 }
940 } finally {
941 Binder.restoreCallingIdentity(ident);
942 }
943
944 return true;
945 }
946
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700947 /**
948 * Start user, if its not already running, and bring it to foreground.
949 */
Evan Rosky18396452016-07-27 15:19:37 -0700950 void startUserInForeground(final int targetUserId) {
951 boolean success = startUser(targetUserId, /* foreground */ true);
952 if (!success) {
953 mInjector.getWindowManager().setSwitchingUser(false);
954 }
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700955 }
956
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600957 boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700958 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Jeff Sharkeyba512352015-11-12 20:17:45 -0800959 != PackageManager.PERMISSION_GRANTED) {
960 String msg = "Permission Denial: unlockUser() from pid="
961 + Binder.getCallingPid()
962 + ", uid=" + Binder.getCallingUid()
963 + " requires " + INTERACT_ACROSS_USERS_FULL;
964 Slog.w(TAG, msg);
965 throw new SecurityException(msg);
966 }
967
Jeff Sharkey8924e872015-11-30 12:52:10 -0700968 final long binderToken = Binder.clearCallingIdentity();
969 try {
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600970 return unlockUserCleared(userId, token, secret, listener);
Jeff Sharkey8924e872015-11-30 12:52:10 -0700971 } finally {
972 Binder.restoreCallingIdentity(binderToken);
973 }
974 }
975
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700976 /**
977 * Attempt to unlock user without a credential token. This typically
978 * succeeds when the device doesn't have credential-encrypted storage, or
979 * when the the credential-encrypted storage isn't tied to a user-provided
980 * PIN or pattern.
981 */
982 boolean maybeUnlockUser(final int userId) {
983 // Try unlocking storage using empty token
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600984 return unlockUserCleared(userId, null, null, null);
985 }
986
987 private static void notifyFinished(int userId, IProgressListener listener) {
988 if (listener == null) return;
989 try {
990 listener.onFinished(userId, null);
991 } catch (RemoteException ignored) {
992 }
Jeff Sharkeyb9fe5372015-12-03 15:23:08 -0700993 }
994
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600995 boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
Jeff Sharkey84a4c972016-04-18 15:36:39 -0600996 IProgressListener listener) {
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +0200997 UserState uss;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -0700998 synchronized (mLock) {
Ricky Wai4266fee2016-05-23 15:33:04 +0100999 // TODO Move this block outside of synchronized if it causes lock contention
1000 if (!StorageManager.isUserKeyUnlocked(userId)) {
1001 final UserInfo userInfo = getUserInfo(userId);
Sudheer Shanka2250d562016-11-07 15:41:02 -08001002 final IStorageManager storageManager = getStorageManager();
Ricky Wai4266fee2016-05-23 15:33:04 +01001003 try {
1004 // We always want to unlock user storage, even user is not started yet
Sudheer Shanka2250d562016-11-07 15:41:02 -08001005 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
Ricky Wai4266fee2016-05-23 15:33:04 +01001006 } catch (RemoteException | RuntimeException e) {
1007 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
1008 }
1009 }
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001010 // Bail if user isn't actually running, otherwise register the given
1011 // listener to watch for unlock progress
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001012 uss = mStartedUsers.get(userId);
Ricky Waif6ef8282016-04-14 10:00:22 +01001013 if (uss == null) {
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001014 notifyFinished(userId, listener);
Ricky Waif6ef8282016-04-14 10:00:22 +01001015 return false;
Jeff Sharkey84a4c972016-04-18 15:36:39 -06001016 } else {
1017 uss.mUnlockProgress.addListener(listener);
Jeff Sharkey24d94912016-07-07 12:33:48 -06001018 uss.tokenProvided = (token != null);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001019 }
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001020 }
Jeff Sharkey8924e872015-11-30 12:52:10 -07001021
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001022 finishUserUnlocking(uss);
1023
1024 final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
Jorim Jaggi526694e2016-08-03 17:15:23 +02001025 synchronized (mLock) {
Jeff Sharkeyba512352015-11-12 20:17:45 -08001026
Jeff Sharkey7661a312016-04-07 12:39:57 -06001027 // We just unlocked a user, so let's now attempt to unlock any
1028 // managed profiles under that user.
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001029 for (int i = 0; i < mStartedUsers.size(); i++) {
1030 final int testUserId = mStartedUsers.keyAt(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001031 final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001032 if (parent != null && parent.id == userId && testUserId != userId) {
Jeff Sharkey7661a312016-04-07 12:39:57 -06001033 Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
1034 + "): attempting unlock because parent was just unlocked");
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001035 childProfilesToUnlock.add(testUserId);
Jeff Sharkey5dab7132016-04-07 01:20:58 -06001036 }
1037 }
1038 }
1039
Jorim Jaggi6f4d7b32016-08-01 14:31:02 +02001040 final int size = childProfilesToUnlock.size();
1041 for (int i = 0; i < size; i++) {
1042 maybeUnlockUser(childProfilesToUnlock.valueAt(i));
1043 }
1044
Jeff Sharkeyba512352015-11-12 20:17:45 -08001045 return true;
1046 }
1047
Suprabh Shukla4fe508b2015-11-20 18:22:57 -08001048 void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001049 // The dialog will show and then initiate the user switch by calling startUserInForeground
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001050 mInjector.showUserSwitchingDialog(fromToUserPair.first, fromToUserPair.second);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001051 }
1052
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001053 void dispatchForegroundProfileChanged(int userId) {
1054 final int observerCount = mUserSwitchObservers.beginBroadcast();
1055 for (int i = 0; i < observerCount; i++) {
1056 try {
1057 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
1058 } catch (RemoteException e) {
1059 // Ignore
1060 }
1061 }
1062 mUserSwitchObservers.finishBroadcast();
1063 }
1064
1065 /** Called on handler thread */
1066 void dispatchUserSwitchComplete(int userId) {
Evan Rosky18396452016-07-27 15:19:37 -07001067 mInjector.getWindowManager().setSwitchingUser(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001068 final int observerCount = mUserSwitchObservers.beginBroadcast();
1069 for (int i = 0; i < observerCount; i++) {
1070 try {
1071 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
1072 } catch (RemoteException e) {
1073 }
1074 }
1075 mUserSwitchObservers.finishBroadcast();
1076 }
1077
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001078 void dispatchLockedBootComplete(int userId) {
1079 final int observerCount = mUserSwitchObservers.beginBroadcast();
1080 for (int i = 0; i < observerCount; i++) {
1081 try {
1082 mUserSwitchObservers.getBroadcastItem(i).onLockedBootComplete(userId);
1083 } catch (RemoteException e) {
1084 // Ignore
1085 }
1086 }
1087 mUserSwitchObservers.finishBroadcast();
1088 }
1089
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001090 private void stopBackgroundUsersIfEnforced(int oldUserId) {
1091 // Never stop system user
1092 if (oldUserId == UserHandle.USER_SYSTEM) {
1093 return;
1094 }
1095 // For now, only check for user restriction. Additional checks can be added here
1096 boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
1097 oldUserId);
1098 if (!disallowRunInBg) {
1099 return;
1100 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001101 synchronized (mLock) {
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001102 if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
1103 + " and related users");
1104 stopUsersLocked(oldUserId, false, null);
1105 }
1106 }
1107
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001108 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001109 synchronized (mLock) {
1110 Slog.wtf(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001111 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1112 }
1113 }
1114
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001115 void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
1116 Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001117 final int observerCount = mUserSwitchObservers.beginBroadcast();
1118 if (observerCount > 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001119 final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001120 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001121 uss.switching = true;
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001122 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001123 }
Fyodor Kupolov38641832016-06-28 17:37:09 -07001124 final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001125 final long dispatchStartedTime = SystemClock.elapsedRealtime();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001126 for (int i = 0; i < observerCount; i++) {
1127 try {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001128 // Prepend with unique prefix to guarantee that keys are unique
1129 final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001130 synchronized (mLock) {
Fyodor Kupolov599d43b2016-06-24 13:46:18 -07001131 curWaitingUserSwitchCallbacks.add(name);
1132 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001133 final IRemoteCallback callback = new IRemoteCallback.Stub() {
1134 @Override
1135 public void sendResult(Bundle data) throws RemoteException {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001136 synchronized (mLock) {
Fyodor Kupolov0e0986e2016-09-22 18:01:36 -07001137 long delay = SystemClock.elapsedRealtime() - dispatchStartedTime;
1138 if (delay > USER_SWITCH_TIMEOUT) {
1139 Slog.wtf(TAG, "User switch timeout: observer " + name
1140 + " sent result after " + delay + " ms");
1141 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001142 // Early return if this session is no longer valid
1143 if (curWaitingUserSwitchCallbacks
1144 != mCurWaitingUserSwitchCallbacks) {
1145 return;
1146 }
1147 curWaitingUserSwitchCallbacks.remove(name);
1148 // Continue switching if all callbacks have been notified
Fyodor Kupolov38641832016-06-28 17:37:09 -07001149 if (waitingCallbacksCount.decrementAndGet() == 0) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001150 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1151 }
1152 }
1153 }
1154 };
1155 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001156 } catch (RemoteException e) {
1157 }
1158 }
1159 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001160 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001161 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
1162 }
1163 }
1164 mUserSwitchObservers.finishBroadcast();
1165 }
1166
1167 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001168 mCurWaitingUserSwitchCallbacks = null;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001169 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1170 mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
1171 oldUserId, newUserId, uss));
1172 }
1173
1174 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001175 Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
Evan Rosky18396452016-07-27 15:19:37 -07001176 if (mUserSwitchUiEnabled) {
1177 synchronized (mLock) {
1178 mInjector.getWindowManager().stopFreezingScreen();
1179 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001180 }
Fyodor Kupolovc94c2492016-04-20 17:44:00 -07001181 uss.switching = false;
1182 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
1183 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
1184 newUserId, 0));
Lenka Trochtovab4484ba2015-12-16 12:32:31 +01001185 stopGuestOrEphemeralUserIfBackground();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001186 stopBackgroundUsersIfEnforced(oldUserId);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001187 }
1188
1189 void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001190 boolean homeInFront = mInjector.stackSupervisorSwitchUserLocked(newUserId, uss);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001191 if (homeInFront) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001192 mInjector.startHomeActivityLocked(newUserId, "moveUserToForeground");
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001193 } else {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001194 mInjector.stackSupervisorResumeFocusedStackTopActivityLocked();
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001195 }
1196 EventLogTags.writeAmSwitchUser(newUserId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001197 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
1198 }
1199
1200 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1201 long ident = Binder.clearCallingIdentity();
1202 try {
1203 Intent intent;
1204 if (oldUserId >= 0) {
1205 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001206 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(oldUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001207 int count = profiles.size();
1208 for (int i = 0; i < count; i++) {
1209 int profileUserId = profiles.get(i).id;
1210 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
1211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1212 | Intent.FLAG_RECEIVER_FOREGROUND);
1213 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001214 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001215 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1216 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1217 }
1218 }
1219 if (newUserId >= 0) {
1220 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001221 List<UserInfo> profiles = mInjector.getUserManager().getProfiles(newUserId, false);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001222 int count = profiles.size();
1223 for (int i = 0; i < count; i++) {
1224 int profileUserId = profiles.get(i).id;
1225 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
1226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1227 | Intent.FLAG_RECEIVER_FOREGROUND);
1228 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001229 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001230 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1231 null, false, false, MY_PID, SYSTEM_UID, profileUserId);
1232 }
1233 intent = new Intent(Intent.ACTION_USER_SWITCHED);
1234 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1235 | Intent.FLAG_RECEIVER_FOREGROUND);
1236 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001237 mInjector.broadcastIntentLocked(intent,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001238 null, null, 0, null, null,
1239 new String[] {android.Manifest.permission.MANAGE_USERS},
1240 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
1241 UserHandle.USER_ALL);
1242 }
1243 } finally {
1244 Binder.restoreCallingIdentity(ident);
1245 }
1246 }
1247
1248
1249 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
1250 int allowMode, String name, String callerPackage) {
1251 final int callingUserId = UserHandle.getUserId(callingUid);
1252 if (callingUserId == userId) {
1253 return userId;
1254 }
1255
1256 // Note that we may be accessing mCurrentUserId outside of a lock...
1257 // shouldn't be a big deal, if this is being called outside
1258 // of a locked context there is intrinsically a race with
1259 // the value the caller will receive and someone else changing it.
1260 // We assume that USER_CURRENT_OR_SELF will use the current user; later
1261 // we will switch to the calling user if access to the current user fails.
1262 int targetUserId = unsafeConvertIncomingUserLocked(userId);
1263
1264 if (callingUid != 0 && callingUid != SYSTEM_UID) {
1265 final boolean allow;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001266 if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001267 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
1268 // If the caller has this permission, they always pass go. And collect $200.
1269 allow = true;
1270 } else if (allowMode == ALLOW_FULL_ONLY) {
1271 // We require full access, sucks to be you.
1272 allow = false;
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001273 } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001274 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1275 // If the caller does not have either permission, they are always doomed.
1276 allow = false;
1277 } else if (allowMode == ALLOW_NON_FULL) {
1278 // We are blanket allowing non-full access, you lucky caller!
1279 allow = true;
1280 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
1281 // We may or may not allow this depending on whether the two users are
1282 // in the same profile.
1283 allow = isSameProfileGroup(callingUserId, targetUserId);
1284 } else {
1285 throw new IllegalArgumentException("Unknown mode: " + allowMode);
1286 }
1287 if (!allow) {
1288 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
1289 // In this case, they would like to just execute as their
1290 // owner user instead of failing.
1291 targetUserId = callingUserId;
1292 } else {
1293 StringBuilder builder = new StringBuilder(128);
1294 builder.append("Permission Denial: ");
1295 builder.append(name);
1296 if (callerPackage != null) {
1297 builder.append(" from ");
1298 builder.append(callerPackage);
1299 }
1300 builder.append(" asks to run as user ");
1301 builder.append(userId);
1302 builder.append(" but is calling from user ");
1303 builder.append(UserHandle.getUserId(callingUid));
1304 builder.append("; this requires ");
1305 builder.append(INTERACT_ACROSS_USERS_FULL);
1306 if (allowMode != ALLOW_FULL_ONLY) {
1307 builder.append(" or ");
1308 builder.append(INTERACT_ACROSS_USERS);
1309 }
1310 String msg = builder.toString();
1311 Slog.w(TAG, msg);
1312 throw new SecurityException(msg);
1313 }
1314 }
1315 }
1316 if (!allowAll && targetUserId < 0) {
1317 throw new IllegalArgumentException(
1318 "Call does not support special user #" + targetUserId);
1319 }
1320 // Check shell permission
1321 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
1322 if (hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId)) {
1323 throw new SecurityException("Shell does not have permission to access user "
1324 + targetUserId + "\n " + Debug.getCallers(3));
1325 }
1326 }
1327 return targetUserId;
1328 }
1329
1330 int unsafeConvertIncomingUserLocked(int userId) {
1331 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
1332 ? getCurrentUserIdLocked(): userId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001333 }
1334
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001335 void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
1336 Preconditions.checkNotNull(name, "Observer name cannot be null");
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001337 if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001338 != PackageManager.PERMISSION_GRANTED) {
1339 final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
1340 + Binder.getCallingPid()
1341 + ", uid=" + Binder.getCallingUid()
1342 + " requires " + INTERACT_ACROSS_USERS_FULL;
1343 Slog.w(TAG, msg);
1344 throw new SecurityException(msg);
1345 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001346 mUserSwitchObservers.register(observer, name);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001347 }
1348
1349 void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
1350 mUserSwitchObservers.unregister(observer);
1351 }
1352
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001353 UserState getStartedUserStateLocked(int userId) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001354 return mStartedUsers.get(userId);
1355 }
1356
1357 boolean hasStartedUserState(int userId) {
1358 return mStartedUsers.get(userId) != null;
1359 }
1360
1361 private void updateStartedUserArrayLocked() {
1362 int num = 0;
1363 for (int i = 0; i < mStartedUsers.size(); i++) {
1364 UserState uss = mStartedUsers.valueAt(i);
1365 // This list does not include stopping users.
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001366 if (uss.state != UserState.STATE_STOPPING
1367 && uss.state != UserState.STATE_SHUTDOWN) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001368 num++;
1369 }
1370 }
1371 mStartedUserArray = new int[num];
1372 num = 0;
1373 for (int i = 0; i < mStartedUsers.size(); i++) {
1374 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001375 if (uss.state != UserState.STATE_STOPPING
1376 && uss.state != UserState.STATE_SHUTDOWN) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001377 mStartedUserArray[num++] = mStartedUsers.keyAt(i);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001378 }
1379 }
1380 }
1381
1382 void sendBootCompletedLocked(IIntentReceiver resultTo) {
1383 for (int i = 0; i < mStartedUsers.size(); i++) {
1384 UserState uss = mStartedUsers.valueAt(i);
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001385 finishUserBoot(uss, resultTo);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001386 }
1387 }
1388
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001389 void onSystemReady() {
1390 updateCurrentProfileIdsLocked();
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001391 }
1392
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001393 /**
1394 * Refreshes the list of users related to the current user when either a
1395 * user switch happens or when a new related user is started in the
1396 * background.
1397 */
Wale Ogunwalef80170f2016-02-04 15:12:29 -08001398 private void updateCurrentProfileIdsLocked() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001399 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(mCurrentUserId,
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001400 false /* enabledOnly */);
1401 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
1402 for (int i = 0; i < currentProfileIds.length; i++) {
1403 currentProfileIds[i] = profiles.get(i).id;
1404 }
1405 mCurrentProfileIds = currentProfileIds;
1406
1407 synchronized (mUserProfileGroupIdsSelfLocked) {
1408 mUserProfileGroupIdsSelfLocked.clear();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001409 final List<UserInfo> users = mInjector.getUserManager().getUsers(false);
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001410 for (int i = 0; i < users.size(); i++) {
1411 UserInfo user = users.get(i);
1412 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1413 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
1414 }
1415 }
1416 }
1417 }
1418
1419 int[] getStartedUserArrayLocked() {
1420 return mStartedUserArray;
1421 }
1422
Nicolas Prevot1219c922016-06-20 17:25:12 +01001423 boolean isUserStoppingOrShuttingDownLocked(int userId) {
1424 UserState state = getStartedUserStateLocked(userId);
1425 if (state == null) {
1426 return false;
1427 }
1428 return state.state == UserState.STATE_STOPPING
1429 || state.state == UserState.STATE_SHUTDOWN;
1430 }
1431
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001432 boolean isUserRunningLocked(int userId, int flags) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001433 UserState state = getStartedUserStateLocked(userId);
1434 if (state == null) {
1435 return false;
1436 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001437 if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001438 return true;
1439 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001440 if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001441 switch (state.state) {
1442 case UserState.STATE_BOOTING:
1443 case UserState.STATE_RUNNING_LOCKED:
1444 return true;
1445 default:
1446 return false;
1447 }
1448 }
1449 if ((flags & ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED) != 0) {
1450 switch (state.state) {
1451 case UserState.STATE_RUNNING_UNLOCKING:
1452 case UserState.STATE_RUNNING_UNLOCKED:
1453 return true;
1454 default:
1455 return false;
1456 }
Jeff Sharkeye17ac152015-11-06 22:40:29 -08001457 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001458 if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
Jeff Sharkeyce18c812016-04-27 16:00:41 -06001459 switch (state.state) {
1460 case UserState.STATE_RUNNING_UNLOCKED:
1461 return true;
1462 default:
1463 return false;
1464 }
Jeff Sharkeybedbaa92015-12-02 16:42:25 -07001465 }
1466
1467 // One way or another, we're running!
1468 return true;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001469 }
1470
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001471 UserInfo getCurrentUser() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001472 if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001473 != PackageManager.PERMISSION_GRANTED) && (
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001474 mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001475 != PackageManager.PERMISSION_GRANTED)) {
1476 String msg = "Permission Denial: getCurrentUser() from pid="
1477 + Binder.getCallingPid()
1478 + ", uid=" + Binder.getCallingUid()
1479 + " requires " + INTERACT_ACROSS_USERS;
1480 Slog.w(TAG, msg);
1481 throw new SecurityException(msg);
1482 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001483 synchronized (mLock) {
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001484 return getCurrentUserLocked();
1485 }
1486 }
1487
1488 UserInfo getCurrentUserLocked() {
1489 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001490 return getUserInfo(userId);
1491 }
1492
1493 int getCurrentOrTargetUserIdLocked() {
1494 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001495 }
1496
1497 int getCurrentUserIdLocked() {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001498 return mCurrentUserId;
1499 }
1500
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001501 private boolean isCurrentUserLocked(int userId) {
Amith Yamasani458ac462015-12-18 11:21:31 -08001502 return userId == getCurrentOrTargetUserIdLocked();
Fyodor Kupolov9cbfc9e2015-10-07 15:52:33 -07001503 }
1504
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001505 int setTargetUserIdLocked(int targetUserId) {
1506 return mTargetUserId = targetUserId;
1507 }
1508
1509 int[] getUsers() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001510 UserManagerService ums = mInjector.getUserManager();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001511 return ums != null ? ums.getUserIds() : new int[] { 0 };
1512 }
1513
1514 UserInfo getUserInfo(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001515 return mInjector.getUserManager().getUserInfo(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001516 }
1517
1518 int[] getUserIds() {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001519 return mInjector.getUserManager().getUserIds();
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001520 }
1521
1522 boolean exists(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001523 return mInjector.getUserManager().exists(userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001524 }
1525
1526 boolean hasUserRestriction(String restriction, int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001527 return mInjector.getUserManager().hasUserRestriction(restriction, userId);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001528 }
1529
1530 Set<Integer> getProfileIds(int userId) {
1531 Set<Integer> userIds = new HashSet<>();
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001532 final List<UserInfo> profiles = mInjector.getUserManager().getProfiles(userId,
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001533 false /* enabledOnly */);
1534 for (UserInfo user : profiles) {
1535 userIds.add(user.id);
1536 }
1537 return userIds;
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001538 }
1539
1540 boolean isSameProfileGroup(int callingUserId, int targetUserId) {
Makoto Onuki8198dea2016-07-28 13:10:42 -07001541 if (callingUserId == targetUserId) {
1542 return true;
1543 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001544 synchronized (mUserProfileGroupIdsSelfLocked) {
1545 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
1546 UserInfo.NO_PROFILE_GROUP_ID);
1547 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
1548 UserInfo.NO_PROFILE_GROUP_ID);
1549 return callingProfile != UserInfo.NO_PROFILE_GROUP_ID
1550 && callingProfile == targetProfile;
1551 }
1552 }
1553
1554 boolean isCurrentProfileLocked(int userId) {
1555 return ArrayUtils.contains(mCurrentProfileIds, userId);
1556 }
1557
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001558 int[] getCurrentProfileIdsLocked() {
1559 return mCurrentProfileIds;
1560 }
1561
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001562 /**
1563 * Returns whether the given user requires credential entry at this time. This is used to
1564 * intercept activity launches for work apps when the Work Challenge is present.
1565 */
1566 boolean shouldConfirmCredentials(int userId) {
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001567 synchronized (mLock) {
Rubin Xub93522a2016-02-23 18:21:48 +00001568 if (mStartedUsers.get(userId) == null) {
1569 return false;
1570 }
1571 }
Clara Bayarria1771112015-12-18 16:29:18 +00001572 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001573 return false;
1574 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001575 final KeyguardManager km = mInjector.getKeyguardManager();
Tony Makae13e182016-05-17 16:36:14 +01001576 return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
Clara Bayarriea9b10e2015-12-04 15:36:26 +00001577 }
1578
Tony Mak8c536f92016-03-21 12:20:41 +00001579 boolean isLockScreenDisabled(@UserIdInt int userId) {
1580 return mLockPatternUtils.isLockScreenDisabled(userId);
1581 }
1582
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001583 void dump(PrintWriter pw, boolean dumpAll) {
1584 pw.println(" mStartedUsers:");
1585 for (int i = 0; i < mStartedUsers.size(); i++) {
1586 UserState uss = mStartedUsers.valueAt(i);
1587 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
1588 pw.print(": "); uss.dump("", pw);
1589 }
1590 pw.print(" mStartedUserArray: [");
1591 for (int i = 0; i < mStartedUserArray.length; i++) {
1592 if (i > 0) pw.print(", ");
1593 pw.print(mStartedUserArray[i]);
1594 }
1595 pw.println("]");
1596 pw.print(" mUserLru: [");
1597 for (int i = 0; i < mUserLru.size(); i++) {
1598 if (i > 0) pw.print(", ");
1599 pw.print(mUserLru.get(i));
1600 }
1601 pw.println("]");
1602 if (dumpAll) {
1603 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
1604 }
1605 synchronized (mUserProfileGroupIdsSelfLocked) {
1606 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
1607 pw.println(" mUserProfileGroupIds:");
1608 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
1609 pw.print(" User #");
1610 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
1611 pw.print(" -> profile #");
1612 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
1613 }
1614 }
1615 }
1616 }
Fyodor Kupolovd6038db2016-06-22 16:53:19 -07001617
1618 @VisibleForTesting
1619 static class Injector {
1620 private final ActivityManagerService mService;
1621 private UserManagerService mUserManager;
1622 private UserManagerInternal mUserManagerInternal;
1623
1624 Injector(ActivityManagerService service) {
1625 mService = service;
1626 }
1627
1628 protected Object getLock() {
1629 return mService;
1630 }
1631
1632 protected Handler getHandler() {
1633 return mService.mHandler;
1634 }
1635
1636 protected Context getContext() {
1637 return mService.mContext;
1638 }
1639
1640 protected LockPatternUtils getLockPatternUtils() {
1641 return new LockPatternUtils(getContext());
1642 }
1643
1644 protected int broadcastIntentLocked(Intent intent, String resolvedType,
1645 IIntentReceiver resultTo, int resultCode, String resultData,
1646 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
1647 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
1648 return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
1649 resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
1650 ordered, sticky, callingPid, callingUid, userId);
1651 }
1652
1653 int checkCallingPermission(String permission) {
1654 return mService.checkCallingPermission(permission);
1655 }
1656
1657 WindowManagerService getWindowManager() {
1658 return mService.mWindowManager;
1659 }
1660 void activityManagerOnUserStopped(int userId) {
1661 mService.onUserStoppedLocked(userId);
1662 }
1663
1664 void systemServiceManagerCleanupUser(int userId) {
1665 mService.mSystemServiceManager.cleanupUser(userId);
1666 }
1667
1668 void stackSupervisorRemoveUserLocked(int userId) {
1669 mService.mStackSupervisor.removeUserLocked(userId);
1670 }
1671
1672 protected UserManagerService getUserManager() {
1673 if (mUserManager == null) {
1674 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
1675 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
1676 }
1677 return mUserManager;
1678 }
1679
1680 UserManagerInternal getUserManagerInternal() {
1681 if (mUserManagerInternal == null) {
1682 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1683 }
1684 return mUserManagerInternal;
1685 }
1686
1687 KeyguardManager getKeyguardManager() {
1688 return mService.mContext.getSystemService(KeyguardManager.class);
1689 }
1690
1691 void batteryStatsServiceNoteEvent(int code, String name, int uid) {
1692 mService.mBatteryStatsService.noteEvent(code, name, uid);
1693 }
1694
1695 void systemServiceManagerStopUser(int userId) {
1696 mService.mSystemServiceManager.stopUser(userId);
1697 }
1698
1699 void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
1700 new PreBootBroadcaster(mService, userId, null, quiet) {
1701 @Override
1702 public void onFinished() {
1703 onFinish.run();
1704 }
1705 }.sendNext();
1706 }
1707
1708 void activityManagerForceStopPackageLocked(int userId, String reason) {
1709 mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
1710 userId, reason);
1711 };
1712
1713 int checkComponentPermission(String permission, int pid, int uid, int owningUid,
1714 boolean exported) {
1715 return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
1716 }
1717
1718 boolean stackSupervisorSwitchUserLocked(int userId, UserState uss) {
1719 return mService.mStackSupervisor.switchUserLocked(userId, uss);
1720 }
1721
1722 void startHomeActivityLocked(int userId, String reason) {
1723 mService.startHomeActivityLocked(userId, reason);
1724 }
1725
1726 void stackSupervisorResumeFocusedStackTopActivityLocked() {
1727 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
1728 }
1729
1730 void stackSupervisorSetLockTaskModeLocked(TaskRecord task, int lockTaskModeState,
1731 String reason, boolean andResume) {
1732 mService.mStackSupervisor.setLockTaskModeLocked(task, lockTaskModeState, reason,
1733 andResume);
1734 }
1735
1736 void updateUserConfigurationLocked() {
1737 mService.updateUserConfigurationLocked();
1738 }
1739
1740 void clearBroadcastQueueForUserLocked(int userId) {
1741 mService.clearBroadcastQueueForUserLocked(userId);
1742 }
1743
1744 void enforceShellRestriction(String restriction, int userId) {
1745 mService.enforceShellRestriction(restriction, userId);
1746 }
1747
1748 void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser) {
1749 Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
1750 true /* above system */);
1751 d.show();
1752 }
1753 }
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001754}