1 /* 2 * Copyright (C) 2011 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 17 package com.android.server.pm; 18 19 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 20 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21 22 import android.Manifest; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.UserIdInt; 26 import android.app.Activity; 27 import android.app.ActivityManager; 28 import android.app.ActivityManagerInternal; 29 import android.app.ActivityManagerNative; 30 import android.app.IActivityManager; 31 import android.app.IStopUserCallback; 32 import android.app.KeyguardManager; 33 import android.app.PendingIntent; 34 import android.app.admin.DevicePolicyManager; 35 import android.content.BroadcastReceiver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.IntentSender; 40 import android.content.pm.PackageManager; 41 import android.content.pm.PackageManager.NameNotFoundException; 42 import android.content.pm.ShortcutServiceInternal; 43 import android.content.pm.UserInfo; 44 import android.content.res.Resources; 45 import android.graphics.Bitmap; 46 import android.os.Binder; 47 import android.os.Build; 48 import android.os.Bundle; 49 import android.os.Debug; 50 import android.os.Environment; 51 import android.os.FileUtils; 52 import android.os.Handler; 53 import android.os.IBinder; 54 import android.os.IProgressListener; 55 import android.os.IUserManager; 56 import android.os.Message; 57 import android.os.ParcelFileDescriptor; 58 import android.os.Parcelable; 59 import android.os.PersistableBundle; 60 import android.os.Process; 61 import android.os.RemoteException; 62 import android.os.ResultReceiver; 63 import android.os.SELinux; 64 import android.os.ServiceManager; 65 import android.os.ShellCallback; 66 import android.os.ShellCommand; 67 import android.os.SystemClock; 68 import android.os.SystemProperties; 69 import android.os.UserHandle; 70 import android.os.UserManager; 71 import android.os.UserManager.EnforcingUser; 72 import android.os.UserManagerInternal; 73 import android.os.UserManagerInternal.UserRestrictionsListener; 74 import android.os.storage.StorageManager; 75 import android.provider.Settings; 76 import android.security.GateKeeper; 77 import android.service.gatekeeper.IGateKeeperService; 78 import android.util.AtomicFile; 79 import android.util.IntArray; 80 import android.util.Log; 81 import android.util.Slog; 82 import android.util.SparseArray; 83 import android.util.SparseBooleanArray; 84 import android.util.SparseIntArray; 85 import android.util.SparseLongArray; 86 import android.util.TimeUtils; 87 import android.util.Xml; 88 89 import com.android.internal.annotations.GuardedBy; 90 import com.android.internal.annotations.VisibleForTesting; 91 import com.android.internal.app.IAppOpsService; 92 import com.android.internal.logging.MetricsLogger; 93 import com.android.internal.os.BackgroundThread; 94 import com.android.internal.util.DumpUtils; 95 import com.android.internal.util.FastXmlSerializer; 96 import com.android.internal.util.Preconditions; 97 import com.android.internal.util.XmlUtils; 98 import com.android.internal.widget.LockPatternUtils; 99 import com.android.server.LocalServices; 100 import com.android.server.LockGuard; 101 import com.android.server.SystemService; 102 import com.android.server.am.UserState; 103 import com.android.server.storage.DeviceStorageMonitorInternal; 104 105 import libcore.io.IoUtils; 106 107 import org.xmlpull.v1.XmlPullParser; 108 import org.xmlpull.v1.XmlPullParserException; 109 import org.xmlpull.v1.XmlSerializer; 110 111 import java.io.BufferedOutputStream; 112 import java.io.File; 113 import java.io.FileDescriptor; 114 import java.io.FileInputStream; 115 import java.io.FileNotFoundException; 116 import java.io.FileOutputStream; 117 import java.io.IOException; 118 import java.io.InputStream; 119 import java.io.OutputStream; 120 import java.io.PrintWriter; 121 import java.nio.charset.StandardCharsets; 122 import java.util.ArrayList; 123 import java.util.Collections; 124 import java.util.LinkedList; 125 import java.util.List; 126 import java.util.Objects; 127 128 /** 129 * Service for {@link UserManager}. 130 * 131 * Method naming convention: 132 * <ul> 133 * <li> Methods suffixed with "LAr" should be called within the {@link #mAppRestrictionsLock} lock. 134 * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock. 135 * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock. 136 * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock. 137 * </ul> 138 */ 139 public class UserManagerService extends IUserManager.Stub { 140 141 private static final String LOG_TAG = "UserManagerService"; 142 static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE 143 private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE 144 // Can be used for manual testing of id recycling 145 private static final boolean RELEASE_DELETED_USER_ID = false; // DO NOT SUBMIT WITH TRUE 146 147 private static final String TAG_NAME = "name"; 148 private static final String TAG_ACCOUNT = "account"; 149 private static final String ATTR_FLAGS = "flags"; 150 private static final String ATTR_ICON_PATH = "icon"; 151 private static final String ATTR_ID = "id"; 152 private static final String ATTR_CREATION_TIME = "created"; 153 private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn"; 154 private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint"; 155 private static final String ATTR_SERIAL_NO = "serialNumber"; 156 private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; 157 private static final String ATTR_PARTIAL = "partial"; 158 private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove"; 159 private static final String ATTR_USER_VERSION = "version"; 160 private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId"; 161 private static final String ATTR_PROFILE_BADGE = "profileBadge"; 162 private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId"; 163 private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName"; 164 private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType"; 165 private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions"; 166 private static final String TAG_USERS = "users"; 167 private static final String TAG_USER = "user"; 168 private static final String TAG_RESTRICTIONS = "restrictions"; 169 private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions"; 170 private static final String TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS = 171 "device_policy_global_restrictions"; 172 /** Legacy name for device owner id tag. */ 173 private static final String TAG_GLOBAL_RESTRICTION_OWNER_ID = "globalRestrictionOwnerUserId"; 174 private static final String TAG_DEVICE_OWNER_USER_ID = "deviceOwnerUserId"; 175 private static final String TAG_ENTRY = "entry"; 176 private static final String TAG_VALUE = "value"; 177 private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; 178 private static final String ATTR_KEY = "key"; 179 private static final String ATTR_VALUE_TYPE = "type"; 180 private static final String ATTR_MULTIPLE = "m"; 181 182 private static final String ATTR_TYPE_STRING_ARRAY = "sa"; 183 private static final String ATTR_TYPE_STRING = "s"; 184 private static final String ATTR_TYPE_BOOLEAN = "b"; 185 private static final String ATTR_TYPE_INTEGER = "i"; 186 private static final String ATTR_TYPE_BUNDLE = "B"; 187 private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA"; 188 189 private static final String USER_INFO_DIR = "system" + File.separator + "users"; 190 private static final String USER_LIST_FILENAME = "userlist.xml"; 191 private static final String USER_PHOTO_FILENAME = "photo.png"; 192 private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp"; 193 194 private static final String RESTRICTIONS_FILE_PREFIX = "res_"; 195 private static final String XML_SUFFIX = ".xml"; 196 197 private static final int ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION = 198 UserInfo.FLAG_MANAGED_PROFILE 199 | UserInfo.FLAG_EPHEMERAL 200 | UserInfo.FLAG_RESTRICTED 201 | UserInfo.FLAG_GUEST 202 | UserInfo.FLAG_DEMO; 203 204 @VisibleForTesting 205 static final int MIN_USER_ID = 10; 206 // We need to keep process uid within Integer.MAX_VALUE. 207 @VisibleForTesting 208 static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE; 209 210 // Max size of the queue of recently removed users 211 @VisibleForTesting 212 static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100; 213 214 private static final int USER_VERSION = 7; 215 216 private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms 217 218 // Maximum number of managed profiles permitted per user is 1. This cannot be increased 219 // without first making sure that the rest of the framework is prepared for it. 220 @VisibleForTesting 221 static final int MAX_MANAGED_PROFILES = 1; 222 223 static final int WRITE_USER_MSG = 1; 224 static final int WRITE_USER_DELAY = 2*1000; // 2 seconds 225 226 // Tron counters 227 private static final String TRON_GUEST_CREATED = "users_guest_created"; 228 private static final String TRON_USER_CREATED = "users_user_created"; 229 private static final String TRON_DEMO_CREATED = "users_demo_created"; 230 231 private final Context mContext; 232 private final PackageManagerService mPm; 233 private final Object mPackagesLock; 234 private final UserDataPreparer mUserDataPreparer; 235 // Short-term lock for internal state, when interaction/sync with PM is not required 236 private final Object mUsersLock = LockGuard.installNewLock(LockGuard.INDEX_USER); 237 private final Object mRestrictionsLock = new Object(); 238 // Used for serializing access to app restriction files 239 private final Object mAppRestrictionsLock = new Object(); 240 241 private final Handler mHandler; 242 243 private final File mUsersDir; 244 private final File mUserListFile; 245 246 private static final IBinder mUserRestriconToken = new Binder(); 247 248 /** 249 * Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps. 250 */ 251 @VisibleForTesting 252 static class UserData { 253 // Basic user information and properties 254 UserInfo info; 255 // Account name used when there is a strong association between a user and an account 256 String account; 257 // Account information for seeding into a newly created user. This could also be 258 // used for login validation for an existing user, for updating their credentials. 259 // In the latter case, data may not need to be persisted as it is only valid for the 260 // current login session. 261 String seedAccountName; 262 String seedAccountType; 263 PersistableBundle seedAccountOptions; 264 // Whether to perist the seed account information to be available after a boot 265 boolean persistSeedData; 266 267 /** Elapsed realtime since boot when the user started. */ 268 long startRealtime; 269 270 /** Elapsed realtime since boot when the user was unlocked. */ 271 long unlockRealtime; 272 clearSeedAccountData()273 void clearSeedAccountData() { 274 seedAccountName = null; 275 seedAccountType = null; 276 seedAccountOptions = null; 277 persistSeedData = false; 278 } 279 } 280 281 @GuardedBy("mUsersLock") 282 private final SparseArray<UserData> mUsers = new SparseArray<>(); 283 284 /** 285 * User restrictions set via UserManager. This doesn't include restrictions set by 286 * device owner / profile owners. Only non-empty restriction bundles are stored. 287 * 288 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 289 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 290 * maybe shared between {@link #mBaseUserRestrictions} and 291 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 292 * (Otherwise we won't be able to detect what restrictions have changed in 293 * {@link #updateUserRestrictionsInternalLR}. 294 */ 295 @GuardedBy("mRestrictionsLock") 296 private final SparseArray<Bundle> mBaseUserRestrictions = new SparseArray<>(); 297 298 /** 299 * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined 300 * with device / profile owner restrictions. We'll initialize it lazily; use 301 * {@link #getEffectiveUserRestrictions} to access it. 302 * 303 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 304 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 305 * maybe shared between {@link #mBaseUserRestrictions} and 306 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 307 * (Otherwise we won't be able to detect what restrictions have changed in 308 * {@link #updateUserRestrictionsInternalLR}. 309 */ 310 @GuardedBy("mRestrictionsLock") 311 private final SparseArray<Bundle> mCachedEffectiveUserRestrictions = new SparseArray<>(); 312 313 /** 314 * User restrictions that have already been applied in 315 * {@link #updateUserRestrictionsInternalLR(Bundle, int)}. We use it to detect restrictions 316 * that have changed since the last 317 * {@link #updateUserRestrictionsInternalLR(Bundle, int)} call. 318 */ 319 @GuardedBy("mRestrictionsLock") 320 private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>(); 321 322 /** 323 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 324 * that should be applied to all users, including guests. Only non-empty restriction bundles are 325 * stored. 326 */ 327 @GuardedBy("mRestrictionsLock") 328 private final SparseArray<Bundle> mDevicePolicyGlobalUserRestrictions = new SparseArray<>(); 329 330 /** 331 * Id of the user that set global restrictions. 332 */ 333 @GuardedBy("mRestrictionsLock") 334 private int mDeviceOwnerUserId = UserHandle.USER_NULL; 335 336 /** 337 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 338 * for each user. Only non-empty restriction bundles are stored. 339 */ 340 @GuardedBy("mRestrictionsLock") 341 private final SparseArray<Bundle> mDevicePolicyLocalUserRestrictions = new SparseArray<>(); 342 343 @GuardedBy("mGuestRestrictions") 344 private final Bundle mGuestRestrictions = new Bundle(); 345 346 /** 347 * Set of user IDs being actively removed. Removed IDs linger in this set 348 * for several seconds to work around a VFS caching issue. 349 * Use {@link #addRemovingUserIdLocked(int)} to add elements to this array 350 */ 351 @GuardedBy("mUsersLock") 352 private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray(); 353 354 /** 355 * Queue of recently removed userIds. Used for recycling of userIds 356 */ 357 @GuardedBy("mUsersLock") 358 private final LinkedList<Integer> mRecentlyRemovedIds = new LinkedList<>(); 359 360 @GuardedBy("mUsersLock") 361 private int[] mUserIds; 362 @GuardedBy("mPackagesLock") 363 private int mNextSerialNumber; 364 private int mUserVersion = 0; 365 366 private IAppOpsService mAppOpsService; 367 368 private final LocalService mLocalService; 369 370 @GuardedBy("mUsersLock") 371 private boolean mIsDeviceManaged; 372 373 @GuardedBy("mUsersLock") 374 private final SparseBooleanArray mIsUserManaged = new SparseBooleanArray(); 375 376 @GuardedBy("mUserRestrictionsListeners") 377 private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners = 378 new ArrayList<>(); 379 380 private final LockPatternUtils mLockPatternUtils; 381 382 private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK = 383 "com.android.server.pm.DISABLE_QUIET_MODE_AFTER_UNLOCK"; 384 385 private final BroadcastReceiver mDisableQuietModeCallback = new BroadcastReceiver() { 386 @Override 387 public void onReceive(Context context, Intent intent) { 388 if (!ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK.equals(intent.getAction())) { 389 return; 390 } 391 final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT); 392 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); 393 // Call setQuietModeEnabled on bg thread to avoid ANR 394 BackgroundThread.getHandler() 395 .post(() -> setQuietModeEnabled(userHandle, false, target)); 396 } 397 }; 398 399 /** 400 * Start an {@link IntentSender} when user is unlocked after disabling quiet mode. 401 * 402 * @see {@link #requestQuietModeEnabled(String, boolean, int, IntentSender)} 403 */ 404 private class DisableQuietModeUserUnlockedCallback extends IProgressListener.Stub { 405 private final IntentSender mTarget; 406 DisableQuietModeUserUnlockedCallback(IntentSender target)407 public DisableQuietModeUserUnlockedCallback(IntentSender target) { 408 Preconditions.checkNotNull(target); 409 mTarget = target; 410 } 411 412 @Override onStarted(int id, Bundle extras)413 public void onStarted(int id, Bundle extras) {} 414 415 @Override onProgress(int id, int progress, Bundle extras)416 public void onProgress(int id, int progress, Bundle extras) {} 417 418 @Override onFinished(int id, Bundle extras)419 public void onFinished(int id, Bundle extras) { 420 try { 421 mContext.startIntentSender(mTarget, null, 0, 0, 0); 422 } catch (IntentSender.SendIntentException e) { 423 Slog.e(LOG_TAG, "Failed to start the target in the callback", e); 424 } 425 } 426 } 427 428 /** 429 * Whether all users should be created ephemeral. 430 */ 431 @GuardedBy("mUsersLock") 432 private boolean mForceEphemeralUsers; 433 434 @GuardedBy("mUserStates") 435 private final SparseIntArray mUserStates = new SparseIntArray(); 436 437 private static UserManagerService sInstance; 438 getInstance()439 public static UserManagerService getInstance() { 440 synchronized (UserManagerService.class) { 441 return sInstance; 442 } 443 } 444 445 public static class LifeCycle extends SystemService { 446 447 private UserManagerService mUms; 448 449 /** 450 * @param context 451 */ LifeCycle(Context context)452 public LifeCycle(Context context) { 453 super(context); 454 } 455 456 @Override onStart()457 public void onStart() { 458 mUms = UserManagerService.getInstance(); 459 publishBinderService(Context.USER_SERVICE, mUms); 460 } 461 462 @Override onBootPhase(int phase)463 public void onBootPhase(int phase) { 464 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 465 mUms.cleanupPartialUsers(); 466 } 467 } 468 469 @Override onStartUser(int userHandle)470 public void onStartUser(int userHandle) { 471 synchronized (mUms.mUsersLock) { 472 final UserData user = mUms.getUserDataLU(userHandle); 473 if (user != null) { 474 user.startRealtime = SystemClock.elapsedRealtime(); 475 } 476 } 477 } 478 479 @Override onUnlockUser(int userHandle)480 public void onUnlockUser(int userHandle) { 481 synchronized (mUms.mUsersLock) { 482 final UserData user = mUms.getUserDataLU(userHandle); 483 if (user != null) { 484 user.unlockRealtime = SystemClock.elapsedRealtime(); 485 } 486 } 487 } 488 489 @Override onStopUser(int userHandle)490 public void onStopUser(int userHandle) { 491 synchronized (mUms.mUsersLock) { 492 final UserData user = mUms.getUserDataLU(userHandle); 493 if (user != null) { 494 user.startRealtime = 0; 495 user.unlockRealtime = 0; 496 } 497 } 498 } 499 } 500 501 // TODO b/28848102 Add support for test dependencies injection 502 @VisibleForTesting UserManagerService(Context context)503 UserManagerService(Context context) { 504 this(context, null, null, new Object(), context.getCacheDir()); 505 } 506 507 /** 508 * Called by package manager to create the service. This is closely 509 * associated with the package manager, and the given lock is the 510 * package manager's own lock. 511 */ UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock)512 UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, 513 Object packagesLock) { 514 this(context, pm, userDataPreparer, packagesLock, Environment.getDataDirectory()); 515 } 516 UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock, File dataDir)517 private UserManagerService(Context context, PackageManagerService pm, 518 UserDataPreparer userDataPreparer, Object packagesLock, File dataDir) { 519 mContext = context; 520 mPm = pm; 521 mPackagesLock = packagesLock; 522 mHandler = new MainHandler(); 523 mUserDataPreparer = userDataPreparer; 524 synchronized (mPackagesLock) { 525 mUsersDir = new File(dataDir, USER_INFO_DIR); 526 mUsersDir.mkdirs(); 527 // Make zeroth user directory, for services to migrate their files to that location 528 File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM)); 529 userZeroDir.mkdirs(); 530 FileUtils.setPermissions(mUsersDir.toString(), 531 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, 532 -1, -1); 533 mUserListFile = new File(mUsersDir, USER_LIST_FILENAME); 534 initDefaultGuestRestrictions(); 535 readUserListLP(); 536 sInstance = this; 537 } 538 mLocalService = new LocalService(); 539 LocalServices.addService(UserManagerInternal.class, mLocalService); 540 mLockPatternUtils = new LockPatternUtils(mContext); 541 mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING); 542 } 543 systemReady()544 void systemReady() { 545 mAppOpsService = IAppOpsService.Stub.asInterface( 546 ServiceManager.getService(Context.APP_OPS_SERVICE)); 547 548 synchronized (mRestrictionsLock) { 549 applyUserRestrictionsLR(UserHandle.USER_SYSTEM); 550 } 551 552 UserInfo currentGuestUser = findCurrentGuestUser(); 553 if (currentGuestUser != null && !hasUserRestriction( 554 UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) { 555 // If a guest user currently exists, apply the DISALLOW_CONFIG_WIFI option 556 // to it, in case this guest was created in a previous version where this 557 // user restriction was not a default guest restriction. 558 setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id); 559 } 560 561 mContext.registerReceiver(mDisableQuietModeCallback, 562 new IntentFilter(ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK), 563 null, mHandler); 564 } 565 cleanupPartialUsers()566 void cleanupPartialUsers() { 567 // Prune out any partially created, partially removed and ephemeral users. 568 ArrayList<UserInfo> partials = new ArrayList<>(); 569 synchronized (mUsersLock) { 570 final int userSize = mUsers.size(); 571 for (int i = 0; i < userSize; i++) { 572 UserInfo ui = mUsers.valueAt(i).info; 573 if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) { 574 partials.add(ui); 575 addRemovingUserIdLocked(ui.id); 576 ui.partial = true; 577 } 578 } 579 } 580 final int partialsSize = partials.size(); 581 for (int i = 0; i < partialsSize; i++) { 582 UserInfo ui = partials.get(i); 583 Slog.w(LOG_TAG, "Removing partially created user " + ui.id 584 + " (name=" + ui.name + ")"); 585 removeUserState(ui.id); 586 } 587 } 588 589 @Override getUserAccount(int userId)590 public String getUserAccount(int userId) { 591 checkManageUserAndAcrossUsersFullPermission("get user account"); 592 synchronized (mUsersLock) { 593 return mUsers.get(userId).account; 594 } 595 } 596 597 @Override setUserAccount(int userId, String accountName)598 public void setUserAccount(int userId, String accountName) { 599 checkManageUserAndAcrossUsersFullPermission("set user account"); 600 UserData userToUpdate = null; 601 synchronized (mPackagesLock) { 602 synchronized (mUsersLock) { 603 final UserData userData = mUsers.get(userId); 604 if (userData == null) { 605 Slog.e(LOG_TAG, "User not found for setting user account: u" + userId); 606 return; 607 } 608 String currentAccount = userData.account; 609 if (!Objects.equals(currentAccount, accountName)) { 610 userData.account = accountName; 611 userToUpdate = userData; 612 } 613 } 614 615 if (userToUpdate != null) { 616 writeUserLP(userToUpdate); 617 } 618 } 619 } 620 621 @Override getPrimaryUser()622 public UserInfo getPrimaryUser() { 623 checkManageUsersPermission("query users"); 624 synchronized (mUsersLock) { 625 final int userSize = mUsers.size(); 626 for (int i = 0; i < userSize; i++) { 627 UserInfo ui = mUsers.valueAt(i).info; 628 if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) { 629 return ui; 630 } 631 } 632 } 633 return null; 634 } 635 636 @Override getUsers(boolean excludeDying)637 public @NonNull List<UserInfo> getUsers(boolean excludeDying) { 638 checkManageOrCreateUsersPermission("query users"); 639 synchronized (mUsersLock) { 640 ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size()); 641 final int userSize = mUsers.size(); 642 for (int i = 0; i < userSize; i++) { 643 UserInfo ui = mUsers.valueAt(i).info; 644 if (ui.partial) { 645 continue; 646 } 647 if (!excludeDying || !mRemovingUserIds.get(ui.id)) { 648 users.add(userWithName(ui)); 649 } 650 } 651 return users; 652 } 653 } 654 655 @Override getProfiles(int userId, boolean enabledOnly)656 public List<UserInfo> getProfiles(int userId, boolean enabledOnly) { 657 boolean returnFullInfo = true; 658 if (userId != UserHandle.getCallingUserId()) { 659 checkManageOrCreateUsersPermission("getting profiles related to user " + userId); 660 } else { 661 returnFullInfo = hasManageUsersPermission(); 662 } 663 final long ident = Binder.clearCallingIdentity(); 664 try { 665 synchronized (mUsersLock) { 666 return getProfilesLU(userId, enabledOnly, returnFullInfo); 667 } 668 } finally { 669 Binder.restoreCallingIdentity(ident); 670 } 671 } 672 673 @Override getProfileIds(int userId, boolean enabledOnly)674 public int[] getProfileIds(int userId, boolean enabledOnly) { 675 if (userId != UserHandle.getCallingUserId()) { 676 checkManageOrCreateUsersPermission("getting profiles related to user " + userId); 677 } 678 final long ident = Binder.clearCallingIdentity(); 679 try { 680 synchronized (mUsersLock) { 681 return getProfileIdsLU(userId, enabledOnly).toArray(); 682 } 683 } finally { 684 Binder.restoreCallingIdentity(ident); 685 } 686 } 687 688 /** Assume permissions already checked and caller's identity cleared */ getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo)689 private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) { 690 IntArray profileIds = getProfileIdsLU(userId, enabledOnly); 691 ArrayList<UserInfo> users = new ArrayList<>(profileIds.size()); 692 for (int i = 0; i < profileIds.size(); i++) { 693 int profileId = profileIds.get(i); 694 UserInfo userInfo = mUsers.get(profileId).info; 695 // If full info is not required - clear PII data to prevent 3P apps from reading it 696 if (!fullInfo) { 697 userInfo = new UserInfo(userInfo); 698 userInfo.name = null; 699 userInfo.iconPath = null; 700 } else { 701 userInfo = userWithName(userInfo); 702 } 703 users.add(userInfo); 704 } 705 return users; 706 } 707 708 /** 709 * Assume permissions already checked and caller's identity cleared 710 */ getProfileIdsLU(int userId, boolean enabledOnly)711 private IntArray getProfileIdsLU(int userId, boolean enabledOnly) { 712 UserInfo user = getUserInfoLU(userId); 713 IntArray result = new IntArray(mUsers.size()); 714 if (user == null) { 715 // Probably a dying user 716 return result; 717 } 718 final int userSize = mUsers.size(); 719 for (int i = 0; i < userSize; i++) { 720 UserInfo profile = mUsers.valueAt(i).info; 721 if (!isProfileOf(user, profile)) { 722 continue; 723 } 724 if (enabledOnly && !profile.isEnabled()) { 725 continue; 726 } 727 if (mRemovingUserIds.get(profile.id)) { 728 continue; 729 } 730 if (profile.partial) { 731 continue; 732 } 733 result.add(profile.id); 734 } 735 return result; 736 } 737 738 @Override getCredentialOwnerProfile(int userHandle)739 public int getCredentialOwnerProfile(int userHandle) { 740 checkManageUsersPermission("get the credential owner"); 741 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) { 742 synchronized (mUsersLock) { 743 UserInfo profileParent = getProfileParentLU(userHandle); 744 if (profileParent != null) { 745 return profileParent.id; 746 } 747 } 748 } 749 750 return userHandle; 751 } 752 753 @Override isSameProfileGroup(int userId, int otherUserId)754 public boolean isSameProfileGroup(int userId, int otherUserId) { 755 if (userId == otherUserId) return true; 756 checkManageUsersPermission("check if in the same profile group"); 757 return isSameProfileGroupNoChecks(userId, otherUserId); 758 } 759 isSameProfileGroupNoChecks(int userId, int otherUserId)760 private boolean isSameProfileGroupNoChecks(int userId, int otherUserId) { 761 synchronized (mUsersLock) { 762 UserInfo userInfo = getUserInfoLU(userId); 763 if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 764 return false; 765 } 766 UserInfo otherUserInfo = getUserInfoLU(otherUserId); 767 if (otherUserInfo == null 768 || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 769 return false; 770 } 771 return userInfo.profileGroupId == otherUserInfo.profileGroupId; 772 } 773 } 774 775 @Override getProfileParent(int userHandle)776 public UserInfo getProfileParent(int userHandle) { 777 checkManageUsersPermission("get the profile parent"); 778 synchronized (mUsersLock) { 779 return getProfileParentLU(userHandle); 780 } 781 } 782 783 @Override getProfileParentId(int userHandle)784 public int getProfileParentId(int userHandle) { 785 checkManageUsersPermission("get the profile parent"); 786 return mLocalService.getProfileParentId(userHandle); 787 } 788 getProfileParentLU(int userHandle)789 private UserInfo getProfileParentLU(int userHandle) { 790 UserInfo profile = getUserInfoLU(userHandle); 791 if (profile == null) { 792 return null; 793 } 794 int parentUserId = profile.profileGroupId; 795 if (parentUserId == userHandle || parentUserId == UserInfo.NO_PROFILE_GROUP_ID) { 796 return null; 797 } else { 798 return getUserInfoLU(parentUserId); 799 } 800 } 801 isProfileOf(UserInfo user, UserInfo profile)802 private static boolean isProfileOf(UserInfo user, UserInfo profile) { 803 return user.id == profile.id || 804 (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 805 && user.profileGroupId == profile.profileGroupId); 806 } 807 broadcastProfileAvailabilityChanges(UserHandle profileHandle, UserHandle parentHandle, boolean inQuietMode)808 private void broadcastProfileAvailabilityChanges(UserHandle profileHandle, 809 UserHandle parentHandle, boolean inQuietMode) { 810 Intent intent = new Intent(); 811 if (inQuietMode) { 812 intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); 813 } else { 814 intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); 815 } 816 intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); 817 intent.putExtra(Intent.EXTRA_USER, profileHandle); 818 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); 819 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 820 mContext.sendBroadcastAsUser(intent, parentHandle); 821 } 822 823 @Override requestQuietModeEnabled(@onNull String callingPackage, boolean enableQuietMode, int userHandle, @Nullable IntentSender target)824 public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode, 825 int userHandle, @Nullable IntentSender target) { 826 Preconditions.checkNotNull(callingPackage); 827 828 if (enableQuietMode && target != null) { 829 throw new IllegalArgumentException( 830 "target should only be specified when we are disabling quiet mode."); 831 } 832 833 ensureCanModifyQuietMode(callingPackage, Binder.getCallingUid(), target != null); 834 final long identity = Binder.clearCallingIdentity(); 835 try { 836 if (enableQuietMode) { 837 setQuietModeEnabled(userHandle, true /* enableQuietMode */, target); 838 return true; 839 } else { 840 boolean needToShowConfirmCredential = 841 mLockPatternUtils.isSecure(userHandle) 842 && !StorageManager.isUserKeyUnlocked(userHandle); 843 if (needToShowConfirmCredential) { 844 showConfirmCredentialToDisableQuietMode(userHandle, target); 845 return false; 846 } else { 847 setQuietModeEnabled(userHandle, false /* enableQuietMode */, target); 848 return true; 849 } 850 } 851 } finally { 852 Binder.restoreCallingIdentity(identity); 853 } 854 } 855 856 /** 857 * The caller can modify quiet mode if it meets one of these conditions: 858 * <ul> 859 * <li>Has system UID or root UID</li> 860 * <li>Has {@link Manifest.permission#MODIFY_QUIET_MODE}</li> 861 * <li>Has {@link Manifest.permission#MANAGE_USERS}</li> 862 * </ul> 863 * <p> 864 * If caller wants to start an intent after disabling the quiet mode, it must has 865 * {@link Manifest.permission#MANAGE_USERS}. 866 */ ensureCanModifyQuietMode(String callingPackage, int callingUid, boolean startIntent)867 private void ensureCanModifyQuietMode(String callingPackage, int callingUid, 868 boolean startIntent) { 869 if (hasManageUsersPermission()) { 870 return; 871 } 872 if (startIntent) { 873 throw new SecurityException("MANAGE_USERS permission is required to start intent " 874 + "after disabling quiet mode."); 875 } 876 final boolean hasModifyQuietModePermission = hasPermissionGranted( 877 Manifest.permission.MODIFY_QUIET_MODE, callingUid); 878 if (hasModifyQuietModePermission) { 879 return; 880 } 881 882 verifyCallingPackage(callingPackage, callingUid); 883 final ShortcutServiceInternal shortcutInternal = 884 LocalServices.getService(ShortcutServiceInternal.class); 885 if (shortcutInternal != null) { 886 boolean isForegroundLauncher = 887 shortcutInternal.isForegroundDefaultLauncher(callingPackage, callingUid); 888 if (isForegroundLauncher) { 889 return; 890 } 891 } 892 throw new SecurityException("Can't modify quiet mode, caller is neither foreground " 893 + "default launcher nor has MANAGE_USERS/MODIFY_QUIET_MODE permission"); 894 } 895 setQuietModeEnabled( int userHandle, boolean enableQuietMode, IntentSender target)896 private void setQuietModeEnabled( 897 int userHandle, boolean enableQuietMode, IntentSender target) { 898 final UserInfo profile, parent; 899 final UserData profileUserData; 900 synchronized (mUsersLock) { 901 profile = getUserInfoLU(userHandle); 902 parent = getProfileParentLU(userHandle); 903 904 if (profile == null || !profile.isManagedProfile()) { 905 throw new IllegalArgumentException("User " + userHandle + " is not a profile"); 906 } 907 if (profile.isQuietModeEnabled() == enableQuietMode) { 908 Slog.i(LOG_TAG, "Quiet mode is already " + enableQuietMode); 909 return; 910 } 911 profile.flags ^= UserInfo.FLAG_QUIET_MODE; 912 profileUserData = getUserDataLU(profile.id); 913 } 914 synchronized (mPackagesLock) { 915 writeUserLP(profileUserData); 916 } 917 try { 918 if (enableQuietMode) { 919 ActivityManager.getService().stopUser(userHandle, /* force */true, null); 920 LocalServices.getService(ActivityManagerInternal.class) 921 .killForegroundAppsForUser(userHandle); 922 } else { 923 IProgressListener callback = target != null 924 ? new DisableQuietModeUserUnlockedCallback(target) 925 : null; 926 ActivityManager.getService().startUserInBackgroundWithListener( 927 userHandle, callback); 928 } 929 } catch (RemoteException e) { 930 // Should not happen, same process. 931 e.rethrowAsRuntimeException(); 932 } 933 broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(), 934 enableQuietMode); 935 } 936 937 @Override isQuietModeEnabled(int userHandle)938 public boolean isQuietModeEnabled(int userHandle) { 939 synchronized (mPackagesLock) { 940 UserInfo info; 941 synchronized (mUsersLock) { 942 info = getUserInfoLU(userHandle); 943 } 944 if (info == null || !info.isManagedProfile()) { 945 return false; 946 } 947 return info.isQuietModeEnabled(); 948 } 949 } 950 951 /** 952 * Show confirm credential screen to unlock user in order to turn off quiet mode. 953 */ showConfirmCredentialToDisableQuietMode( @serIdInt int userHandle, @Nullable IntentSender target)954 private void showConfirmCredentialToDisableQuietMode( 955 @UserIdInt int userHandle, @Nullable IntentSender target) { 956 // otherwise, we show a profile challenge to trigger decryption of the user 957 final KeyguardManager km = (KeyguardManager) mContext.getSystemService( 958 Context.KEYGUARD_SERVICE); 959 // We should use userHandle not credentialOwnerUserId here, as even if it is unified 960 // lock, confirm screenlock page will know and show personal challenge, and unlock 961 // work profile when personal challenge is correct 962 final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, 963 userHandle); 964 if (unlockIntent == null) { 965 return; 966 } 967 final Intent callBackIntent = new Intent( 968 ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK); 969 if (target != null) { 970 callBackIntent.putExtra(Intent.EXTRA_INTENT, target); 971 } 972 callBackIntent.putExtra(Intent.EXTRA_USER_ID, userHandle); 973 callBackIntent.setPackage(mContext.getPackageName()); 974 callBackIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 975 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 976 mContext, 977 0, 978 callBackIntent, 979 PendingIntent.FLAG_CANCEL_CURRENT | 980 PendingIntent.FLAG_ONE_SHOT | 981 PendingIntent.FLAG_IMMUTABLE); 982 // After unlocking the challenge, it will disable quiet mode and run the original 983 // intentSender 984 unlockIntent.putExtra(Intent.EXTRA_INTENT, pendingIntent.getIntentSender()); 985 unlockIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 986 mContext.startActivity(unlockIntent); 987 } 988 989 @Override setUserEnabled(int userId)990 public void setUserEnabled(int userId) { 991 checkManageUsersPermission("enable user"); 992 synchronized (mPackagesLock) { 993 UserInfo info; 994 synchronized (mUsersLock) { 995 info = getUserInfoLU(userId); 996 } 997 if (info != null && !info.isEnabled()) { 998 info.flags ^= UserInfo.FLAG_DISABLED; 999 writeUserLP(getUserDataLU(info.id)); 1000 } 1001 } 1002 } 1003 1004 @Override setUserAdmin(int userId)1005 public void setUserAdmin(int userId) { 1006 checkManageUserAndAcrossUsersFullPermission("set user admin"); 1007 1008 synchronized (mPackagesLock) { 1009 UserInfo info; 1010 synchronized (mUsersLock) { 1011 info = getUserInfoLU(userId); 1012 } 1013 if (info == null || info.isAdmin()) { 1014 // Exit if no user found with that id, or the user is already an Admin. 1015 return; 1016 } 1017 1018 info.flags ^= UserInfo.FLAG_ADMIN; 1019 writeUserLP(getUserDataLU(info.id)); 1020 } 1021 1022 // Remove non-admin restrictions. 1023 // Keep synchronized with createUserEvenWhenDisallowed. 1024 setUserRestriction(UserManager.DISALLOW_SMS, false, userId); 1025 setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, userId); 1026 } 1027 1028 /** 1029 * Evicts a user's CE key by stopping and restarting the user. 1030 * 1031 * The key is evicted automatically by the user controller when the user has stopped. 1032 */ 1033 @Override evictCredentialEncryptionKey(@serIdInt int userId)1034 public void evictCredentialEncryptionKey(@UserIdInt int userId) { 1035 checkManageUsersPermission("evict CE key"); 1036 final IActivityManager am = ActivityManagerNative.getDefault(); 1037 final long identity = Binder.clearCallingIdentity(); 1038 try { 1039 am.restartUserInBackground(userId); 1040 } catch (RemoteException re) { 1041 throw re.rethrowAsRuntimeException(); 1042 } finally { 1043 Binder.restoreCallingIdentity(identity); 1044 } 1045 } 1046 1047 @Override getUserInfo(int userId)1048 public UserInfo getUserInfo(int userId) { 1049 checkManageOrCreateUsersPermission("query user"); 1050 synchronized (mUsersLock) { 1051 return userWithName(getUserInfoLU(userId)); 1052 } 1053 } 1054 1055 /** 1056 * Returns a UserInfo object with the name filled in, for Owner, or the original 1057 * if the name is already set. 1058 */ userWithName(UserInfo orig)1059 private UserInfo userWithName(UserInfo orig) { 1060 if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) { 1061 UserInfo withName = new UserInfo(orig); 1062 withName.name = getOwnerName(); 1063 return withName; 1064 } else { 1065 return orig; 1066 } 1067 } 1068 1069 @Override getManagedProfileBadge(@serIdInt int userId)1070 public int getManagedProfileBadge(@UserIdInt int userId) { 1071 int callingUserId = UserHandle.getCallingUserId(); 1072 if (callingUserId != userId && !hasManageUsersPermission()) { 1073 if (!isSameProfileGroupNoChecks(callingUserId, userId)) { 1074 throw new SecurityException( 1075 "You need MANAGE_USERS permission to: check if specified user a " + 1076 "managed profile outside your profile group"); 1077 } 1078 } 1079 synchronized (mUsersLock) { 1080 UserInfo userInfo = getUserInfoLU(userId); 1081 return userInfo != null ? userInfo.profileBadge : 0; 1082 } 1083 } 1084 1085 @Override isManagedProfile(int userId)1086 public boolean isManagedProfile(int userId) { 1087 int callingUserId = UserHandle.getCallingUserId(); 1088 if (callingUserId != userId && !hasManageUsersPermission()) { 1089 if (!isSameProfileGroupNoChecks(callingUserId, userId)) { 1090 throw new SecurityException( 1091 "You need MANAGE_USERS permission to: check if specified user a " + 1092 "managed profile outside your profile group"); 1093 } 1094 } 1095 synchronized (mUsersLock) { 1096 UserInfo userInfo = getUserInfoLU(userId); 1097 return userInfo != null && userInfo.isManagedProfile(); 1098 } 1099 } 1100 1101 @Override isUserUnlockingOrUnlocked(int userId)1102 public boolean isUserUnlockingOrUnlocked(int userId) { 1103 checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlockingOrUnlocked"); 1104 return mLocalService.isUserUnlockingOrUnlocked(userId); 1105 } 1106 1107 @Override isUserUnlocked(int userId)1108 public boolean isUserUnlocked(int userId) { 1109 checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlocked"); 1110 return mLocalService.isUserUnlocked(userId); 1111 } 1112 1113 @Override isUserRunning(int userId)1114 public boolean isUserRunning(int userId) { 1115 checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserRunning"); 1116 return mLocalService.isUserRunning(userId); 1117 } 1118 1119 @Override getUserStartRealtime()1120 public long getUserStartRealtime() { 1121 final int userId = UserHandle.getUserId(Binder.getCallingUid()); 1122 synchronized (mUsersLock) { 1123 final UserData user = getUserDataLU(userId); 1124 if (user != null) { 1125 return user.startRealtime; 1126 } 1127 return 0; 1128 } 1129 } 1130 1131 @Override getUserUnlockRealtime()1132 public long getUserUnlockRealtime() { 1133 synchronized (mUsersLock) { 1134 final UserData user = getUserDataLU(UserHandle.getUserId(Binder.getCallingUid())); 1135 if (user != null) { 1136 return user.unlockRealtime; 1137 } 1138 return 0; 1139 } 1140 } 1141 checkManageOrInteractPermIfCallerInOtherProfileGroup(int userId, String name)1142 private void checkManageOrInteractPermIfCallerInOtherProfileGroup(int userId, String name) { 1143 int callingUserId = UserHandle.getCallingUserId(); 1144 if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) || 1145 hasManageUsersPermission()) { 1146 return; 1147 } 1148 if (!hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, 1149 Binder.getCallingUid())) { 1150 throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS permission " 1151 + "to: check " + name); 1152 } 1153 } 1154 1155 @Override isDemoUser(int userId)1156 public boolean isDemoUser(int userId) { 1157 int callingUserId = UserHandle.getCallingUserId(); 1158 if (callingUserId != userId && !hasManageUsersPermission()) { 1159 throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId 1160 + " is a demo user"); 1161 } 1162 synchronized (mUsersLock) { 1163 UserInfo userInfo = getUserInfoLU(userId); 1164 return userInfo != null && userInfo.isDemo(); 1165 } 1166 } 1167 1168 @Override isRestricted()1169 public boolean isRestricted() { 1170 synchronized (mUsersLock) { 1171 return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted(); 1172 } 1173 } 1174 1175 @Override canHaveRestrictedProfile(int userId)1176 public boolean canHaveRestrictedProfile(int userId) { 1177 checkManageUsersPermission("canHaveRestrictedProfile"); 1178 synchronized (mUsersLock) { 1179 final UserInfo userInfo = getUserInfoLU(userId); 1180 if (userInfo == null || !userInfo.canHaveProfile()) { 1181 return false; 1182 } 1183 if (!userInfo.isAdmin()) { 1184 return false; 1185 } 1186 // restricted profile can be created if there is no DO set and the admin user has no PO; 1187 return !mIsDeviceManaged && !mIsUserManaged.get(userId); 1188 } 1189 } 1190 1191 @Override hasRestrictedProfiles()1192 public boolean hasRestrictedProfiles() { 1193 checkManageUsersPermission("hasRestrictedProfiles"); 1194 final int callingUserId = UserHandle.getCallingUserId(); 1195 synchronized (mUsersLock) { 1196 final int userSize = mUsers.size(); 1197 for (int i = 0; i < userSize; i++) { 1198 UserInfo profile = mUsers.valueAt(i).info; 1199 if (callingUserId != profile.id 1200 && profile.restrictedProfileParentId == callingUserId) { 1201 return true; 1202 } 1203 } 1204 return false; 1205 } 1206 } 1207 1208 /* 1209 * Should be locked on mUsers before calling this. 1210 */ getUserInfoLU(int userId)1211 private UserInfo getUserInfoLU(int userId) { 1212 final UserData userData = mUsers.get(userId); 1213 // If it is partial and not in the process of being removed, return as unknown user. 1214 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 1215 Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); 1216 return null; 1217 } 1218 return userData != null ? userData.info : null; 1219 } 1220 getUserDataLU(int userId)1221 private UserData getUserDataLU(int userId) { 1222 final UserData userData = mUsers.get(userId); 1223 // If it is partial and not in the process of being removed, return as unknown user. 1224 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 1225 return null; 1226 } 1227 return userData; 1228 } 1229 1230 /** 1231 * Obtains {@link #mUsersLock} and return UserInfo from mUsers. 1232 * <p>No permissions checking or any addition checks are made</p> 1233 */ getUserInfoNoChecks(int userId)1234 private UserInfo getUserInfoNoChecks(int userId) { 1235 synchronized (mUsersLock) { 1236 final UserData userData = mUsers.get(userId); 1237 return userData != null ? userData.info : null; 1238 } 1239 } 1240 1241 /** 1242 * Obtains {@link #mUsersLock} and return UserData from mUsers. 1243 * <p>No permissions checking or any addition checks are made</p> 1244 */ getUserDataNoChecks(int userId)1245 private UserData getUserDataNoChecks(int userId) { 1246 synchronized (mUsersLock) { 1247 return mUsers.get(userId); 1248 } 1249 } 1250 1251 /** Called by PackageManagerService */ exists(int userId)1252 public boolean exists(int userId) { 1253 return mLocalService.exists(userId); 1254 } 1255 1256 @Override setUserName(int userId, String name)1257 public void setUserName(int userId, String name) { 1258 checkManageUsersPermission("rename users"); 1259 boolean changed = false; 1260 synchronized (mPackagesLock) { 1261 UserData userData = getUserDataNoChecks(userId); 1262 if (userData == null || userData.info.partial) { 1263 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId); 1264 return; 1265 } 1266 if (name != null && !name.equals(userData.info.name)) { 1267 userData.info.name = name; 1268 writeUserLP(userData); 1269 changed = true; 1270 } 1271 } 1272 if (changed) { 1273 sendUserInfoChangedBroadcast(userId); 1274 } 1275 } 1276 1277 @Override setUserIcon(int userId, Bitmap bitmap)1278 public void setUserIcon(int userId, Bitmap bitmap) { 1279 checkManageUsersPermission("update users"); 1280 if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) { 1281 Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled."); 1282 return; 1283 } 1284 mLocalService.setUserIcon(userId, bitmap); 1285 } 1286 1287 1288 sendUserInfoChangedBroadcast(int userId)1289 private void sendUserInfoChangedBroadcast(int userId) { 1290 Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED); 1291 changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 1292 changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 1293 mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL); 1294 } 1295 1296 @Override getUserIcon(int targetUserId)1297 public ParcelFileDescriptor getUserIcon(int targetUserId) { 1298 String iconPath; 1299 synchronized (mPackagesLock) { 1300 UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId); 1301 if (targetUserInfo == null || targetUserInfo.partial) { 1302 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId); 1303 return null; 1304 } 1305 1306 final int callingUserId = UserHandle.getCallingUserId(); 1307 final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId; 1308 final int targetGroupId = targetUserInfo.profileGroupId; 1309 final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID 1310 && callingGroupId == targetGroupId); 1311 if ((callingUserId != targetUserId) && !sameGroup) { 1312 checkManageUsersPermission("get the icon of a user who is not related"); 1313 } 1314 1315 if (targetUserInfo.iconPath == null) { 1316 return null; 1317 } 1318 iconPath = targetUserInfo.iconPath; 1319 } 1320 1321 try { 1322 return ParcelFileDescriptor.open( 1323 new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY); 1324 } catch (FileNotFoundException e) { 1325 Log.e(LOG_TAG, "Couldn't find icon file", e); 1326 } 1327 return null; 1328 } 1329 makeInitialized(int userId)1330 public void makeInitialized(int userId) { 1331 checkManageUsersPermission("makeInitialized"); 1332 boolean scheduleWriteUser = false; 1333 UserData userData; 1334 synchronized (mUsersLock) { 1335 userData = mUsers.get(userId); 1336 if (userData == null || userData.info.partial) { 1337 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId); 1338 return; 1339 } 1340 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 1341 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 1342 scheduleWriteUser = true; 1343 } 1344 } 1345 if (scheduleWriteUser) { 1346 scheduleWriteUser(userData); 1347 } 1348 } 1349 1350 /** 1351 * If default guest restrictions haven't been initialized yet, add the basic 1352 * restrictions. 1353 */ initDefaultGuestRestrictions()1354 private void initDefaultGuestRestrictions() { 1355 synchronized (mGuestRestrictions) { 1356 if (mGuestRestrictions.isEmpty()) { 1357 mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true); 1358 mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); 1359 mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true); 1360 mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); 1361 } 1362 } 1363 } 1364 1365 @Override getDefaultGuestRestrictions()1366 public Bundle getDefaultGuestRestrictions() { 1367 checkManageUsersPermission("getDefaultGuestRestrictions"); 1368 synchronized (mGuestRestrictions) { 1369 return new Bundle(mGuestRestrictions); 1370 } 1371 } 1372 1373 @Override setDefaultGuestRestrictions(Bundle restrictions)1374 public void setDefaultGuestRestrictions(Bundle restrictions) { 1375 checkManageUsersPermission("setDefaultGuestRestrictions"); 1376 synchronized (mGuestRestrictions) { 1377 mGuestRestrictions.clear(); 1378 mGuestRestrictions.putAll(restrictions); 1379 } 1380 synchronized (mPackagesLock) { 1381 writeUserListLP(); 1382 } 1383 } 1384 1385 /** 1386 * See {@link UserManagerInternal#setDevicePolicyUserRestrictions} 1387 */ setDevicePolicyUserRestrictionsInner(int userId, @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope)1388 private void setDevicePolicyUserRestrictionsInner(int userId, @Nullable Bundle restrictions, 1389 boolean isDeviceOwner, int cameraRestrictionScope) { 1390 final Bundle global = new Bundle(); 1391 final Bundle local = new Bundle(); 1392 1393 // Sort restrictions into local and global ensuring they don't overlap. 1394 UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, isDeviceOwner, 1395 cameraRestrictionScope, global, local); 1396 1397 boolean globalChanged, localChanged; 1398 synchronized (mRestrictionsLock) { 1399 // Update global and local restrictions if they were changed. 1400 globalChanged = updateRestrictionsIfNeededLR( 1401 userId, global, mDevicePolicyGlobalUserRestrictions); 1402 localChanged = updateRestrictionsIfNeededLR( 1403 userId, local, mDevicePolicyLocalUserRestrictions); 1404 1405 if (isDeviceOwner) { 1406 // Remember the global restriction owner userId to be able to make a distinction 1407 // in getUserRestrictionSource on who set local policies. 1408 mDeviceOwnerUserId = userId; 1409 } else { 1410 if (mDeviceOwnerUserId == userId) { 1411 // When profile owner sets restrictions it passes null global bundle and we 1412 // reset global restriction owner userId. 1413 // This means this user used to have DO, but now the DO is gone and the user 1414 // instead has PO. 1415 mDeviceOwnerUserId = UserHandle.USER_NULL; 1416 } 1417 } 1418 } 1419 if (DBG) { 1420 Log.d(LOG_TAG, "setDevicePolicyUserRestrictions: userId=" + userId 1421 + " global=" + global + (globalChanged ? " (changed)" : "") 1422 + " local=" + local + (localChanged ? " (changed)" : "") 1423 ); 1424 } 1425 // Don't call them within the mRestrictionsLock. 1426 synchronized (mPackagesLock) { 1427 if (localChanged || globalChanged) { 1428 writeUserLP(getUserDataNoChecks(userId)); 1429 } 1430 } 1431 1432 synchronized (mRestrictionsLock) { 1433 if (globalChanged) { 1434 applyUserRestrictionsForAllUsersLR(); 1435 } else if (localChanged) { 1436 applyUserRestrictionsLR(userId); 1437 } 1438 } 1439 } 1440 1441 /** 1442 * Updates restriction bundle for a given user in a given restriction array. If new bundle is 1443 * empty, record is removed from the array. 1444 * @return whether restrictions bundle is different from the old one. 1445 */ updateRestrictionsIfNeededLR(int userId, @Nullable Bundle restrictions, SparseArray<Bundle> restrictionsArray)1446 private boolean updateRestrictionsIfNeededLR(int userId, @Nullable Bundle restrictions, 1447 SparseArray<Bundle> restrictionsArray) { 1448 final boolean changed = 1449 !UserRestrictionsUtils.areEqual(restrictionsArray.get(userId), restrictions); 1450 if (changed) { 1451 if (!UserRestrictionsUtils.isEmpty(restrictions)) { 1452 restrictionsArray.put(userId, restrictions); 1453 } else { 1454 restrictionsArray.delete(userId); 1455 } 1456 } 1457 return changed; 1458 } 1459 1460 @GuardedBy("mRestrictionsLock") computeEffectiveUserRestrictionsLR(int userId)1461 private Bundle computeEffectiveUserRestrictionsLR(int userId) { 1462 final Bundle baseRestrictions = 1463 UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId)); 1464 final Bundle global = UserRestrictionsUtils.mergeAll(mDevicePolicyGlobalUserRestrictions); 1465 final Bundle local = mDevicePolicyLocalUserRestrictions.get(userId); 1466 1467 if (UserRestrictionsUtils.isEmpty(global) && UserRestrictionsUtils.isEmpty(local)) { 1468 // Common case first. 1469 return baseRestrictions; 1470 } 1471 final Bundle effective = UserRestrictionsUtils.clone(baseRestrictions); 1472 UserRestrictionsUtils.merge(effective, global); 1473 UserRestrictionsUtils.merge(effective, local); 1474 1475 return effective; 1476 } 1477 1478 @GuardedBy("mRestrictionsLock") invalidateEffectiveUserRestrictionsLR(int userId)1479 private void invalidateEffectiveUserRestrictionsLR(int userId) { 1480 if (DBG) { 1481 Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId); 1482 } 1483 mCachedEffectiveUserRestrictions.remove(userId); 1484 } 1485 getEffectiveUserRestrictions(int userId)1486 private Bundle getEffectiveUserRestrictions(int userId) { 1487 synchronized (mRestrictionsLock) { 1488 Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId); 1489 if (restrictions == null) { 1490 restrictions = computeEffectiveUserRestrictionsLR(userId); 1491 mCachedEffectiveUserRestrictions.put(userId, restrictions); 1492 } 1493 return restrictions; 1494 } 1495 } 1496 1497 /** @return a specific user restriction that's in effect currently. */ 1498 @Override hasUserRestriction(String restrictionKey, int userId)1499 public boolean hasUserRestriction(String restrictionKey, int userId) { 1500 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1501 return false; 1502 } 1503 Bundle restrictions = getEffectiveUserRestrictions(userId); 1504 return restrictions != null && restrictions.getBoolean(restrictionKey); 1505 } 1506 1507 /** @return if any user has the given restriction. */ 1508 @Override hasUserRestrictionOnAnyUser(String restrictionKey)1509 public boolean hasUserRestrictionOnAnyUser(String restrictionKey) { 1510 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1511 return false; 1512 } 1513 final List<UserInfo> users = getUsers(/* excludeDying= */ true); 1514 for (int i = 0; i < users.size(); i++) { 1515 final int userId = users.get(i).id; 1516 Bundle restrictions = getEffectiveUserRestrictions(userId); 1517 if (restrictions != null && restrictions.getBoolean(restrictionKey)) { 1518 return true; 1519 } 1520 } 1521 return false; 1522 } 1523 1524 /** 1525 * @hide 1526 * 1527 * Returns who set a user restriction on a user. 1528 * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. 1529 * @param restrictionKey the string key representing the restriction 1530 * @param userId the id of the user for whom to retrieve the restrictions. 1531 * @return The source of user restriction. Any combination of 1532 * {@link UserManager#RESTRICTION_NOT_SET}, 1533 * {@link UserManager#RESTRICTION_SOURCE_SYSTEM}, 1534 * {@link UserManager#RESTRICTION_SOURCE_DEVICE_OWNER} 1535 * and {@link UserManager#RESTRICTION_SOURCE_PROFILE_OWNER} 1536 */ 1537 @Override getUserRestrictionSource(String restrictionKey, int userId)1538 public int getUserRestrictionSource(String restrictionKey, int userId) { 1539 List<EnforcingUser> enforcingUsers = getUserRestrictionSources(restrictionKey, userId); 1540 // Get "bitwise or" of restriction sources for all enforcing users. 1541 int result = UserManager.RESTRICTION_NOT_SET; 1542 for (int i = enforcingUsers.size() - 1; i >= 0; i--) { 1543 result |= enforcingUsers.get(i).getUserRestrictionSource(); 1544 } 1545 return result; 1546 } 1547 1548 @Override getUserRestrictionSources( String restrictionKey, @UserIdInt int userId)1549 public List<EnforcingUser> getUserRestrictionSources( 1550 String restrictionKey, @UserIdInt int userId) { 1551 checkManageUsersPermission("getUserRestrictionSource"); 1552 1553 // Shortcut for the most common case 1554 if (!hasUserRestriction(restrictionKey, userId)) { 1555 return Collections.emptyList(); 1556 } 1557 1558 final List<EnforcingUser> result = new ArrayList<>(); 1559 1560 // Check if it is base restriction. 1561 if (hasBaseUserRestriction(restrictionKey, userId)) { 1562 result.add(new EnforcingUser( 1563 UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM)); 1564 } 1565 1566 synchronized (mRestrictionsLock) { 1567 // Check if it is set by profile owner. 1568 Bundle profileOwnerRestrictions = mDevicePolicyLocalUserRestrictions.get(userId); 1569 if (UserRestrictionsUtils.contains(profileOwnerRestrictions, restrictionKey)) { 1570 result.add(getEnforcingUserLocked(userId)); 1571 } 1572 1573 // Iterate over all users who enforce global restrictions. 1574 for (int i = mDevicePolicyGlobalUserRestrictions.size() - 1; i >= 0; i--) { 1575 Bundle globalRestrictions = mDevicePolicyGlobalUserRestrictions.valueAt(i); 1576 int profileUserId = mDevicePolicyGlobalUserRestrictions.keyAt(i); 1577 if (UserRestrictionsUtils.contains(globalRestrictions, restrictionKey)) { 1578 result.add(getEnforcingUserLocked(profileUserId)); 1579 } 1580 } 1581 } 1582 return result; 1583 } 1584 1585 @GuardedBy("mRestrictionsLock") getEnforcingUserLocked(@serIdInt int userId)1586 private EnforcingUser getEnforcingUserLocked(@UserIdInt int userId) { 1587 int source = mDeviceOwnerUserId == userId ? UserManager.RESTRICTION_SOURCE_DEVICE_OWNER 1588 : UserManager.RESTRICTION_SOURCE_PROFILE_OWNER; 1589 return new EnforcingUser(userId, source); 1590 } 1591 1592 /** 1593 * @return UserRestrictions that are in effect currently. This always returns a new 1594 * {@link Bundle}. 1595 */ 1596 @Override getUserRestrictions(int userId)1597 public Bundle getUserRestrictions(int userId) { 1598 return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId)); 1599 } 1600 1601 @Override hasBaseUserRestriction(String restrictionKey, int userId)1602 public boolean hasBaseUserRestriction(String restrictionKey, int userId) { 1603 checkManageUsersPermission("hasBaseUserRestriction"); 1604 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1605 return false; 1606 } 1607 synchronized (mRestrictionsLock) { 1608 Bundle bundle = mBaseUserRestrictions.get(userId); 1609 return (bundle != null && bundle.getBoolean(restrictionKey, false)); 1610 } 1611 } 1612 1613 @Override setUserRestriction(String key, boolean value, int userId)1614 public void setUserRestriction(String key, boolean value, int userId) { 1615 checkManageUsersPermission("setUserRestriction"); 1616 if (!UserRestrictionsUtils.isValidRestriction(key)) { 1617 return; 1618 } 1619 synchronized (mRestrictionsLock) { 1620 // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create 1621 // a copy. 1622 final Bundle newRestrictions = UserRestrictionsUtils.clone( 1623 mBaseUserRestrictions.get(userId)); 1624 newRestrictions.putBoolean(key, value); 1625 1626 updateUserRestrictionsInternalLR(newRestrictions, userId); 1627 } 1628 } 1629 1630 /** 1631 * Optionally updating user restrictions, calculate the effective user restrictions and also 1632 * propagate to other services and system settings. 1633 * 1634 * @param newBaseRestrictions User restrictions to set. 1635 * If null, will not update user restrictions and only does the propagation. 1636 * @param userId target user ID. 1637 */ 1638 @GuardedBy("mRestrictionsLock") updateUserRestrictionsInternalLR( @ullable Bundle newBaseRestrictions, int userId)1639 private void updateUserRestrictionsInternalLR( 1640 @Nullable Bundle newBaseRestrictions, int userId) { 1641 final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull( 1642 mAppliedUserRestrictions.get(userId)); 1643 1644 // Update base restrictions. 1645 if (newBaseRestrictions != null) { 1646 // If newBaseRestrictions == the current one, it's probably a bug. 1647 final Bundle prevBaseRestrictions = mBaseUserRestrictions.get(userId); 1648 1649 Preconditions.checkState(prevBaseRestrictions != newBaseRestrictions); 1650 Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId) 1651 != newBaseRestrictions); 1652 1653 if (updateRestrictionsIfNeededLR(userId, newBaseRestrictions, mBaseUserRestrictions)) { 1654 scheduleWriteUser(getUserDataNoChecks(userId)); 1655 } 1656 } 1657 1658 final Bundle effective = computeEffectiveUserRestrictionsLR(userId); 1659 1660 mCachedEffectiveUserRestrictions.put(userId, effective); 1661 1662 // Apply the new restrictions. 1663 if (DBG) { 1664 debug("Applying user restrictions: userId=" + userId 1665 + " new=" + effective + " prev=" + prevAppliedRestrictions); 1666 } 1667 1668 if (mAppOpsService != null) { // We skip it until system-ready. 1669 mHandler.post(new Runnable() { 1670 @Override 1671 public void run() { 1672 try { 1673 mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId); 1674 } catch (RemoteException e) { 1675 Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions"); 1676 } 1677 } 1678 }); 1679 } 1680 1681 propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions); 1682 1683 mAppliedUserRestrictions.put(userId, new Bundle(effective)); 1684 } 1685 propagateUserRestrictionsLR(final int userId, Bundle newRestrictions, Bundle prevRestrictions)1686 private void propagateUserRestrictionsLR(final int userId, 1687 Bundle newRestrictions, Bundle prevRestrictions) { 1688 // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock 1689 // actually, but we still need some kind of synchronization otherwise we might end up 1690 // calling listeners out-of-order, thus "LR". 1691 1692 if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) { 1693 return; 1694 } 1695 1696 final Bundle newRestrictionsFinal = new Bundle(newRestrictions); 1697 final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions); 1698 1699 mHandler.post(new Runnable() { 1700 @Override 1701 public void run() { 1702 UserRestrictionsUtils.applyUserRestrictions( 1703 mContext, userId, newRestrictionsFinal, prevRestrictionsFinal); 1704 1705 final UserRestrictionsListener[] listeners; 1706 synchronized (mUserRestrictionsListeners) { 1707 listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()]; 1708 mUserRestrictionsListeners.toArray(listeners); 1709 } 1710 for (int i = 0; i < listeners.length; i++) { 1711 listeners[i].onUserRestrictionsChanged(userId, 1712 newRestrictionsFinal, prevRestrictionsFinal); 1713 } 1714 1715 final Intent broadcast = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) 1716 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 1717 mContext.sendBroadcastAsUser(broadcast, UserHandle.of(userId)); 1718 } 1719 }); 1720 } 1721 1722 // Package private for the inner class. applyUserRestrictionsLR(int userId)1723 void applyUserRestrictionsLR(int userId) { 1724 updateUserRestrictionsInternalLR(null, userId); 1725 } 1726 1727 @GuardedBy("mRestrictionsLock") 1728 // Package private for the inner class. applyUserRestrictionsForAllUsersLR()1729 void applyUserRestrictionsForAllUsersLR() { 1730 if (DBG) { 1731 debug("applyUserRestrictionsForAllUsersLR"); 1732 } 1733 // First, invalidate all cached values. 1734 mCachedEffectiveUserRestrictions.clear(); 1735 1736 // We don't want to call into ActivityManagerService while taking a lock, so we'll call 1737 // it on a handler. 1738 final Runnable r = new Runnable() { 1739 @Override 1740 public void run() { 1741 // Then get the list of running users. 1742 final int[] runningUsers; 1743 try { 1744 runningUsers = ActivityManager.getService().getRunningUserIds(); 1745 } catch (RemoteException e) { 1746 Log.w(LOG_TAG, "Unable to access ActivityManagerService"); 1747 return; 1748 } 1749 // Then re-calculate the effective restrictions and apply, only for running users. 1750 // It's okay if a new user has started after the getRunningUserIds() call, 1751 // because we'll do the same thing (re-calculate the restrictions and apply) 1752 // when we start a user. 1753 synchronized (mRestrictionsLock) { 1754 for (int i = 0; i < runningUsers.length; i++) { 1755 applyUserRestrictionsLR(runningUsers[i]); 1756 } 1757 } 1758 } 1759 }; 1760 mHandler.post(r); 1761 } 1762 1763 /** 1764 * Check if we've hit the limit of how many users can be created. 1765 */ isUserLimitReached()1766 private boolean isUserLimitReached() { 1767 int count; 1768 synchronized (mUsersLock) { 1769 count = getAliveUsersExcludingGuestsCountLU(); 1770 } 1771 return count >= UserManager.getMaxSupportedUsers(); 1772 } 1773 1774 @Override canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne)1775 public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) { 1776 checkManageUsersPermission("check if more managed profiles can be added."); 1777 if (ActivityManager.isLowRamDeviceStatic()) { 1778 return false; 1779 } 1780 if (!mContext.getPackageManager().hasSystemFeature( 1781 PackageManager.FEATURE_MANAGED_USERS)) { 1782 return false; 1783 } 1784 // Limit number of managed profiles that can be created 1785 final int managedProfilesCount = getProfiles(userId, false).size() - 1; 1786 final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0; 1787 if (managedProfilesCount - profilesRemovedCount >= getMaxManagedProfiles()) { 1788 return false; 1789 } 1790 synchronized(mUsersLock) { 1791 UserInfo userInfo = getUserInfoLU(userId); 1792 if (userInfo == null || !userInfo.canHaveProfile()) { 1793 return false; 1794 } 1795 int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU() 1796 - profilesRemovedCount; 1797 // We allow creating a managed profile in the special case where there is only one user. 1798 return usersCountAfterRemoving == 1 1799 || usersCountAfterRemoving < UserManager.getMaxSupportedUsers(); 1800 } 1801 } 1802 getAliveUsersExcludingGuestsCountLU()1803 private int getAliveUsersExcludingGuestsCountLU() { 1804 int aliveUserCount = 0; 1805 final int totalUserCount = mUsers.size(); 1806 // Skip over users being removed 1807 for (int i = 0; i < totalUserCount; i++) { 1808 UserInfo user = mUsers.valueAt(i).info; 1809 if (!mRemovingUserIds.get(user.id) && !user.isGuest()) { 1810 aliveUserCount++; 1811 } 1812 } 1813 return aliveUserCount; 1814 } 1815 1816 /** 1817 * Enforces that only the system UID or root's UID or apps that have the 1818 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and 1819 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL} 1820 * permissions can make certain calls to the UserManager. 1821 * 1822 * @param message used as message if SecurityException is thrown 1823 * @throws SecurityException if the caller does not have enough privilege. 1824 */ checkManageUserAndAcrossUsersFullPermission(String message)1825 private static final void checkManageUserAndAcrossUsersFullPermission(String message) { 1826 final int uid = Binder.getCallingUid(); 1827 1828 if (uid == Process.SYSTEM_UID || uid == 0) { 1829 // System UID or root's UID are granted privilege. 1830 return; 1831 } 1832 1833 if (hasPermissionGranted(Manifest.permission.MANAGE_USERS, uid) 1834 && hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)) { 1835 // Apps with both permissions are granted privilege. 1836 return; 1837 } 1838 1839 throw new SecurityException( 1840 "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " + message); 1841 } 1842 hasPermissionGranted(String permission, int uid)1843 private static boolean hasPermissionGranted(String permission, int uid) { 1844 return ActivityManager.checkComponentPermission( 1845 permission, uid, /* owningUid = */-1, /* exported = */ true) == 1846 PackageManager.PERMISSION_GRANTED; 1847 } 1848 1849 /** 1850 * Enforces that only the system UID or root's UID or apps that have the 1851 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} 1852 * permission can make certain calls to the UserManager. 1853 * 1854 * @param message used as message if SecurityException is thrown 1855 * @throws SecurityException if the caller is not system or root 1856 * @see #hasManageUsersPermission() 1857 */ checkManageUsersPermission(String message)1858 private static final void checkManageUsersPermission(String message) { 1859 if (!hasManageUsersPermission()) { 1860 throw new SecurityException("You need MANAGE_USERS permission to: " + message); 1861 } 1862 } 1863 1864 /** 1865 * Enforces that only the system UID or root's UID or apps that have the 1866 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or 1867 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} 1868 * can make certain calls to the UserManager. 1869 * 1870 * @param message used as message if SecurityException is thrown 1871 * @throws SecurityException if the caller is not system or root 1872 * @see #hasManageOrCreateUsersPermission() 1873 */ checkManageOrCreateUsersPermission(String message)1874 private static final void checkManageOrCreateUsersPermission(String message) { 1875 if (!hasManageOrCreateUsersPermission()) { 1876 throw new SecurityException( 1877 "You either need MANAGE_USERS or CREATE_USERS permission to: " + message); 1878 } 1879 } 1880 1881 /** 1882 * Similar to {@link #checkManageOrCreateUsersPermission(String)} but when the caller is tries 1883 * to create user/profiles other than what is allowed for 1884 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} permission, then it will only 1885 * allow callers with {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} permission. 1886 */ checkManageOrCreateUsersPermission(int creationFlags)1887 private static final void checkManageOrCreateUsersPermission(int creationFlags) { 1888 if ((creationFlags & ~ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION) == 0) { 1889 if (!hasManageOrCreateUsersPermission()) { 1890 throw new SecurityException("You either need MANAGE_USERS or CREATE_USERS " 1891 + "permission to create an user with flags: " + creationFlags); 1892 } 1893 } else if (!hasManageUsersPermission()) { 1894 throw new SecurityException("You need MANAGE_USERS permission to create an user " 1895 + " with flags: " + creationFlags); 1896 } 1897 } 1898 1899 /** 1900 * @return whether the calling UID is system UID or root's UID or the calling app has the 1901 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}. 1902 */ hasManageUsersPermission()1903 private static final boolean hasManageUsersPermission() { 1904 final int callingUid = Binder.getCallingUid(); 1905 return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) 1906 || callingUid == Process.ROOT_UID 1907 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid); 1908 } 1909 1910 /** 1911 * @return whether the calling UID is system UID or root's UID or the calling app has the 1912 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or 1913 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}. 1914 */ hasManageOrCreateUsersPermission()1915 private static final boolean hasManageOrCreateUsersPermission() { 1916 final int callingUid = Binder.getCallingUid(); 1917 return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) 1918 || callingUid == Process.ROOT_UID 1919 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid) 1920 || hasPermissionGranted(android.Manifest.permission.CREATE_USERS, callingUid); 1921 } 1922 1923 /** 1924 * Enforces that only the system UID or root's UID (on any user) can make certain calls to the 1925 * UserManager. 1926 * 1927 * @param message used as message if SecurityException is thrown 1928 * @throws SecurityException if the caller is not system or root 1929 */ checkSystemOrRoot(String message)1930 private static void checkSystemOrRoot(String message) { 1931 final int uid = Binder.getCallingUid(); 1932 if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) { 1933 throw new SecurityException("Only system may: " + message); 1934 } 1935 } 1936 writeBitmapLP(UserInfo info, Bitmap bitmap)1937 private void writeBitmapLP(UserInfo info, Bitmap bitmap) { 1938 try { 1939 File dir = new File(mUsersDir, Integer.toString(info.id)); 1940 File file = new File(dir, USER_PHOTO_FILENAME); 1941 File tmp = new File(dir, USER_PHOTO_FILENAME_TMP); 1942 if (!dir.exists()) { 1943 dir.mkdir(); 1944 FileUtils.setPermissions( 1945 dir.getPath(), 1946 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1947 -1, -1); 1948 } 1949 FileOutputStream os; 1950 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp)) 1951 && tmp.renameTo(file) && SELinux.restorecon(file)) { 1952 info.iconPath = file.getAbsolutePath(); 1953 } 1954 try { 1955 os.close(); 1956 } catch (IOException ioe) { 1957 // What the ... ! 1958 } 1959 tmp.delete(); 1960 } catch (FileNotFoundException e) { 1961 Slog.w(LOG_TAG, "Error setting photo for user ", e); 1962 } 1963 } 1964 1965 /** 1966 * Returns an array of user ids. This array is cached here for quick access, so do not modify or 1967 * cache it elsewhere. 1968 * @return the array of user ids. 1969 */ getUserIds()1970 public int[] getUserIds() { 1971 synchronized (mUsersLock) { 1972 return mUserIds; 1973 } 1974 } 1975 readUserListLP()1976 private void readUserListLP() { 1977 if (!mUserListFile.exists()) { 1978 fallbackToSingleUserLP(); 1979 return; 1980 } 1981 FileInputStream fis = null; 1982 AtomicFile userListFile = new AtomicFile(mUserListFile); 1983 try { 1984 fis = userListFile.openRead(); 1985 XmlPullParser parser = Xml.newPullParser(); 1986 parser.setInput(fis, StandardCharsets.UTF_8.name()); 1987 int type; 1988 while ((type = parser.next()) != XmlPullParser.START_TAG 1989 && type != XmlPullParser.END_DOCUMENT) { 1990 // Skip 1991 } 1992 1993 if (type != XmlPullParser.START_TAG) { 1994 Slog.e(LOG_TAG, "Unable to read user list"); 1995 fallbackToSingleUserLP(); 1996 return; 1997 } 1998 1999 mNextSerialNumber = -1; 2000 if (parser.getName().equals(TAG_USERS)) { 2001 String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO); 2002 if (lastSerialNumber != null) { 2003 mNextSerialNumber = Integer.parseInt(lastSerialNumber); 2004 } 2005 String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION); 2006 if (versionNumber != null) { 2007 mUserVersion = Integer.parseInt(versionNumber); 2008 } 2009 } 2010 2011 // Pre-O global user restriction were stored as a single bundle (as opposed to per-user 2012 // currently), take care of it in case of upgrade. 2013 Bundle oldDevicePolicyGlobalUserRestrictions = null; 2014 2015 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 2016 if (type == XmlPullParser.START_TAG) { 2017 final String name = parser.getName(); 2018 if (name.equals(TAG_USER)) { 2019 String id = parser.getAttributeValue(null, ATTR_ID); 2020 2021 UserData userData = readUserLP(Integer.parseInt(id)); 2022 2023 if (userData != null) { 2024 synchronized (mUsersLock) { 2025 mUsers.put(userData.info.id, userData); 2026 if (mNextSerialNumber < 0 2027 || mNextSerialNumber <= userData.info.id) { 2028 mNextSerialNumber = userData.info.id + 1; 2029 } 2030 } 2031 } 2032 } else if (name.equals(TAG_GUEST_RESTRICTIONS)) { 2033 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2034 && type != XmlPullParser.END_TAG) { 2035 if (type == XmlPullParser.START_TAG) { 2036 if (parser.getName().equals(TAG_RESTRICTIONS)) { 2037 synchronized (mGuestRestrictions) { 2038 UserRestrictionsUtils 2039 .readRestrictions(parser, mGuestRestrictions); 2040 } 2041 } 2042 break; 2043 } 2044 } 2045 } else if (name.equals(TAG_DEVICE_OWNER_USER_ID) 2046 // Legacy name, should only be encountered when upgrading from pre-O. 2047 || name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) { 2048 String ownerUserId = parser.getAttributeValue(null, ATTR_ID); 2049 if (ownerUserId != null) { 2050 mDeviceOwnerUserId = Integer.parseInt(ownerUserId); 2051 } 2052 } else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) { 2053 // Should only happen when upgrading from pre-O (version < 7). 2054 oldDevicePolicyGlobalUserRestrictions = 2055 UserRestrictionsUtils.readRestrictions(parser); 2056 } 2057 } 2058 } 2059 2060 updateUserIds(); 2061 upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions); 2062 } catch (IOException | XmlPullParserException e) { 2063 fallbackToSingleUserLP(); 2064 } finally { 2065 IoUtils.closeQuietly(fis); 2066 } 2067 } 2068 2069 /** 2070 * Upgrade steps between versions, either for fixing bugs or changing the data format. 2071 * @param oldGlobalUserRestrictions Pre-O global device policy restrictions. 2072 */ upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions)2073 private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) { 2074 final int originalVersion = mUserVersion; 2075 int userVersion = mUserVersion; 2076 if (userVersion < 1) { 2077 // Assign a proper name for the owner, if not initialized correctly before 2078 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 2079 if ("Primary".equals(userData.info.name)) { 2080 userData.info.name = 2081 mContext.getResources().getString(com.android.internal.R.string.owner_name); 2082 scheduleWriteUser(userData); 2083 } 2084 userVersion = 1; 2085 } 2086 2087 if (userVersion < 2) { 2088 // Owner should be marked as initialized 2089 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 2090 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 2091 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 2092 scheduleWriteUser(userData); 2093 } 2094 userVersion = 2; 2095 } 2096 2097 2098 if (userVersion < 4) { 2099 userVersion = 4; 2100 } 2101 2102 if (userVersion < 5) { 2103 initDefaultGuestRestrictions(); 2104 userVersion = 5; 2105 } 2106 2107 if (userVersion < 6) { 2108 final boolean splitSystemUser = UserManager.isSplitSystemUser(); 2109 synchronized (mUsersLock) { 2110 for (int i = 0; i < mUsers.size(); i++) { 2111 UserData userData = mUsers.valueAt(i); 2112 // In non-split mode, only user 0 can have restricted profiles 2113 if (!splitSystemUser && userData.info.isRestricted() 2114 && (userData.info.restrictedProfileParentId 2115 == UserInfo.NO_PROFILE_GROUP_ID)) { 2116 userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM; 2117 scheduleWriteUser(userData); 2118 } 2119 } 2120 } 2121 userVersion = 6; 2122 } 2123 2124 if (userVersion < 7) { 2125 // Previously only one user could enforce global restrictions, now it is per-user. 2126 synchronized (mRestrictionsLock) { 2127 if (!UserRestrictionsUtils.isEmpty(oldGlobalUserRestrictions) 2128 && mDeviceOwnerUserId != UserHandle.USER_NULL) { 2129 mDevicePolicyGlobalUserRestrictions.put( 2130 mDeviceOwnerUserId, oldGlobalUserRestrictions); 2131 } 2132 // ENSURE_VERIFY_APPS is now enforced globally even if put by profile owner, so move 2133 // it from local to global bundle for all users who set it. 2134 UserRestrictionsUtils.moveRestriction(UserManager.ENSURE_VERIFY_APPS, 2135 mDevicePolicyLocalUserRestrictions, mDevicePolicyGlobalUserRestrictions 2136 ); 2137 } 2138 userVersion = 7; 2139 } 2140 2141 if (userVersion < USER_VERSION) { 2142 Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to " 2143 + USER_VERSION); 2144 } else { 2145 mUserVersion = userVersion; 2146 2147 if (originalVersion < mUserVersion) { 2148 writeUserListLP(); 2149 } 2150 } 2151 } 2152 fallbackToSingleUserLP()2153 private void fallbackToSingleUserLP() { 2154 int flags = UserInfo.FLAG_INITIALIZED; 2155 // In split system user mode, the admin and primary flags are assigned to the first human 2156 // user. 2157 if (!UserManager.isSplitSystemUser()) { 2158 flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY; 2159 } 2160 // Create the system user 2161 UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags); 2162 UserData userData = putUserInfo(system); 2163 mNextSerialNumber = MIN_USER_ID; 2164 mUserVersion = USER_VERSION; 2165 2166 Bundle restrictions = new Bundle(); 2167 try { 2168 final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray( 2169 com.android.internal.R.array.config_defaultFirstUserRestrictions); 2170 for (String userRestriction : defaultFirstUserRestrictions) { 2171 if (UserRestrictionsUtils.isValidRestriction(userRestriction)) { 2172 restrictions.putBoolean(userRestriction, true); 2173 } 2174 } 2175 } catch (Resources.NotFoundException e) { 2176 Log.e(LOG_TAG, "Couldn't find resource: config_defaultFirstUserRestrictions", e); 2177 } 2178 2179 if (!restrictions.isEmpty()) { 2180 synchronized (mRestrictionsLock) { 2181 mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions); 2182 } 2183 } 2184 2185 updateUserIds(); 2186 initDefaultGuestRestrictions(); 2187 2188 writeUserLP(userData); 2189 writeUserListLP(); 2190 } 2191 getOwnerName()2192 private String getOwnerName() { 2193 return mContext.getResources().getString(com.android.internal.R.string.owner_name); 2194 } 2195 scheduleWriteUser(UserData UserData)2196 private void scheduleWriteUser(UserData UserData) { 2197 if (DBG) { 2198 debug("scheduleWriteUser"); 2199 } 2200 // No need to wrap it within a lock -- worst case, we'll just post the same message 2201 // twice. 2202 if (!mHandler.hasMessages(WRITE_USER_MSG, UserData)) { 2203 Message msg = mHandler.obtainMessage(WRITE_USER_MSG, UserData); 2204 mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); 2205 } 2206 } 2207 writeUserLP(UserData userData)2208 private void writeUserLP(UserData userData) { 2209 if (DBG) { 2210 debug("writeUserLP " + userData); 2211 } 2212 FileOutputStream fos = null; 2213 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX)); 2214 try { 2215 fos = userFile.startWrite(); 2216 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2217 writeUserLP(userData, bos); 2218 userFile.finishWrite(fos); 2219 } catch (Exception ioe) { 2220 Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe); 2221 userFile.failWrite(fos); 2222 } 2223 } 2224 2225 /* 2226 * Writes the user file in this format: 2227 * 2228 * <user flags="20039023" id="0"> 2229 * <name>Primary</name> 2230 * </user> 2231 */ 2232 @VisibleForTesting writeUserLP(UserData userData, OutputStream os)2233 void writeUserLP(UserData userData, OutputStream os) 2234 throws IOException, XmlPullParserException { 2235 // XmlSerializer serializer = XmlUtils.serializerInstance(); 2236 final XmlSerializer serializer = new FastXmlSerializer(); 2237 serializer.setOutput(os, StandardCharsets.UTF_8.name()); 2238 serializer.startDocument(null, true); 2239 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2240 2241 final UserInfo userInfo = userData.info; 2242 serializer.startTag(null, TAG_USER); 2243 serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); 2244 serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber)); 2245 serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); 2246 serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime)); 2247 serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME, 2248 Long.toString(userInfo.lastLoggedInTime)); 2249 if (userInfo.lastLoggedInFingerprint != null) { 2250 serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT, 2251 userInfo.lastLoggedInFingerprint); 2252 } 2253 if (userInfo.iconPath != null) { 2254 serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); 2255 } 2256 if (userInfo.partial) { 2257 serializer.attribute(null, ATTR_PARTIAL, "true"); 2258 } 2259 if (userInfo.guestToRemove) { 2260 serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true"); 2261 } 2262 if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 2263 serializer.attribute(null, ATTR_PROFILE_GROUP_ID, 2264 Integer.toString(userInfo.profileGroupId)); 2265 } 2266 serializer.attribute(null, ATTR_PROFILE_BADGE, 2267 Integer.toString(userInfo.profileBadge)); 2268 if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) { 2269 serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID, 2270 Integer.toString(userInfo.restrictedProfileParentId)); 2271 } 2272 // Write seed data 2273 if (userData.persistSeedData) { 2274 if (userData.seedAccountName != null) { 2275 serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName); 2276 } 2277 if (userData.seedAccountType != null) { 2278 serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType); 2279 } 2280 } 2281 if (userInfo.name != null) { 2282 serializer.startTag(null, TAG_NAME); 2283 serializer.text(userInfo.name); 2284 serializer.endTag(null, TAG_NAME); 2285 } 2286 synchronized (mRestrictionsLock) { 2287 UserRestrictionsUtils.writeRestrictions(serializer, 2288 mBaseUserRestrictions.get(userInfo.id), TAG_RESTRICTIONS); 2289 UserRestrictionsUtils.writeRestrictions(serializer, 2290 mDevicePolicyLocalUserRestrictions.get(userInfo.id), 2291 TAG_DEVICE_POLICY_RESTRICTIONS); 2292 UserRestrictionsUtils.writeRestrictions(serializer, 2293 mDevicePolicyGlobalUserRestrictions.get(userInfo.id), 2294 TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS); 2295 } 2296 2297 if (userData.account != null) { 2298 serializer.startTag(null, TAG_ACCOUNT); 2299 serializer.text(userData.account); 2300 serializer.endTag(null, TAG_ACCOUNT); 2301 } 2302 2303 if (userData.persistSeedData && userData.seedAccountOptions != null) { 2304 serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS); 2305 userData.seedAccountOptions.saveToXml(serializer); 2306 serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS); 2307 } 2308 2309 serializer.endTag(null, TAG_USER); 2310 2311 serializer.endDocument(); 2312 } 2313 2314 /* 2315 * Writes the user list file in this format: 2316 * 2317 * <users nextSerialNumber="3"> 2318 * <user id="0"></user> 2319 * <user id="2"></user> 2320 * </users> 2321 */ writeUserListLP()2322 private void writeUserListLP() { 2323 if (DBG) { 2324 debug("writeUserList"); 2325 } 2326 FileOutputStream fos = null; 2327 AtomicFile userListFile = new AtomicFile(mUserListFile); 2328 try { 2329 fos = userListFile.startWrite(); 2330 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2331 2332 // XmlSerializer serializer = XmlUtils.serializerInstance(); 2333 final XmlSerializer serializer = new FastXmlSerializer(); 2334 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 2335 serializer.startDocument(null, true); 2336 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2337 2338 serializer.startTag(null, TAG_USERS); 2339 serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber)); 2340 serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); 2341 2342 serializer.startTag(null, TAG_GUEST_RESTRICTIONS); 2343 synchronized (mGuestRestrictions) { 2344 UserRestrictionsUtils 2345 .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS); 2346 } 2347 serializer.endTag(null, TAG_GUEST_RESTRICTIONS); 2348 serializer.startTag(null, TAG_DEVICE_OWNER_USER_ID); 2349 serializer.attribute(null, ATTR_ID, Integer.toString(mDeviceOwnerUserId)); 2350 serializer.endTag(null, TAG_DEVICE_OWNER_USER_ID); 2351 int[] userIdsToWrite; 2352 synchronized (mUsersLock) { 2353 userIdsToWrite = new int[mUsers.size()]; 2354 for (int i = 0; i < userIdsToWrite.length; i++) { 2355 UserInfo user = mUsers.valueAt(i).info; 2356 userIdsToWrite[i] = user.id; 2357 } 2358 } 2359 for (int id : userIdsToWrite) { 2360 serializer.startTag(null, TAG_USER); 2361 serializer.attribute(null, ATTR_ID, Integer.toString(id)); 2362 serializer.endTag(null, TAG_USER); 2363 } 2364 2365 serializer.endTag(null, TAG_USERS); 2366 2367 serializer.endDocument(); 2368 userListFile.finishWrite(fos); 2369 } catch (Exception e) { 2370 userListFile.failWrite(fos); 2371 Slog.e(LOG_TAG, "Error writing user list"); 2372 } 2373 } 2374 readUserLP(int id)2375 private UserData readUserLP(int id) { 2376 FileInputStream fis = null; 2377 try { 2378 AtomicFile userFile = 2379 new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX)); 2380 fis = userFile.openRead(); 2381 return readUserLP(id, fis); 2382 } catch (IOException ioe) { 2383 Slog.e(LOG_TAG, "Error reading user list"); 2384 } catch (XmlPullParserException pe) { 2385 Slog.e(LOG_TAG, "Error reading user list"); 2386 } finally { 2387 IoUtils.closeQuietly(fis); 2388 } 2389 return null; 2390 } 2391 2392 @VisibleForTesting readUserLP(int id, InputStream is)2393 UserData readUserLP(int id, InputStream is) throws IOException, 2394 XmlPullParserException { 2395 int flags = 0; 2396 int serialNumber = id; 2397 String name = null; 2398 String account = null; 2399 String iconPath = null; 2400 long creationTime = 0L; 2401 long lastLoggedInTime = 0L; 2402 String lastLoggedInFingerprint = null; 2403 int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; 2404 int profileBadge = 0; 2405 int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID; 2406 boolean partial = false; 2407 boolean guestToRemove = false; 2408 boolean persistSeedData = false; 2409 String seedAccountName = null; 2410 String seedAccountType = null; 2411 PersistableBundle seedAccountOptions = null; 2412 Bundle baseRestrictions = null; 2413 Bundle localRestrictions = null; 2414 Bundle globalRestrictions = null; 2415 2416 XmlPullParser parser = Xml.newPullParser(); 2417 parser.setInput(is, StandardCharsets.UTF_8.name()); 2418 int type; 2419 while ((type = parser.next()) != XmlPullParser.START_TAG 2420 && type != XmlPullParser.END_DOCUMENT) { 2421 // Skip 2422 } 2423 2424 if (type != XmlPullParser.START_TAG) { 2425 Slog.e(LOG_TAG, "Unable to read user " + id); 2426 return null; 2427 } 2428 2429 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) { 2430 int storedId = readIntAttribute(parser, ATTR_ID, -1); 2431 if (storedId != id) { 2432 Slog.e(LOG_TAG, "User id does not match the file name"); 2433 return null; 2434 } 2435 serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id); 2436 flags = readIntAttribute(parser, ATTR_FLAGS, 0); 2437 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); 2438 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0); 2439 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0); 2440 lastLoggedInFingerprint = parser.getAttributeValue(null, 2441 ATTR_LAST_LOGGED_IN_FINGERPRINT); 2442 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID, 2443 UserInfo.NO_PROFILE_GROUP_ID); 2444 profileBadge = readIntAttribute(parser, ATTR_PROFILE_BADGE, 0); 2445 restrictedProfileParentId = readIntAttribute(parser, 2446 ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID); 2447 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); 2448 if ("true".equals(valueString)) { 2449 partial = true; 2450 } 2451 valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE); 2452 if ("true".equals(valueString)) { 2453 guestToRemove = true; 2454 } 2455 2456 seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME); 2457 seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE); 2458 if (seedAccountName != null || seedAccountType != null) { 2459 persistSeedData = true; 2460 } 2461 2462 int outerDepth = parser.getDepth(); 2463 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2464 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2465 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2466 continue; 2467 } 2468 String tag = parser.getName(); 2469 if (TAG_NAME.equals(tag)) { 2470 type = parser.next(); 2471 if (type == XmlPullParser.TEXT) { 2472 name = parser.getText(); 2473 } 2474 } else if (TAG_RESTRICTIONS.equals(tag)) { 2475 baseRestrictions = UserRestrictionsUtils.readRestrictions(parser); 2476 } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) { 2477 localRestrictions = UserRestrictionsUtils.readRestrictions(parser); 2478 } else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) { 2479 globalRestrictions = UserRestrictionsUtils.readRestrictions(parser); 2480 } else if (TAG_ACCOUNT.equals(tag)) { 2481 type = parser.next(); 2482 if (type == XmlPullParser.TEXT) { 2483 account = parser.getText(); 2484 } 2485 } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) { 2486 seedAccountOptions = PersistableBundle.restoreFromXml(parser); 2487 persistSeedData = true; 2488 } 2489 } 2490 } 2491 2492 // Create the UserInfo object that gets passed around 2493 UserInfo userInfo = new UserInfo(id, name, iconPath, flags); 2494 userInfo.serialNumber = serialNumber; 2495 userInfo.creationTime = creationTime; 2496 userInfo.lastLoggedInTime = lastLoggedInTime; 2497 userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint; 2498 userInfo.partial = partial; 2499 userInfo.guestToRemove = guestToRemove; 2500 userInfo.profileGroupId = profileGroupId; 2501 userInfo.profileBadge = profileBadge; 2502 userInfo.restrictedProfileParentId = restrictedProfileParentId; 2503 2504 // Create the UserData object that's internal to this class 2505 UserData userData = new UserData(); 2506 userData.info = userInfo; 2507 userData.account = account; 2508 userData.seedAccountName = seedAccountName; 2509 userData.seedAccountType = seedAccountType; 2510 userData.persistSeedData = persistSeedData; 2511 userData.seedAccountOptions = seedAccountOptions; 2512 2513 synchronized (mRestrictionsLock) { 2514 if (baseRestrictions != null) { 2515 mBaseUserRestrictions.put(id, baseRestrictions); 2516 } 2517 if (localRestrictions != null) { 2518 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions); 2519 } 2520 if (globalRestrictions != null) { 2521 mDevicePolicyGlobalUserRestrictions.put(id, globalRestrictions); 2522 } 2523 } 2524 return userData; 2525 } 2526 readIntAttribute(XmlPullParser parser, String attr, int defaultValue)2527 private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) { 2528 String valueString = parser.getAttributeValue(null, attr); 2529 if (valueString == null) return defaultValue; 2530 try { 2531 return Integer.parseInt(valueString); 2532 } catch (NumberFormatException nfe) { 2533 return defaultValue; 2534 } 2535 } 2536 readLongAttribute(XmlPullParser parser, String attr, long defaultValue)2537 private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) { 2538 String valueString = parser.getAttributeValue(null, attr); 2539 if (valueString == null) return defaultValue; 2540 try { 2541 return Long.parseLong(valueString); 2542 } catch (NumberFormatException nfe) { 2543 return defaultValue; 2544 } 2545 } 2546 2547 /** 2548 * Removes the app restrictions file for a specific package and user id, if it exists. 2549 */ cleanAppRestrictionsForPackageLAr(String pkg, int userId)2550 private static void cleanAppRestrictionsForPackageLAr(String pkg, int userId) { 2551 File dir = Environment.getUserSystemDirectory(userId); 2552 File resFile = new File(dir, packageToRestrictionsFileName(pkg)); 2553 if (resFile.exists()) { 2554 resFile.delete(); 2555 } 2556 } 2557 2558 @Override createProfileForUser(String name, int flags, int userId, String[] disallowedPackages)2559 public UserInfo createProfileForUser(String name, int flags, int userId, 2560 String[] disallowedPackages) { 2561 checkManageOrCreateUsersPermission(flags); 2562 return createUserInternal(name, flags, userId, disallowedPackages); 2563 } 2564 2565 @Override createProfileForUserEvenWhenDisallowed(String name, int flags, int userId, String[] disallowedPackages)2566 public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags, int userId, 2567 String[] disallowedPackages) { 2568 checkManageOrCreateUsersPermission(flags); 2569 return createUserInternalUnchecked(name, flags, userId, disallowedPackages); 2570 } 2571 2572 @Override removeUserEvenWhenDisallowed(@serIdInt int userHandle)2573 public boolean removeUserEvenWhenDisallowed(@UserIdInt int userHandle) { 2574 checkManageOrCreateUsersPermission("Only the system can remove users"); 2575 return removeUserUnchecked(userHandle); 2576 } 2577 2578 @Override createUser(String name, int flags)2579 public UserInfo createUser(String name, int flags) { 2580 checkManageOrCreateUsersPermission(flags); 2581 return createUserInternal(name, flags, UserHandle.USER_NULL); 2582 } 2583 createUserInternal(String name, int flags, int parentId)2584 private UserInfo createUserInternal(String name, int flags, int parentId) { 2585 return createUserInternal(name, flags, parentId, null); 2586 } 2587 createUserInternal(String name, int flags, int parentId, String[] disallowedPackages)2588 private UserInfo createUserInternal(String name, int flags, int parentId, 2589 String[] disallowedPackages) { 2590 String restriction = ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0) 2591 ? UserManager.DISALLOW_ADD_MANAGED_PROFILE 2592 : UserManager.DISALLOW_ADD_USER; 2593 if (hasUserRestriction(restriction, UserHandle.getCallingUserId())) { 2594 Log.w(LOG_TAG, "Cannot add user. " + restriction + " is enabled."); 2595 return null; 2596 } 2597 return createUserInternalUnchecked(name, flags, parentId, disallowedPackages); 2598 } 2599 createUserInternalUnchecked(String name, int flags, int parentId, String[] disallowedPackages)2600 private UserInfo createUserInternalUnchecked(String name, int flags, int parentId, 2601 String[] disallowedPackages) { 2602 DeviceStorageMonitorInternal dsm = LocalServices 2603 .getService(DeviceStorageMonitorInternal.class); 2604 if (dsm.isMemoryLow()) { 2605 Log.w(LOG_TAG, "Cannot add user. Not enough space on disk."); 2606 return null; 2607 } 2608 final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0; 2609 final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0; 2610 final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0; 2611 final boolean isDemo = (flags & UserInfo.FLAG_DEMO) != 0; 2612 final long ident = Binder.clearCallingIdentity(); 2613 UserInfo userInfo; 2614 UserData userData; 2615 final int userId; 2616 try { 2617 synchronized (mPackagesLock) { 2618 UserData parent = null; 2619 if (parentId != UserHandle.USER_NULL) { 2620 synchronized (mUsersLock) { 2621 parent = getUserDataLU(parentId); 2622 } 2623 if (parent == null) return null; 2624 } 2625 if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) { 2626 Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId); 2627 return null; 2628 } 2629 if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) { 2630 // If we're not adding a guest/demo user or a managed profile and the limit has 2631 // been reached, cannot add a user. 2632 return null; 2633 } 2634 // If we're adding a guest and there already exists one, bail. 2635 if (isGuest && findCurrentGuestUser() != null) { 2636 return null; 2637 } 2638 // In legacy mode, restricted profile's parent can only be the owner user 2639 if (isRestricted && !UserManager.isSplitSystemUser() 2640 && (parentId != UserHandle.USER_SYSTEM)) { 2641 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner"); 2642 return null; 2643 } 2644 if (isRestricted && UserManager.isSplitSystemUser()) { 2645 if (parent == null) { 2646 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be " 2647 + "specified"); 2648 return null; 2649 } 2650 if (!parent.info.canHaveProfile()) { 2651 Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be " 2652 + "created for the specified parent user id " + parentId); 2653 return null; 2654 } 2655 } 2656 // In split system user mode, we assign the first human user the primary flag. 2657 // And if there is no device owner, we also assign the admin flag to primary user. 2658 if (UserManager.isSplitSystemUser() 2659 && !isGuest && !isManagedProfile && getPrimaryUser() == null) { 2660 flags |= UserInfo.FLAG_PRIMARY; 2661 synchronized (mUsersLock) { 2662 if (!mIsDeviceManaged) { 2663 flags |= UserInfo.FLAG_ADMIN; 2664 } 2665 } 2666 } 2667 2668 userId = getNextAvailableId(); 2669 Environment.getUserSystemDirectory(userId).mkdirs(); 2670 boolean ephemeralGuests = Resources.getSystem() 2671 .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral); 2672 2673 synchronized (mUsersLock) { 2674 // Add ephemeral flag to guests/users if required. Also inherit it from parent. 2675 if ((isGuest && ephemeralGuests) || mForceEphemeralUsers 2676 || (parent != null && parent.info.isEphemeral())) { 2677 flags |= UserInfo.FLAG_EPHEMERAL; 2678 } 2679 2680 userInfo = new UserInfo(userId, name, null, flags); 2681 userInfo.serialNumber = mNextSerialNumber++; 2682 long now = System.currentTimeMillis(); 2683 userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0; 2684 userInfo.partial = true; 2685 userInfo.lastLoggedInFingerprint = Build.FINGERPRINT; 2686 if (isManagedProfile && parentId != UserHandle.USER_NULL) { 2687 userInfo.profileBadge = getFreeProfileBadgeLU(parentId); 2688 } 2689 userData = new UserData(); 2690 userData.info = userInfo; 2691 mUsers.put(userId, userData); 2692 } 2693 writeUserLP(userData); 2694 writeUserListLP(); 2695 if (parent != null) { 2696 if (isManagedProfile) { 2697 if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 2698 parent.info.profileGroupId = parent.info.id; 2699 writeUserLP(parent); 2700 } 2701 userInfo.profileGroupId = parent.info.profileGroupId; 2702 } else if (isRestricted) { 2703 if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) { 2704 parent.info.restrictedProfileParentId = parent.info.id; 2705 writeUserLP(parent); 2706 } 2707 userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId; 2708 } 2709 } 2710 } 2711 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2712 storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral()); 2713 mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber, 2714 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 2715 mPm.createNewUser(userId, disallowedPackages); 2716 userInfo.partial = false; 2717 synchronized (mPackagesLock) { 2718 writeUserLP(userData); 2719 } 2720 updateUserIds(); 2721 Bundle restrictions = new Bundle(); 2722 if (isGuest) { 2723 synchronized (mGuestRestrictions) { 2724 restrictions.putAll(mGuestRestrictions); 2725 } 2726 } 2727 synchronized (mRestrictionsLock) { 2728 mBaseUserRestrictions.append(userId, restrictions); 2729 } 2730 mPm.onNewUserCreated(userId); 2731 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED); 2732 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 2733 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 2734 android.Manifest.permission.MANAGE_USERS); 2735 MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED 2736 : (isDemo ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1); 2737 } finally { 2738 Binder.restoreCallingIdentity(ident); 2739 } 2740 return userInfo; 2741 } 2742 2743 @VisibleForTesting putUserInfo(UserInfo userInfo)2744 UserData putUserInfo(UserInfo userInfo) { 2745 final UserData userData = new UserData(); 2746 userData.info = userInfo; 2747 synchronized (mUsers) { 2748 mUsers.put(userInfo.id, userData); 2749 } 2750 return userData; 2751 } 2752 2753 @VisibleForTesting removeUserInfo(int userId)2754 void removeUserInfo(int userId) { 2755 synchronized (mUsers) { 2756 mUsers.remove(userId); 2757 } 2758 } 2759 2760 /** 2761 * @hide 2762 */ 2763 @Override createRestrictedProfile(String name, int parentUserId)2764 public UserInfo createRestrictedProfile(String name, int parentUserId) { 2765 checkManageOrCreateUsersPermission("setupRestrictedProfile"); 2766 final UserInfo user = createProfileForUser( 2767 name, UserInfo.FLAG_RESTRICTED, parentUserId, null); 2768 if (user == null) { 2769 return null; 2770 } 2771 long identity = Binder.clearCallingIdentity(); 2772 try { 2773 setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id); 2774 // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise 2775 // the putIntForUser() will fail. 2776 android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(), 2777 android.provider.Settings.Secure.LOCATION_MODE, 2778 android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id); 2779 setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id); 2780 } finally { 2781 Binder.restoreCallingIdentity(identity); 2782 } 2783 return user; 2784 } 2785 2786 /** 2787 * Find the current guest user. If the Guest user is partial, 2788 * then do not include it in the results as it is about to die. 2789 */ findCurrentGuestUser()2790 private UserInfo findCurrentGuestUser() { 2791 synchronized (mUsersLock) { 2792 final int size = mUsers.size(); 2793 for (int i = 0; i < size; i++) { 2794 final UserInfo user = mUsers.valueAt(i).info; 2795 if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) { 2796 return user; 2797 } 2798 } 2799 } 2800 return null; 2801 } 2802 2803 /** 2804 * Mark this guest user for deletion to allow us to create another guest 2805 * and switch to that user before actually removing this guest. 2806 * @param userHandle the userid of the current guest 2807 * @return whether the user could be marked for deletion 2808 */ 2809 @Override markGuestForDeletion(int userHandle)2810 public boolean markGuestForDeletion(int userHandle) { 2811 checkManageUsersPermission("Only the system can remove users"); 2812 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 2813 UserManager.DISALLOW_REMOVE_USER, false)) { 2814 Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 2815 return false; 2816 } 2817 2818 long ident = Binder.clearCallingIdentity(); 2819 try { 2820 final UserData userData; 2821 synchronized (mPackagesLock) { 2822 synchronized (mUsersLock) { 2823 userData = mUsers.get(userHandle); 2824 if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) { 2825 return false; 2826 } 2827 } 2828 if (!userData.info.isGuest()) { 2829 return false; 2830 } 2831 // We set this to a guest user that is to be removed. This is a temporary state 2832 // where we are allowed to add new Guest users, even if this one is still not 2833 // removed. This user will still show up in getUserInfo() calls. 2834 // If we don't get around to removing this Guest user, it will be purged on next 2835 // startup. 2836 userData.info.guestToRemove = true; 2837 // Mark it as disabled, so that it isn't returned any more when 2838 // profiles are queried. 2839 userData.info.flags |= UserInfo.FLAG_DISABLED; 2840 writeUserLP(userData); 2841 } 2842 } finally { 2843 Binder.restoreCallingIdentity(ident); 2844 } 2845 return true; 2846 } 2847 2848 /** 2849 * Removes a user and all data directories created for that user. This method should be called 2850 * after the user's processes have been terminated. 2851 * @param userHandle the user's id 2852 */ 2853 @Override removeUser(int userHandle)2854 public boolean removeUser(int userHandle) { 2855 Slog.i(LOG_TAG, "removeUser u" + userHandle); 2856 checkManageOrCreateUsersPermission("Only the system can remove users"); 2857 2858 final boolean isManagedProfile; 2859 synchronized (mUsersLock) { 2860 UserInfo userInfo = getUserInfoLU(userHandle); 2861 isManagedProfile = userInfo != null && userInfo.isManagedProfile(); 2862 } 2863 String restriction = isManagedProfile 2864 ? UserManager.DISALLOW_REMOVE_MANAGED_PROFILE : UserManager.DISALLOW_REMOVE_USER; 2865 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) { 2866 Log.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled."); 2867 return false; 2868 } 2869 return removeUserUnchecked(userHandle); 2870 } 2871 removeUserUnchecked(int userHandle)2872 private boolean removeUserUnchecked(int userHandle) { 2873 long ident = Binder.clearCallingIdentity(); 2874 try { 2875 final UserData userData; 2876 int currentUser = ActivityManager.getCurrentUser(); 2877 if (currentUser == userHandle) { 2878 Log.w(LOG_TAG, "Current user cannot be removed"); 2879 return false; 2880 } 2881 synchronized (mPackagesLock) { 2882 synchronized (mUsersLock) { 2883 userData = mUsers.get(userHandle); 2884 if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) { 2885 return false; 2886 } 2887 2888 addRemovingUserIdLocked(userHandle); 2889 } 2890 2891 // Set this to a partially created user, so that the user will be purged 2892 // on next startup, in case the runtime stops now before stopping and 2893 // removing the user completely. 2894 userData.info.partial = true; 2895 // Mark it as disabled, so that it isn't returned any more when 2896 // profiles are queried. 2897 userData.info.flags |= UserInfo.FLAG_DISABLED; 2898 writeUserLP(userData); 2899 } 2900 try { 2901 mAppOpsService.removeUser(userHandle); 2902 } catch (RemoteException e) { 2903 Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e); 2904 } 2905 2906 if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 2907 && userData.info.isManagedProfile()) { 2908 // Send broadcast to notify system that the user removed was a 2909 // managed user. 2910 sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id); 2911 } 2912 2913 if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle); 2914 int res; 2915 try { 2916 res = ActivityManager.getService().stopUser(userHandle, /* force= */ true, 2917 new IStopUserCallback.Stub() { 2918 @Override 2919 public void userStopped(int userId) { 2920 finishRemoveUser(userId); 2921 } 2922 @Override 2923 public void userStopAborted(int userId) { 2924 } 2925 }); 2926 } catch (RemoteException e) { 2927 return false; 2928 } 2929 return res == ActivityManager.USER_OP_SUCCESS; 2930 } finally { 2931 Binder.restoreCallingIdentity(ident); 2932 } 2933 } 2934 2935 @GuardedBy("mUsersLock") 2936 @VisibleForTesting addRemovingUserIdLocked(int userId)2937 void addRemovingUserIdLocked(int userId) { 2938 // We remember deleted user IDs to prevent them from being 2939 // reused during the current boot; they can still be reused 2940 // after a reboot or recycling of userIds. 2941 mRemovingUserIds.put(userId, true); 2942 mRecentlyRemovedIds.add(userId); 2943 // Keep LRU queue of recently removed IDs for recycling 2944 if (mRecentlyRemovedIds.size() > MAX_RECENTLY_REMOVED_IDS_SIZE) { 2945 mRecentlyRemovedIds.removeFirst(); 2946 } 2947 } 2948 finishRemoveUser(final int userHandle)2949 void finishRemoveUser(final int userHandle) { 2950 if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle); 2951 // Let other services shutdown any activity and clean up their state before completely 2952 // wiping the user's system directory and removing from the user list 2953 long ident = Binder.clearCallingIdentity(); 2954 try { 2955 Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED); 2956 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2957 mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL, 2958 android.Manifest.permission.MANAGE_USERS, 2959 2960 new BroadcastReceiver() { 2961 @Override 2962 public void onReceive(Context context, Intent intent) { 2963 if (DBG) { 2964 Slog.i(LOG_TAG, 2965 "USER_REMOVED broadcast sent, cleaning up user data " 2966 + userHandle); 2967 } 2968 new Thread() { 2969 @Override 2970 public void run() { 2971 // Clean up any ActivityManager state 2972 LocalServices.getService(ActivityManagerInternal.class) 2973 .onUserRemoved(userHandle); 2974 removeUserState(userHandle); 2975 } 2976 }.start(); 2977 } 2978 }, 2979 2980 null, Activity.RESULT_OK, null, null); 2981 } finally { 2982 Binder.restoreCallingIdentity(ident); 2983 } 2984 } 2985 removeUserState(final int userHandle)2986 private void removeUserState(final int userHandle) { 2987 try { 2988 mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle); 2989 } catch (IllegalStateException e) { 2990 // This may be simply because the user was partially created. 2991 Slog.i(LOG_TAG, 2992 "Destroying key for user " + userHandle + " failed, continuing anyway", e); 2993 } 2994 2995 // Cleanup gatekeeper secure user id 2996 try { 2997 final IGateKeeperService gk = GateKeeper.getService(); 2998 if (gk != null) { 2999 gk.clearSecureUserId(userHandle); 3000 } 3001 } catch (Exception ex) { 3002 Slog.w(LOG_TAG, "unable to clear GK secure user id"); 3003 } 3004 3005 // Cleanup package manager settings 3006 mPm.cleanUpUser(this, userHandle); 3007 3008 // Clean up all data before removing metadata 3009 mUserDataPreparer.destroyUserData(userHandle, 3010 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 3011 3012 // Remove this user from the list 3013 synchronized (mUsersLock) { 3014 mUsers.remove(userHandle); 3015 mIsUserManaged.delete(userHandle); 3016 } 3017 synchronized (mUserStates) { 3018 mUserStates.delete(userHandle); 3019 } 3020 synchronized (mRestrictionsLock) { 3021 mBaseUserRestrictions.remove(userHandle); 3022 mAppliedUserRestrictions.remove(userHandle); 3023 mCachedEffectiveUserRestrictions.remove(userHandle); 3024 mDevicePolicyLocalUserRestrictions.remove(userHandle); 3025 if (mDevicePolicyGlobalUserRestrictions.get(userHandle) != null) { 3026 mDevicePolicyGlobalUserRestrictions.remove(userHandle); 3027 applyUserRestrictionsForAllUsersLR(); 3028 } 3029 } 3030 // Update the user list 3031 synchronized (mPackagesLock) { 3032 writeUserListLP(); 3033 } 3034 // Remove user file 3035 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX)); 3036 userFile.delete(); 3037 updateUserIds(); 3038 if (RELEASE_DELETED_USER_ID) { 3039 synchronized (mUsers) { 3040 mRemovingUserIds.delete(userHandle); 3041 } 3042 } 3043 } 3044 sendProfileRemovedBroadcast(int parentUserId, int removedUserId)3045 private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { 3046 Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); 3047 managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | 3048 Intent.FLAG_RECEIVER_FOREGROUND); 3049 managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); 3050 managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); 3051 mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null); 3052 } 3053 3054 @Override getApplicationRestrictions(String packageName)3055 public Bundle getApplicationRestrictions(String packageName) { 3056 return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId()); 3057 } 3058 3059 @Override getApplicationRestrictionsForUser(String packageName, int userId)3060 public Bundle getApplicationRestrictionsForUser(String packageName, int userId) { 3061 if (UserHandle.getCallingUserId() != userId 3062 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { 3063 checkSystemOrRoot("get application restrictions for other user/app " + packageName); 3064 } 3065 synchronized (mAppRestrictionsLock) { 3066 // Read the restrictions from XML 3067 return readApplicationRestrictionsLAr(packageName, userId); 3068 } 3069 } 3070 3071 @Override setApplicationRestrictions(String packageName, Bundle restrictions, int userId)3072 public void setApplicationRestrictions(String packageName, Bundle restrictions, 3073 int userId) { 3074 checkSystemOrRoot("set application restrictions"); 3075 if (restrictions != null) { 3076 restrictions.setDefusable(true); 3077 } 3078 synchronized (mAppRestrictionsLock) { 3079 if (restrictions == null || restrictions.isEmpty()) { 3080 cleanAppRestrictionsForPackageLAr(packageName, userId); 3081 } else { 3082 // Write the restrictions to XML 3083 writeApplicationRestrictionsLAr(packageName, restrictions, userId); 3084 } 3085 } 3086 3087 // Notify package of changes via an intent - only sent to explicitly registered receivers. 3088 Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); 3089 changeIntent.setPackage(packageName); 3090 changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3091 mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId)); 3092 } 3093 getUidForPackage(String packageName)3094 private int getUidForPackage(String packageName) { 3095 long ident = Binder.clearCallingIdentity(); 3096 try { 3097 return mContext.getPackageManager().getApplicationInfo(packageName, 3098 PackageManager.MATCH_ANY_USER).uid; 3099 } catch (NameNotFoundException nnfe) { 3100 return -1; 3101 } finally { 3102 Binder.restoreCallingIdentity(ident); 3103 } 3104 } 3105 3106 @GuardedBy("mAppRestrictionsLock") readApplicationRestrictionsLAr(String packageName, int userId)3107 private static Bundle readApplicationRestrictionsLAr(String packageName, int userId) { 3108 AtomicFile restrictionsFile = 3109 new AtomicFile(new File(Environment.getUserSystemDirectory(userId), 3110 packageToRestrictionsFileName(packageName))); 3111 return readApplicationRestrictionsLAr(restrictionsFile); 3112 } 3113 3114 @VisibleForTesting 3115 @GuardedBy("mAppRestrictionsLock") readApplicationRestrictionsLAr(AtomicFile restrictionsFile)3116 static Bundle readApplicationRestrictionsLAr(AtomicFile restrictionsFile) { 3117 final Bundle restrictions = new Bundle(); 3118 final ArrayList<String> values = new ArrayList<>(); 3119 if (!restrictionsFile.getBaseFile().exists()) { 3120 return restrictions; 3121 } 3122 3123 FileInputStream fis = null; 3124 try { 3125 fis = restrictionsFile.openRead(); 3126 XmlPullParser parser = Xml.newPullParser(); 3127 parser.setInput(fis, StandardCharsets.UTF_8.name()); 3128 XmlUtils.nextElement(parser); 3129 if (parser.getEventType() != XmlPullParser.START_TAG) { 3130 Slog.e(LOG_TAG, "Unable to read restrictions file " 3131 + restrictionsFile.getBaseFile()); 3132 return restrictions; 3133 } 3134 while (parser.next() != XmlPullParser.END_DOCUMENT) { 3135 readEntry(restrictions, values, parser); 3136 } 3137 } catch (IOException|XmlPullParserException e) { 3138 Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e); 3139 } finally { 3140 IoUtils.closeQuietly(fis); 3141 } 3142 return restrictions; 3143 } 3144 readEntry(Bundle restrictions, ArrayList<String> values, XmlPullParser parser)3145 private static void readEntry(Bundle restrictions, ArrayList<String> values, 3146 XmlPullParser parser) throws XmlPullParserException, IOException { 3147 int type = parser.getEventType(); 3148 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) { 3149 String key = parser.getAttributeValue(null, ATTR_KEY); 3150 String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE); 3151 String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE); 3152 if (multiple != null) { 3153 values.clear(); 3154 int count = Integer.parseInt(multiple); 3155 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) { 3156 if (type == XmlPullParser.START_TAG 3157 && parser.getName().equals(TAG_VALUE)) { 3158 values.add(parser.nextText().trim()); 3159 count--; 3160 } 3161 } 3162 String [] valueStrings = new String[values.size()]; 3163 values.toArray(valueStrings); 3164 restrictions.putStringArray(key, valueStrings); 3165 } else if (ATTR_TYPE_BUNDLE.equals(valType)) { 3166 restrictions.putBundle(key, readBundleEntry(parser, values)); 3167 } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) { 3168 final int outerDepth = parser.getDepth(); 3169 ArrayList<Bundle> bundleList = new ArrayList<>(); 3170 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 3171 Bundle childBundle = readBundleEntry(parser, values); 3172 bundleList.add(childBundle); 3173 } 3174 restrictions.putParcelableArray(key, 3175 bundleList.toArray(new Bundle[bundleList.size()])); 3176 } else { 3177 String value = parser.nextText().trim(); 3178 if (ATTR_TYPE_BOOLEAN.equals(valType)) { 3179 restrictions.putBoolean(key, Boolean.parseBoolean(value)); 3180 } else if (ATTR_TYPE_INTEGER.equals(valType)) { 3181 restrictions.putInt(key, Integer.parseInt(value)); 3182 } else { 3183 restrictions.putString(key, value); 3184 } 3185 } 3186 } 3187 } 3188 readBundleEntry(XmlPullParser parser, ArrayList<String> values)3189 private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values) 3190 throws IOException, XmlPullParserException { 3191 Bundle childBundle = new Bundle(); 3192 final int outerDepth = parser.getDepth(); 3193 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 3194 readEntry(childBundle, values, parser); 3195 } 3196 return childBundle; 3197 } 3198 3199 @GuardedBy("mAppRestrictionsLock") writeApplicationRestrictionsLAr(String packageName, Bundle restrictions, int userId)3200 private static void writeApplicationRestrictionsLAr(String packageName, 3201 Bundle restrictions, int userId) { 3202 AtomicFile restrictionsFile = new AtomicFile( 3203 new File(Environment.getUserSystemDirectory(userId), 3204 packageToRestrictionsFileName(packageName))); 3205 writeApplicationRestrictionsLAr(restrictions, restrictionsFile); 3206 } 3207 3208 @VisibleForTesting 3209 @GuardedBy("mAppRestrictionsLock") writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile)3210 static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) { 3211 FileOutputStream fos = null; 3212 try { 3213 fos = restrictionsFile.startWrite(); 3214 final BufferedOutputStream bos = new BufferedOutputStream(fos); 3215 3216 final XmlSerializer serializer = new FastXmlSerializer(); 3217 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 3218 serializer.startDocument(null, true); 3219 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 3220 3221 serializer.startTag(null, TAG_RESTRICTIONS); 3222 writeBundle(restrictions, serializer); 3223 serializer.endTag(null, TAG_RESTRICTIONS); 3224 3225 serializer.endDocument(); 3226 restrictionsFile.finishWrite(fos); 3227 } catch (Exception e) { 3228 restrictionsFile.failWrite(fos); 3229 Slog.e(LOG_TAG, "Error writing application restrictions list", e); 3230 } 3231 } 3232 writeBundle(Bundle restrictions, XmlSerializer serializer)3233 private static void writeBundle(Bundle restrictions, XmlSerializer serializer) 3234 throws IOException { 3235 for (String key : restrictions.keySet()) { 3236 Object value = restrictions.get(key); 3237 serializer.startTag(null, TAG_ENTRY); 3238 serializer.attribute(null, ATTR_KEY, key); 3239 3240 if (value instanceof Boolean) { 3241 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN); 3242 serializer.text(value.toString()); 3243 } else if (value instanceof Integer) { 3244 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER); 3245 serializer.text(value.toString()); 3246 } else if (value == null || value instanceof String) { 3247 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING); 3248 serializer.text(value != null ? (String) value : ""); 3249 } else if (value instanceof Bundle) { 3250 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 3251 writeBundle((Bundle) value, serializer); 3252 } else if (value instanceof Parcelable[]) { 3253 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY); 3254 Parcelable[] array = (Parcelable[]) value; 3255 for (Parcelable parcelable : array) { 3256 if (!(parcelable instanceof Bundle)) { 3257 throw new IllegalArgumentException("bundle-array can only hold Bundles"); 3258 } 3259 serializer.startTag(null, TAG_ENTRY); 3260 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 3261 writeBundle((Bundle) parcelable, serializer); 3262 serializer.endTag(null, TAG_ENTRY); 3263 } 3264 } else { 3265 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY); 3266 String[] values = (String[]) value; 3267 serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length)); 3268 for (String choice : values) { 3269 serializer.startTag(null, TAG_VALUE); 3270 serializer.text(choice != null ? choice : ""); 3271 serializer.endTag(null, TAG_VALUE); 3272 } 3273 } 3274 serializer.endTag(null, TAG_ENTRY); 3275 } 3276 } 3277 3278 @Override getUserSerialNumber(int userHandle)3279 public int getUserSerialNumber(int userHandle) { 3280 synchronized (mUsersLock) { 3281 if (!exists(userHandle)) return -1; 3282 return getUserInfoLU(userHandle).serialNumber; 3283 } 3284 } 3285 3286 @Override isUserNameSet(int userHandle)3287 public boolean isUserNameSet(int userHandle) { 3288 synchronized (mUsersLock) { 3289 UserInfo userInfo = getUserInfoLU(userHandle); 3290 return userInfo != null && userInfo.name != null; 3291 } 3292 } 3293 3294 @Override getUserHandle(int userSerialNumber)3295 public int getUserHandle(int userSerialNumber) { 3296 synchronized (mUsersLock) { 3297 for (int userId : mUserIds) { 3298 UserInfo info = getUserInfoLU(userId); 3299 if (info != null && info.serialNumber == userSerialNumber) return userId; 3300 } 3301 // Not found 3302 return -1; 3303 } 3304 } 3305 3306 @Override getUserCreationTime(int userHandle)3307 public long getUserCreationTime(int userHandle) { 3308 int callingUserId = UserHandle.getCallingUserId(); 3309 UserInfo userInfo = null; 3310 synchronized (mUsersLock) { 3311 if (callingUserId == userHandle) { 3312 userInfo = getUserInfoLU(userHandle); 3313 } else { 3314 UserInfo parent = getProfileParentLU(userHandle); 3315 if (parent != null && parent.id == callingUserId) { 3316 userInfo = getUserInfoLU(userHandle); 3317 } 3318 } 3319 } 3320 if (userInfo == null) { 3321 throw new SecurityException("userHandle can only be the calling user or a managed " 3322 + "profile associated with this user"); 3323 } 3324 return userInfo.creationTime; 3325 } 3326 3327 /** 3328 * Caches the list of user ids in an array, adjusting the array size when necessary. 3329 */ updateUserIds()3330 private void updateUserIds() { 3331 int num = 0; 3332 synchronized (mUsersLock) { 3333 final int userSize = mUsers.size(); 3334 for (int i = 0; i < userSize; i++) { 3335 if (!mUsers.valueAt(i).info.partial) { 3336 num++; 3337 } 3338 } 3339 final int[] newUsers = new int[num]; 3340 int n = 0; 3341 for (int i = 0; i < userSize; i++) { 3342 if (!mUsers.valueAt(i).info.partial) { 3343 newUsers[n++] = mUsers.keyAt(i); 3344 } 3345 } 3346 mUserIds = newUsers; 3347 } 3348 } 3349 3350 /** 3351 * Called right before a user is started. This gives us a chance to prepare 3352 * app storage and apply any user restrictions. 3353 */ onBeforeStartUser(int userId)3354 public void onBeforeStartUser(int userId) { 3355 UserInfo userInfo = getUserInfo(userId); 3356 if (userInfo == null) { 3357 return; 3358 } 3359 final int userSerial = userInfo.serialNumber; 3360 // Migrate only if build fingerprints mismatch 3361 boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); 3362 mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE); 3363 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData); 3364 3365 if (userId != UserHandle.USER_SYSTEM) { 3366 synchronized (mRestrictionsLock) { 3367 applyUserRestrictionsLR(userId); 3368 } 3369 } 3370 } 3371 3372 /** 3373 * Called right before a user is unlocked. This gives us a chance to prepare 3374 * app storage. 3375 */ onBeforeUnlockUser(@serIdInt int userId)3376 public void onBeforeUnlockUser(@UserIdInt int userId) { 3377 UserInfo userInfo = getUserInfo(userId); 3378 if (userInfo == null) { 3379 return; 3380 } 3381 final int userSerial = userInfo.serialNumber; 3382 // Migrate only if build fingerprints mismatch 3383 boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); 3384 mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); 3385 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData); 3386 } 3387 3388 /** 3389 * Examine all users present on given mounted volume, and destroy data 3390 * belonging to users that are no longer valid, or whose user ID has been 3391 * recycled. 3392 */ reconcileUsers(String volumeUuid)3393 void reconcileUsers(String volumeUuid) { 3394 mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(true /* excludeDying */)); 3395 } 3396 3397 /** 3398 * Make a note of the last started time of a user and do some cleanup. 3399 * This is called with ActivityManagerService lock held. 3400 * @param userId the user that was just foregrounded 3401 */ onUserLoggedIn(@serIdInt int userId)3402 public void onUserLoggedIn(@UserIdInt int userId) { 3403 UserData userData = getUserDataNoChecks(userId); 3404 if (userData == null || userData.info.partial) { 3405 Slog.w(LOG_TAG, "userForeground: unknown user #" + userId); 3406 return; 3407 } 3408 3409 final long now = System.currentTimeMillis(); 3410 if (now > EPOCH_PLUS_30_YEARS) { 3411 userData.info.lastLoggedInTime = now; 3412 } 3413 userData.info.lastLoggedInFingerprint = Build.FINGERPRINT; 3414 scheduleWriteUser(userData); 3415 } 3416 3417 /** 3418 * Returns the next available user id, filling in any holes in the ids. 3419 */ 3420 @VisibleForTesting getNextAvailableId()3421 int getNextAvailableId() { 3422 int nextId; 3423 synchronized (mUsersLock) { 3424 nextId = scanNextAvailableIdLocked(); 3425 if (nextId >= 0) { 3426 return nextId; 3427 } 3428 // All ids up to MAX_USER_ID were used. Remove all mRemovingUserIds, 3429 // except most recently removed 3430 if (mRemovingUserIds.size() > 0) { 3431 Slog.i(LOG_TAG, "All available IDs are used. Recycling LRU ids."); 3432 mRemovingUserIds.clear(); 3433 for (Integer recentlyRemovedId : mRecentlyRemovedIds) { 3434 mRemovingUserIds.put(recentlyRemovedId, true); 3435 } 3436 nextId = scanNextAvailableIdLocked(); 3437 } 3438 } 3439 if (nextId < 0) { 3440 throw new IllegalStateException("No user id available!"); 3441 } 3442 return nextId; 3443 } 3444 3445 @GuardedBy("mUsersLock") scanNextAvailableIdLocked()3446 private int scanNextAvailableIdLocked() { 3447 for (int i = MIN_USER_ID; i < MAX_USER_ID; i++) { 3448 if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) { 3449 return i; 3450 } 3451 } 3452 return -1; 3453 } 3454 packageToRestrictionsFileName(String packageName)3455 private static String packageToRestrictionsFileName(String packageName) { 3456 return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX; 3457 } 3458 3459 @Override setSeedAccountData(int userId, String accountName, String accountType, PersistableBundle accountOptions, boolean persist)3460 public void setSeedAccountData(int userId, String accountName, String accountType, 3461 PersistableBundle accountOptions, boolean persist) { 3462 checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data"); 3463 synchronized (mPackagesLock) { 3464 final UserData userData; 3465 synchronized (mUsersLock) { 3466 userData = getUserDataLU(userId); 3467 if (userData == null) { 3468 Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); 3469 return; 3470 } 3471 userData.seedAccountName = accountName; 3472 userData.seedAccountType = accountType; 3473 userData.seedAccountOptions = accountOptions; 3474 userData.persistSeedData = persist; 3475 } 3476 if (persist) { 3477 writeUserLP(userData); 3478 } 3479 } 3480 } 3481 3482 @Override getSeedAccountName()3483 public String getSeedAccountName() throws RemoteException { 3484 checkManageUsersPermission("Cannot get seed account information"); 3485 synchronized (mUsersLock) { 3486 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 3487 return userData.seedAccountName; 3488 } 3489 } 3490 3491 @Override getSeedAccountType()3492 public String getSeedAccountType() throws RemoteException { 3493 checkManageUsersPermission("Cannot get seed account information"); 3494 synchronized (mUsersLock) { 3495 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 3496 return userData.seedAccountType; 3497 } 3498 } 3499 3500 @Override getSeedAccountOptions()3501 public PersistableBundle getSeedAccountOptions() throws RemoteException { 3502 checkManageUsersPermission("Cannot get seed account information"); 3503 synchronized (mUsersLock) { 3504 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 3505 return userData.seedAccountOptions; 3506 } 3507 } 3508 3509 @Override clearSeedAccountData()3510 public void clearSeedAccountData() throws RemoteException { 3511 checkManageUsersPermission("Cannot clear seed account information"); 3512 synchronized (mPackagesLock) { 3513 UserData userData; 3514 synchronized (mUsersLock) { 3515 userData = getUserDataLU(UserHandle.getCallingUserId()); 3516 if (userData == null) return; 3517 userData.clearSeedAccountData(); 3518 } 3519 writeUserLP(userData); 3520 } 3521 } 3522 3523 @Override someUserHasSeedAccount(String accountName, String accountType)3524 public boolean someUserHasSeedAccount(String accountName, String accountType) 3525 throws RemoteException { 3526 checkManageUsersPermission("Cannot check seed account information"); 3527 synchronized (mUsersLock) { 3528 final int userSize = mUsers.size(); 3529 for (int i = 0; i < userSize; i++) { 3530 final UserData data = mUsers.valueAt(i); 3531 if (data.info.isInitialized()) continue; 3532 if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) { 3533 continue; 3534 } 3535 if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) { 3536 continue; 3537 } 3538 return true; 3539 } 3540 } 3541 return false; 3542 } 3543 3544 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)3545 public void onShellCommand(FileDescriptor in, FileDescriptor out, 3546 FileDescriptor err, String[] args, ShellCallback callback, 3547 ResultReceiver resultReceiver) { 3548 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 3549 } 3550 onShellCommand(Shell shell, String cmd)3551 int onShellCommand(Shell shell, String cmd) { 3552 if (cmd == null) { 3553 return shell.handleDefaultCommands(cmd); 3554 } 3555 3556 final PrintWriter pw = shell.getOutPrintWriter(); 3557 try { 3558 switch(cmd) { 3559 case "list": 3560 return runList(pw); 3561 } 3562 } catch (RemoteException e) { 3563 pw.println("Remote exception: " + e); 3564 } 3565 return -1; 3566 } 3567 runList(PrintWriter pw)3568 private int runList(PrintWriter pw) throws RemoteException { 3569 final IActivityManager am = ActivityManager.getService(); 3570 final List<UserInfo> users = getUsers(false); 3571 if (users == null) { 3572 pw.println("Error: couldn't get users"); 3573 return 1; 3574 } else { 3575 pw.println("Users:"); 3576 for (int i = 0; i < users.size(); i++) { 3577 String running = am.isUserRunning(users.get(i).id, 0) ? " running" : ""; 3578 pw.println("\t" + users.get(i).toString() + running); 3579 } 3580 return 0; 3581 } 3582 } 3583 3584 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)3585 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3586 if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; 3587 3588 long now = System.currentTimeMillis(); 3589 final long nowRealtime = SystemClock.elapsedRealtime(); 3590 StringBuilder sb = new StringBuilder(); 3591 synchronized (mPackagesLock) { 3592 synchronized (mUsersLock) { 3593 pw.println("Users:"); 3594 for (int i = 0; i < mUsers.size(); i++) { 3595 UserData userData = mUsers.valueAt(i); 3596 if (userData == null) { 3597 continue; 3598 } 3599 UserInfo userInfo = userData.info; 3600 final int userId = userInfo.id; 3601 pw.print(" "); pw.print(userInfo); 3602 pw.print(" serialNo="); pw.print(userInfo.serialNumber); 3603 if (mRemovingUserIds.get(userId)) { 3604 pw.print(" <removing> "); 3605 } 3606 if (userInfo.partial) { 3607 pw.print(" <partial>"); 3608 } 3609 pw.println(); 3610 pw.print(" State: "); 3611 final int state; 3612 synchronized (mUserStates) { 3613 state = mUserStates.get(userId, -1); 3614 } 3615 pw.println(UserState.stateToString(state)); 3616 pw.print(" Created: "); 3617 dumpTimeAgo(pw, sb, now, userInfo.creationTime); 3618 3619 pw.print(" Last logged in: "); 3620 dumpTimeAgo(pw, sb, now, userInfo.lastLoggedInTime); 3621 3622 pw.print(" Last logged in fingerprint: "); 3623 pw.println(userInfo.lastLoggedInFingerprint); 3624 3625 pw.print(" Start time: "); 3626 dumpTimeAgo(pw, sb, nowRealtime, userData.startRealtime); 3627 3628 pw.print(" Unlock time: "); 3629 dumpTimeAgo(pw, sb, nowRealtime, userData.unlockRealtime); 3630 3631 pw.print(" Has profile owner: "); 3632 pw.println(mIsUserManaged.get(userId)); 3633 pw.println(" Restrictions:"); 3634 synchronized (mRestrictionsLock) { 3635 UserRestrictionsUtils.dumpRestrictions( 3636 pw, " ", mBaseUserRestrictions.get(userInfo.id)); 3637 pw.println(" Device policy global restrictions:"); 3638 UserRestrictionsUtils.dumpRestrictions( 3639 pw, " ", mDevicePolicyGlobalUserRestrictions.get(userInfo.id)); 3640 pw.println(" Device policy local restrictions:"); 3641 UserRestrictionsUtils.dumpRestrictions( 3642 pw, " ", mDevicePolicyLocalUserRestrictions.get(userInfo.id)); 3643 pw.println(" Effective restrictions:"); 3644 UserRestrictionsUtils.dumpRestrictions( 3645 pw, " ", mCachedEffectiveUserRestrictions.get(userInfo.id)); 3646 } 3647 3648 if (userData.account != null) { 3649 pw.print(" Account name: " + userData.account); 3650 pw.println(); 3651 } 3652 3653 if (userData.seedAccountName != null) { 3654 pw.print(" Seed account name: " + userData.seedAccountName); 3655 pw.println(); 3656 if (userData.seedAccountType != null) { 3657 pw.print(" account type: " + userData.seedAccountType); 3658 pw.println(); 3659 } 3660 if (userData.seedAccountOptions != null) { 3661 pw.print(" account options exist"); 3662 pw.println(); 3663 } 3664 } 3665 } 3666 } 3667 pw.println(); 3668 pw.println(" Device owner id:" + mDeviceOwnerUserId); 3669 pw.println(); 3670 pw.println(" Guest restrictions:"); 3671 synchronized (mGuestRestrictions) { 3672 UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions); 3673 } 3674 synchronized (mUsersLock) { 3675 pw.println(); 3676 pw.println(" Device managed: " + mIsDeviceManaged); 3677 if (mRemovingUserIds.size() > 0) { 3678 pw.println(); 3679 pw.println(" Recently removed userIds: " + mRecentlyRemovedIds); 3680 } 3681 } 3682 synchronized (mUserStates) { 3683 pw.println(" Started users state: " + mUserStates); 3684 } 3685 // Dump some capabilities 3686 pw.println(); 3687 pw.println(" Max users: " + UserManager.getMaxSupportedUsers()); 3688 pw.println(" Supports switchable users: " + UserManager.supportsMultipleUsers()); 3689 pw.println(" All guests ephemeral: " + Resources.getSystem().getBoolean( 3690 com.android.internal.R.bool.config_guestUserEphemeral)); 3691 } 3692 } 3693 dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time)3694 private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) { 3695 if (time == 0) { 3696 pw.println("<unknown>"); 3697 } else { 3698 sb.setLength(0); 3699 TimeUtils.formatDuration(nowTime - time, sb); 3700 sb.append(" ago"); 3701 pw.println(sb); 3702 } 3703 } 3704 3705 final class MainHandler extends Handler { 3706 3707 @Override handleMessage(Message msg)3708 public void handleMessage(Message msg) { 3709 switch (msg.what) { 3710 case WRITE_USER_MSG: 3711 removeMessages(WRITE_USER_MSG, msg.obj); 3712 synchronized (mPackagesLock) { 3713 int userId = ((UserData) msg.obj).info.id; 3714 UserData userData = getUserDataNoChecks(userId); 3715 if (userData != null) { 3716 writeUserLP(userData); 3717 } 3718 } 3719 } 3720 } 3721 } 3722 3723 /** 3724 * @param userId 3725 * @return whether the user has been initialized yet 3726 */ isUserInitialized(int userId)3727 boolean isUserInitialized(int userId) { 3728 return mLocalService.isUserInitialized(userId); 3729 } 3730 3731 private class LocalService extends UserManagerInternal { 3732 @Override setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope)3733 public void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions, 3734 boolean isDeviceOwner, int cameraRestrictionScope) { 3735 UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, restrictions, 3736 isDeviceOwner, cameraRestrictionScope); 3737 } 3738 3739 @Override getBaseUserRestrictions(int userId)3740 public Bundle getBaseUserRestrictions(int userId) { 3741 synchronized (mRestrictionsLock) { 3742 return mBaseUserRestrictions.get(userId); 3743 } 3744 } 3745 3746 @Override setBaseUserRestrictionsByDpmsForMigration( int userId, Bundle baseRestrictions)3747 public void setBaseUserRestrictionsByDpmsForMigration( 3748 int userId, Bundle baseRestrictions) { 3749 synchronized (mRestrictionsLock) { 3750 if (updateRestrictionsIfNeededLR( 3751 userId, new Bundle(baseRestrictions), mBaseUserRestrictions)) { 3752 invalidateEffectiveUserRestrictionsLR(userId); 3753 } 3754 } 3755 3756 final UserData userData = getUserDataNoChecks(userId); 3757 synchronized (mPackagesLock) { 3758 if (userData != null) { 3759 writeUserLP(userData); 3760 } else { 3761 Slog.w(LOG_TAG, "UserInfo not found for " + userId); 3762 } 3763 } 3764 } 3765 3766 @Override getUserRestriction(int userId, String key)3767 public boolean getUserRestriction(int userId, String key) { 3768 return getUserRestrictions(userId).getBoolean(key); 3769 } 3770 3771 @Override addUserRestrictionsListener(UserRestrictionsListener listener)3772 public void addUserRestrictionsListener(UserRestrictionsListener listener) { 3773 synchronized (mUserRestrictionsListeners) { 3774 mUserRestrictionsListeners.add(listener); 3775 } 3776 } 3777 3778 @Override removeUserRestrictionsListener(UserRestrictionsListener listener)3779 public void removeUserRestrictionsListener(UserRestrictionsListener listener) { 3780 synchronized (mUserRestrictionsListeners) { 3781 mUserRestrictionsListeners.remove(listener); 3782 } 3783 } 3784 3785 @Override setDeviceManaged(boolean isManaged)3786 public void setDeviceManaged(boolean isManaged) { 3787 synchronized (mUsersLock) { 3788 mIsDeviceManaged = isManaged; 3789 } 3790 } 3791 3792 @Override setUserManaged(int userId, boolean isManaged)3793 public void setUserManaged(int userId, boolean isManaged) { 3794 synchronized (mUsersLock) { 3795 mIsUserManaged.put(userId, isManaged); 3796 } 3797 } 3798 3799 @Override setUserIcon(int userId, Bitmap bitmap)3800 public void setUserIcon(int userId, Bitmap bitmap) { 3801 long ident = Binder.clearCallingIdentity(); 3802 try { 3803 synchronized (mPackagesLock) { 3804 UserData userData = getUserDataNoChecks(userId); 3805 if (userData == null || userData.info.partial) { 3806 Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId); 3807 return; 3808 } 3809 writeBitmapLP(userData.info, bitmap); 3810 writeUserLP(userData); 3811 } 3812 sendUserInfoChangedBroadcast(userId); 3813 } finally { 3814 Binder.restoreCallingIdentity(ident); 3815 } 3816 } 3817 3818 @Override setForceEphemeralUsers(boolean forceEphemeralUsers)3819 public void setForceEphemeralUsers(boolean forceEphemeralUsers) { 3820 synchronized (mUsersLock) { 3821 mForceEphemeralUsers = forceEphemeralUsers; 3822 } 3823 } 3824 3825 @Override removeAllUsers()3826 public void removeAllUsers() { 3827 if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) { 3828 // Remove the non-system users straight away. 3829 removeNonSystemUsers(); 3830 } else { 3831 // Switch to the system user first and then remove the other users. 3832 BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() { 3833 @Override 3834 public void onReceive(Context context, Intent intent) { 3835 int userId = 3836 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 3837 if (userId != UserHandle.USER_SYSTEM) { 3838 return; 3839 } 3840 mContext.unregisterReceiver(this); 3841 removeNonSystemUsers(); 3842 } 3843 }; 3844 IntentFilter userSwitchedFilter = new IntentFilter(); 3845 userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED); 3846 mContext.registerReceiver( 3847 userSwitchedReceiver, userSwitchedFilter, null, mHandler); 3848 3849 // Switch to the system user. 3850 ActivityManager am = 3851 (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 3852 am.switchUser(UserHandle.USER_SYSTEM); 3853 } 3854 } 3855 3856 @Override onEphemeralUserStop(int userId)3857 public void onEphemeralUserStop(int userId) { 3858 synchronized (mUsersLock) { 3859 UserInfo userInfo = getUserInfoLU(userId); 3860 if (userInfo != null && userInfo.isEphemeral()) { 3861 // Do not allow switching back to the ephemeral user again as the user is going 3862 // to be deleted. 3863 userInfo.flags |= UserInfo.FLAG_DISABLED; 3864 if (userInfo.isGuest()) { 3865 // Indicate that the guest will be deleted after it stops. 3866 userInfo.guestToRemove = true; 3867 } 3868 } 3869 } 3870 } 3871 3872 @Override createUserEvenWhenDisallowed(String name, int flags, String[] disallowedPackages)3873 public UserInfo createUserEvenWhenDisallowed(String name, int flags, 3874 String[] disallowedPackages) { 3875 UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL, 3876 disallowedPackages); 3877 // Keep this in sync with UserManager.createUser 3878 if (user != null && !user.isAdmin() && !user.isDemo()) { 3879 setUserRestriction(UserManager.DISALLOW_SMS, true, user.id); 3880 setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id); 3881 } 3882 return user; 3883 } 3884 3885 @Override removeUserEvenWhenDisallowed(int userId)3886 public boolean removeUserEvenWhenDisallowed(int userId) { 3887 return removeUserUnchecked(userId); 3888 } 3889 3890 @Override isUserRunning(int userId)3891 public boolean isUserRunning(int userId) { 3892 synchronized (mUserStates) { 3893 return mUserStates.get(userId, -1) >= 0; 3894 } 3895 } 3896 3897 @Override setUserState(int userId, int userState)3898 public void setUserState(int userId, int userState) { 3899 synchronized (mUserStates) { 3900 mUserStates.put(userId, userState); 3901 } 3902 } 3903 3904 @Override removeUserState(int userId)3905 public void removeUserState(int userId) { 3906 synchronized (mUserStates) { 3907 mUserStates.delete(userId); 3908 } 3909 } 3910 3911 @Override getUserIds()3912 public int[] getUserIds() { 3913 return UserManagerService.this.getUserIds(); 3914 } 3915 3916 @Override isUserUnlockingOrUnlocked(int userId)3917 public boolean isUserUnlockingOrUnlocked(int userId) { 3918 int state; 3919 synchronized (mUserStates) { 3920 state = mUserStates.get(userId, -1); 3921 } 3922 // Special case, in the stopping/shutdown state user key can still be unlocked 3923 if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) { 3924 return StorageManager.isUserKeyUnlocked(userId); 3925 } 3926 return (state == UserState.STATE_RUNNING_UNLOCKING) 3927 || (state == UserState.STATE_RUNNING_UNLOCKED); 3928 } 3929 3930 @Override isUserUnlocked(int userId)3931 public boolean isUserUnlocked(int userId) { 3932 int state; 3933 synchronized (mUserStates) { 3934 state = mUserStates.get(userId, -1); 3935 } 3936 // Special case, in the stopping/shutdown state user key can still be unlocked 3937 if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) { 3938 return StorageManager.isUserKeyUnlocked(userId); 3939 } 3940 return state == UserState.STATE_RUNNING_UNLOCKED; 3941 } 3942 3943 @Override isUserInitialized(int userId)3944 public boolean isUserInitialized(int userId) { 3945 return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0; 3946 } 3947 3948 @Override exists(int userId)3949 public boolean exists(int userId) { 3950 return getUserInfoNoChecks(userId) != null; 3951 } 3952 3953 @Override isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException)3954 public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, 3955 boolean throwSecurityException) { 3956 if (targetUserId == callingUserId) { 3957 return true; 3958 } 3959 synchronized (mUsersLock) { 3960 UserInfo callingUserInfo = getUserInfoLU(callingUserId); 3961 if (callingUserInfo == null || callingUserInfo.isManagedProfile()) { 3962 if (throwSecurityException) { 3963 throw new SecurityException( 3964 debugMsg + " for another profile " 3965 + targetUserId + " from " + callingUserId); 3966 } 3967 } 3968 3969 UserInfo targetUserInfo = getUserInfoLU(targetUserId); 3970 if (targetUserInfo == null || !targetUserInfo.isEnabled()) { 3971 // Do not throw any exception here as this could happen due to race conditions 3972 // between the system updating its state and the client getting notified. 3973 if (throwSecurityException) { 3974 Slog.w(LOG_TAG, debugMsg + " for disabled profile " 3975 + targetUserId + " from " + callingUserId); 3976 } 3977 return false; 3978 } 3979 3980 if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || 3981 targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 3982 if (throwSecurityException) { 3983 throw new SecurityException( 3984 debugMsg + " for unrelated profile " + targetUserId); 3985 } 3986 return false; 3987 } 3988 } 3989 return true; 3990 } 3991 3992 @Override getProfileParentId(int userId)3993 public int getProfileParentId(int userId) { 3994 synchronized (mUsersLock) { 3995 UserInfo profileParent = getProfileParentLU(userId); 3996 if (profileParent == null) { 3997 return userId; 3998 } 3999 return profileParent.id; 4000 } 4001 } 4002 4003 @Override isSettingRestrictedForUser(String setting, @UserIdInt int userId, String value, int callingUid)4004 public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId, 4005 String value, int callingUid) { 4006 return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId, 4007 value, callingUid); 4008 } 4009 } 4010 4011 /* Remove all the users except of the system one. */ removeNonSystemUsers()4012 private void removeNonSystemUsers() { 4013 ArrayList<UserInfo> usersToRemove = new ArrayList<>(); 4014 synchronized (mUsersLock) { 4015 final int userSize = mUsers.size(); 4016 for (int i = 0; i < userSize; i++) { 4017 UserInfo ui = mUsers.valueAt(i).info; 4018 if (ui.id != UserHandle.USER_SYSTEM) { 4019 usersToRemove.add(ui); 4020 } 4021 } 4022 } 4023 for (UserInfo ui: usersToRemove) { 4024 removeUser(ui.id); 4025 } 4026 } 4027 4028 private class Shell extends ShellCommand { 4029 @Override onCommand(String cmd)4030 public int onCommand(String cmd) { 4031 return onShellCommand(this, cmd); 4032 } 4033 4034 @Override onHelp()4035 public void onHelp() { 4036 final PrintWriter pw = getOutPrintWriter(); 4037 pw.println("User manager (user) commands:"); 4038 pw.println(" help"); 4039 pw.println(" Print this help text."); 4040 pw.println(""); 4041 pw.println(" list"); 4042 pw.println(" Prints all users on the system."); 4043 } 4044 } 4045 debug(String message)4046 private static void debug(String message) { 4047 Log.d(LOG_TAG, message + 4048 (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, " ") : "")); 4049 } 4050 4051 @VisibleForTesting getMaxManagedProfiles()4052 static int getMaxManagedProfiles() { 4053 // Allow overriding max managed profiles on debuggable builds for testing 4054 // of multiple profiles. 4055 if (!Build.IS_DEBUGGABLE) { 4056 return MAX_MANAGED_PROFILES; 4057 } else { 4058 return SystemProperties.getInt("persist.sys.max_profiles", 4059 MAX_MANAGED_PROFILES); 4060 } 4061 } 4062 4063 @VisibleForTesting getFreeProfileBadgeLU(int parentUserId)4064 int getFreeProfileBadgeLU(int parentUserId) { 4065 int maxManagedProfiles = getMaxManagedProfiles(); 4066 boolean[] usedBadges = new boolean[maxManagedProfiles]; 4067 final int userSize = mUsers.size(); 4068 for (int i = 0; i < userSize; i++) { 4069 UserInfo ui = mUsers.valueAt(i).info; 4070 // Check which badge indexes are already used by this profile group. 4071 if (ui.isManagedProfile() 4072 && ui.profileGroupId == parentUserId 4073 && !mRemovingUserIds.get(ui.id) 4074 && ui.profileBadge < maxManagedProfiles) { 4075 usedBadges[ui.profileBadge] = true; 4076 } 4077 } 4078 for (int i = 0; i < maxManagedProfiles; i++) { 4079 if (!usedBadges[i]) { 4080 return i; 4081 } 4082 } 4083 return 0; 4084 } 4085 4086 /** 4087 * Checks if the given user has a managed profile associated with it. 4088 * @param userId The parent user 4089 * @return 4090 */ hasManagedProfile(int userId)4091 boolean hasManagedProfile(int userId) { 4092 synchronized (mUsersLock) { 4093 UserInfo userInfo = getUserInfoLU(userId); 4094 final int userSize = mUsers.size(); 4095 for (int i = 0; i < userSize; i++) { 4096 UserInfo profile = mUsers.valueAt(i).info; 4097 if (userId != profile.id && isProfileOf(userInfo, profile)) { 4098 return true; 4099 } 4100 } 4101 return false; 4102 } 4103 } 4104 4105 /** 4106 * Check if the calling package name matches with the calling UID, throw 4107 * {@link SecurityException} if not. 4108 */ verifyCallingPackage(String callingPackage, int callingUid)4109 private void verifyCallingPackage(String callingPackage, int callingUid) { 4110 int packageUid = mPm.getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid)); 4111 if (packageUid != callingUid) { 4112 throw new SecurityException("Specified package " + callingPackage 4113 + " does not match the calling uid " + callingUid); 4114 } 4115 } 4116 } 4117