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.ColorRes; 24 import android.annotation.DrawableRes; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.StringRes; 28 import android.annotation.UserIdInt; 29 import android.app.Activity; 30 import android.app.ActivityManager; 31 import android.app.ActivityManagerInternal; 32 import android.app.ActivityManagerNative; 33 import android.app.IActivityManager; 34 import android.app.IStopUserCallback; 35 import android.app.KeyguardManager; 36 import android.app.PendingIntent; 37 import android.app.admin.DevicePolicyEventLogger; 38 import android.app.admin.DevicePolicyManagerInternal; 39 import android.content.BroadcastReceiver; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.IntentSender; 44 import android.content.pm.CrossProfileAppsInternal; 45 import android.content.pm.PackageManager; 46 import android.content.pm.PackageManager.NameNotFoundException; 47 import android.content.pm.PackageManagerInternal; 48 import android.content.pm.ShortcutServiceInternal; 49 import android.content.pm.UserInfo; 50 import android.content.pm.UserInfo.UserInfoFlag; 51 import android.content.res.Resources; 52 import android.graphics.Bitmap; 53 import android.os.Binder; 54 import android.os.Build; 55 import android.os.Bundle; 56 import android.os.Debug; 57 import android.os.Environment; 58 import android.os.FileUtils; 59 import android.os.Handler; 60 import android.os.IBinder; 61 import android.os.IProgressListener; 62 import android.os.IUserManager; 63 import android.os.IUserRestrictionsListener; 64 import android.os.Message; 65 import android.os.ParcelFileDescriptor; 66 import android.os.Parcelable; 67 import android.os.PersistableBundle; 68 import android.os.Process; 69 import android.os.RemoteException; 70 import android.os.ResultReceiver; 71 import android.os.SELinux; 72 import android.os.ServiceManager; 73 import android.os.ServiceSpecificException; 74 import android.os.ShellCallback; 75 import android.os.ShellCommand; 76 import android.os.SystemClock; 77 import android.os.SystemProperties; 78 import android.os.UserHandle; 79 import android.os.UserManager; 80 import android.os.UserManager.EnforcingUser; 81 import android.os.UserManager.QuietModeFlag; 82 import android.os.UserManagerInternal; 83 import android.os.UserManagerInternal.UserRestrictionsListener; 84 import android.os.storage.StorageManager; 85 import android.security.GateKeeper; 86 import android.service.gatekeeper.IGateKeeperService; 87 import android.stats.devicepolicy.DevicePolicyEnums; 88 import android.util.ArrayMap; 89 import android.util.ArraySet; 90 import android.util.AtomicFile; 91 import android.util.IntArray; 92 import android.util.Slog; 93 import android.util.SparseArray; 94 import android.util.SparseBooleanArray; 95 import android.util.SparseIntArray; 96 import android.util.TimeUtils; 97 import android.util.Xml; 98 99 import com.android.internal.annotations.GuardedBy; 100 import com.android.internal.annotations.VisibleForTesting; 101 import com.android.internal.app.IAppOpsService; 102 import com.android.internal.logging.MetricsLogger; 103 import com.android.internal.os.BackgroundThread; 104 import com.android.internal.util.DumpUtils; 105 import com.android.internal.util.FastXmlSerializer; 106 import com.android.internal.util.FrameworkStatsLog; 107 import com.android.internal.util.IndentingPrintWriter; 108 import com.android.internal.util.Preconditions; 109 import com.android.internal.util.XmlUtils; 110 import com.android.internal.widget.LockPatternUtils; 111 import com.android.server.LocalServices; 112 import com.android.server.LockGuard; 113 import com.android.server.SystemService; 114 import com.android.server.am.UserState; 115 import com.android.server.storage.DeviceStorageMonitorInternal; 116 import com.android.server.utils.TimingsTraceAndSlog; 117 118 import libcore.io.IoUtils; 119 120 import org.xmlpull.v1.XmlPullParser; 121 import org.xmlpull.v1.XmlPullParserException; 122 import org.xmlpull.v1.XmlSerializer; 123 124 import java.io.BufferedOutputStream; 125 import java.io.File; 126 import java.io.FileDescriptor; 127 import java.io.FileInputStream; 128 import java.io.FileNotFoundException; 129 import java.io.FileOutputStream; 130 import java.io.IOException; 131 import java.io.InputStream; 132 import java.io.OutputStream; 133 import java.io.PrintWriter; 134 import java.nio.charset.StandardCharsets; 135 import java.util.ArrayList; 136 import java.util.Arrays; 137 import java.util.Collections; 138 import java.util.LinkedList; 139 import java.util.List; 140 import java.util.Objects; 141 import java.util.Set; 142 import java.util.concurrent.ThreadLocalRandom; 143 144 /** 145 * Service for {@link UserManager}. 146 * 147 * Method naming convention: 148 * <ul> 149 * <li> Methods suffixed with "LAr" should be called within the {@link #mAppRestrictionsLock} lock. 150 * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock. 151 * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock. 152 * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock. 153 * </ul> 154 */ 155 public class UserManagerService extends IUserManager.Stub { 156 157 private static final String LOG_TAG = "UserManagerService"; 158 static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE 159 private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE 160 // Can be used for manual testing of id recycling 161 private static final boolean RELEASE_DELETED_USER_ID = false; // DO NOT SUBMIT WITH TRUE 162 163 private static final String TAG_NAME = "name"; 164 private static final String TAG_ACCOUNT = "account"; 165 private static final String ATTR_FLAGS = "flags"; 166 private static final String ATTR_TYPE = "type"; 167 private static final String ATTR_ICON_PATH = "icon"; 168 private static final String ATTR_ID = "id"; 169 private static final String ATTR_CREATION_TIME = "created"; 170 private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn"; 171 private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint"; 172 private static final String ATTR_SERIAL_NO = "serialNumber"; 173 private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; 174 private static final String ATTR_PARTIAL = "partial"; 175 private static final String ATTR_PRE_CREATED = "preCreated"; 176 private static final String ATTR_CONVERTED_FROM_PRE_CREATED = "convertedFromPreCreated"; 177 private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove"; 178 private static final String ATTR_USER_VERSION = "version"; 179 private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId"; 180 private static final String ATTR_PROFILE_BADGE = "profileBadge"; 181 private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId"; 182 private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName"; 183 private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType"; 184 private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions"; 185 private static final String TAG_USERS = "users"; 186 private static final String TAG_USER = "user"; 187 private static final String TAG_RESTRICTIONS = "restrictions"; 188 private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions"; 189 private static final String TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS = 190 "device_policy_local_restrictions"; 191 private static final String TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS = 192 "device_policy_global_restrictions"; 193 /** Legacy name for device owner id tag. */ 194 private static final String TAG_GLOBAL_RESTRICTION_OWNER_ID = "globalRestrictionOwnerUserId"; 195 private static final String TAG_DEVICE_OWNER_USER_ID = "deviceOwnerUserId"; 196 private static final String TAG_ENTRY = "entry"; 197 private static final String TAG_VALUE = "value"; 198 private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; 199 private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL = 200 "lastRequestQuietModeEnabledCall"; 201 private static final String ATTR_KEY = "key"; 202 private static final String ATTR_VALUE_TYPE = "type"; 203 private static final String ATTR_MULTIPLE = "m"; 204 205 private static final String ATTR_TYPE_STRING_ARRAY = "sa"; 206 private static final String ATTR_TYPE_STRING = "s"; 207 private static final String ATTR_TYPE_BOOLEAN = "b"; 208 private static final String ATTR_TYPE_INTEGER = "i"; 209 private static final String ATTR_TYPE_BUNDLE = "B"; 210 private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA"; 211 212 private static final String USER_INFO_DIR = "system" + File.separator + "users"; 213 private static final String USER_LIST_FILENAME = "userlist.xml"; 214 private static final String USER_PHOTO_FILENAME = "photo.png"; 215 private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp"; 216 217 private static final String RESTRICTIONS_FILE_PREFIX = "res_"; 218 private static final String XML_SUFFIX = ".xml"; 219 220 private static final int ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION = 221 UserInfo.FLAG_MANAGED_PROFILE 222 | UserInfo.FLAG_EPHEMERAL 223 | UserInfo.FLAG_RESTRICTED 224 | UserInfo.FLAG_GUEST 225 | UserInfo.FLAG_DEMO; 226 227 @VisibleForTesting 228 static final int MIN_USER_ID = UserHandle.MIN_SECONDARY_USER_ID; 229 230 // We need to keep process uid within Integer.MAX_VALUE. 231 @VisibleForTesting 232 static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE; 233 234 // Max size of the queue of recently removed users 235 @VisibleForTesting 236 static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100; 237 238 private static final int USER_VERSION = 9; 239 240 private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms 241 242 static final int WRITE_USER_MSG = 1; 243 static final int WRITE_USER_DELAY = 2*1000; // 2 seconds 244 245 // Tron counters 246 private static final String TRON_GUEST_CREATED = "users_guest_created"; 247 private static final String TRON_USER_CREATED = "users_user_created"; 248 private static final String TRON_DEMO_CREATED = "users_demo_created"; 249 250 private final Context mContext; 251 private final PackageManagerService mPm; 252 private final Object mPackagesLock; 253 private final UserDataPreparer mUserDataPreparer; 254 // Short-term lock for internal state, when interaction/sync with PM is not required 255 private final Object mUsersLock = LockGuard.installNewLock(LockGuard.INDEX_USER); 256 private final Object mRestrictionsLock = new Object(); 257 // Used for serializing access to app restriction files 258 private final Object mAppRestrictionsLock = new Object(); 259 260 private final Handler mHandler; 261 262 private final File mUsersDir; 263 private final File mUserListFile; 264 265 private static final IBinder mUserRestriconToken = new Binder(); 266 267 /** Installs system packages based on user-type. */ 268 private final UserSystemPackageInstaller mSystemPackageInstaller; 269 270 private PackageManagerInternal mPmInternal; 271 private CrossProfileAppsInternal mCrossProfileAppsInternal; 272 private DevicePolicyManagerInternal mDevicePolicyManagerInternal; 273 274 /** 275 * Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps. 276 */ 277 @VisibleForTesting 278 static class UserData { 279 // Basic user information and properties 280 UserInfo info; 281 // Account name used when there is a strong association between a user and an account 282 String account; 283 // Account information for seeding into a newly created user. This could also be 284 // used for login validation for an existing user, for updating their credentials. 285 // In the latter case, data may not need to be persisted as it is only valid for the 286 // current login session. 287 String seedAccountName; 288 String seedAccountType; 289 PersistableBundle seedAccountOptions; 290 // Whether to perist the seed account information to be available after a boot 291 boolean persistSeedData; 292 293 /** Elapsed realtime since boot when the user started. */ 294 long startRealtime; 295 296 /** Elapsed realtime since boot when the user was unlocked. */ 297 long unlockRealtime; 298 299 private long mLastRequestQuietModeEnabledMillis; 300 setLastRequestQuietModeEnabledMillis(long millis)301 void setLastRequestQuietModeEnabledMillis(long millis) { 302 mLastRequestQuietModeEnabledMillis = millis; 303 } 304 getLastRequestQuietModeEnabledMillis()305 long getLastRequestQuietModeEnabledMillis() { 306 return mLastRequestQuietModeEnabledMillis; 307 } 308 clearSeedAccountData()309 void clearSeedAccountData() { 310 seedAccountName = null; 311 seedAccountType = null; 312 seedAccountOptions = null; 313 persistSeedData = false; 314 } 315 } 316 317 @GuardedBy("mUsersLock") 318 private final SparseArray<UserData> mUsers = new SparseArray<>(); 319 320 /** 321 * Map of user type names to their corresponding {@link UserTypeDetails}. 322 * Should not be modified after UserManagerService constructor finishes. 323 */ 324 private final ArrayMap<String, UserTypeDetails> mUserTypes; 325 326 /** 327 * User restrictions set via UserManager. This doesn't include restrictions set by 328 * device owner / profile owners. Only non-empty restriction bundles are stored. 329 * 330 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 331 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 332 * maybe shared between {@link #mBaseUserRestrictions} and 333 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 334 * (Otherwise we won't be able to detect what restrictions have changed in 335 * {@link #updateUserRestrictionsInternalLR}. 336 */ 337 @GuardedBy("mRestrictionsLock") 338 private final RestrictionsSet mBaseUserRestrictions = new RestrictionsSet(); 339 340 /** 341 * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined 342 * with device / profile owner restrictions. We'll initialize it lazily; use 343 * {@link #getEffectiveUserRestrictions} to access it. 344 * 345 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 346 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 347 * maybe shared between {@link #mBaseUserRestrictions} and 348 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 349 * (Otherwise we won't be able to detect what restrictions have changed in 350 * {@link #updateUserRestrictionsInternalLR}. 351 */ 352 @GuardedBy("mRestrictionsLock") 353 private final RestrictionsSet mCachedEffectiveUserRestrictions = new RestrictionsSet(); 354 355 /** 356 * User restrictions that have already been applied in 357 * {@link #updateUserRestrictionsInternalLR(Bundle, int)}. We use it to detect restrictions 358 * that have changed since the last 359 * {@link #updateUserRestrictionsInternalLR(Bundle, int)} call. 360 */ 361 @GuardedBy("mRestrictionsLock") 362 private final RestrictionsSet mAppliedUserRestrictions = new RestrictionsSet(); 363 364 /** 365 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 366 * that should be applied to all users, including guests. Only non-empty restriction bundles are 367 * stored. 368 * The key is the user id of the user whom the restriction originated from. 369 */ 370 @GuardedBy("mRestrictionsLock") 371 private final RestrictionsSet mDevicePolicyGlobalUserRestrictions = new RestrictionsSet(); 372 373 /** 374 * Id of the user that set global restrictions. 375 */ 376 @GuardedBy("mRestrictionsLock") 377 private int mDeviceOwnerUserId = UserHandle.USER_NULL; 378 379 /** 380 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 381 * for each user. 382 * The key is the user id of the user whom the restrictions are targeting. 383 * The key inside the restrictionsSet is the user id of the user whom the restriction 384 * originated from. 385 * targetUserId -> originatingUserId -> restrictionBundle 386 */ 387 @GuardedBy("mRestrictionsLock") 388 private final SparseArray<RestrictionsSet> mDevicePolicyLocalUserRestrictions = 389 new SparseArray<>(); 390 391 @GuardedBy("mGuestRestrictions") 392 private final Bundle mGuestRestrictions = new Bundle(); 393 394 /** 395 * Set of user IDs being actively removed. Removed IDs linger in this set 396 * for several seconds to work around a VFS caching issue. 397 * Use {@link #addRemovingUserIdLocked(int)} to add elements to this array 398 */ 399 @GuardedBy("mUsersLock") 400 private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray(); 401 402 /** 403 * Queue of recently removed userIds. Used for recycling of userIds 404 */ 405 @GuardedBy("mUsersLock") 406 private final LinkedList<Integer> mRecentlyRemovedIds = new LinkedList<>(); 407 408 @GuardedBy("mUsersLock") 409 private int[] mUserIds; 410 411 @GuardedBy("mUsersLock") 412 private int[] mUserIdsIncludingPreCreated; 413 414 @GuardedBy("mPackagesLock") 415 private int mNextSerialNumber; 416 private int mUserVersion = 0; 417 418 private IAppOpsService mAppOpsService; 419 420 private final LocalService mLocalService; 421 422 @GuardedBy("mUsersLock") 423 private boolean mIsDeviceManaged; 424 425 @GuardedBy("mUsersLock") 426 private final SparseBooleanArray mIsUserManaged = new SparseBooleanArray(); 427 428 @GuardedBy("mUserRestrictionsListeners") 429 private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners = 430 new ArrayList<>(); 431 432 private final LockPatternUtils mLockPatternUtils; 433 434 private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK = 435 "com.android.server.pm.DISABLE_QUIET_MODE_AFTER_UNLOCK"; 436 437 private final BroadcastReceiver mDisableQuietModeCallback = new BroadcastReceiver() { 438 @Override 439 public void onReceive(Context context, Intent intent) { 440 if (!ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK.equals(intent.getAction())) { 441 return; 442 } 443 final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT); 444 final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); 445 // Call setQuietModeEnabled on bg thread to avoid ANR 446 BackgroundThread.getHandler().post(() -> 447 setQuietModeEnabled(userId, false, target, /* callingPackage */ null)); 448 } 449 }; 450 451 /** 452 * Start an {@link IntentSender} when user is unlocked after disabling quiet mode. 453 * 454 * @see #requestQuietModeEnabled(String, boolean, int, IntentSender, int) 455 */ 456 private class DisableQuietModeUserUnlockedCallback extends IProgressListener.Stub { 457 private final IntentSender mTarget; 458 DisableQuietModeUserUnlockedCallback(IntentSender target)459 public DisableQuietModeUserUnlockedCallback(IntentSender target) { 460 Objects.requireNonNull(target); 461 mTarget = target; 462 } 463 464 @Override onStarted(int id, Bundle extras)465 public void onStarted(int id, Bundle extras) {} 466 467 @Override onProgress(int id, int progress, Bundle extras)468 public void onProgress(int id, int progress, Bundle extras) {} 469 470 @Override onFinished(int id, Bundle extras)471 public void onFinished(int id, Bundle extras) { 472 mHandler.post(() -> { 473 try { 474 mContext.startIntentSender(mTarget, null, 0, 0, 0); 475 } catch (IntentSender.SendIntentException e) { 476 Slog.e(LOG_TAG, "Failed to start the target in the callback", e); 477 } 478 }); 479 } 480 } 481 482 /** 483 * Whether all users should be created ephemeral. 484 */ 485 @GuardedBy("mUsersLock") 486 private boolean mForceEphemeralUsers; 487 488 /** 489 * The member mUserStates affects the return value of isUserUnlocked. 490 * If any value in mUserStates changes, then the binder cache for 491 * isUserUnlocked must be invalidated. When adding mutating methods to 492 * WatchedUserStates, be sure to invalidate the cache in the new 493 * methods. 494 */ 495 private class WatchedUserStates { 496 final SparseIntArray states; WatchedUserStates()497 public WatchedUserStates() { 498 states = new SparseIntArray(); 499 invalidateIsUserUnlockedCache(); 500 } get(int userId)501 public int get(int userId) { 502 return states.get(userId); 503 } get(int userId, int fallback)504 public int get(int userId, int fallback) { 505 return states.indexOfKey(userId) >= 0 ? states.get(userId) : fallback; 506 } put(int userId, int state)507 public void put(int userId, int state) { 508 states.put(userId, state); 509 invalidateIsUserUnlockedCache(); 510 } delete(int userId)511 public void delete(int userId) { 512 states.delete(userId); 513 invalidateIsUserUnlockedCache(); 514 } 515 @Override toString()516 public String toString() { 517 return states.toString(); 518 } invalidateIsUserUnlockedCache()519 private void invalidateIsUserUnlockedCache() { 520 UserManager.invalidateIsUserUnlockedCache(); 521 } 522 } 523 @GuardedBy("mUserStates") 524 private final WatchedUserStates mUserStates = new WatchedUserStates(); 525 526 private static UserManagerService sInstance; 527 getInstance()528 public static UserManagerService getInstance() { 529 synchronized (UserManagerService.class) { 530 return sInstance; 531 } 532 } 533 534 public static class LifeCycle extends SystemService { 535 536 private UserManagerService mUms; 537 538 /** 539 * @param context 540 */ LifeCycle(Context context)541 public LifeCycle(Context context) { 542 super(context); 543 } 544 545 @Override onStart()546 public void onStart() { 547 mUms = UserManagerService.getInstance(); 548 publishBinderService(Context.USER_SERVICE, mUms); 549 } 550 551 @Override onBootPhase(int phase)552 public void onBootPhase(int phase) { 553 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 554 mUms.cleanupPartialUsers(); 555 556 if (mUms.mPm.isDeviceUpgrading()) { 557 mUms.cleanupPreCreatedUsers(); 558 } 559 } 560 } 561 562 @Override onStartUser(@serIdInt int userId)563 public void onStartUser(@UserIdInt int userId) { 564 synchronized (mUms.mUsersLock) { 565 final UserData user = mUms.getUserDataLU(userId); 566 if (user != null) { 567 user.startRealtime = SystemClock.elapsedRealtime(); 568 } 569 } 570 } 571 572 @Override onUnlockUser(@serIdInt int userId)573 public void onUnlockUser(@UserIdInt int userId) { 574 synchronized (mUms.mUsersLock) { 575 final UserData user = mUms.getUserDataLU(userId); 576 if (user != null) { 577 user.unlockRealtime = SystemClock.elapsedRealtime(); 578 } 579 } 580 } 581 582 @Override onStopUser(@serIdInt int userId)583 public void onStopUser(@UserIdInt int userId) { 584 synchronized (mUms.mUsersLock) { 585 final UserData user = mUms.getUserDataLU(userId); 586 if (user != null) { 587 user.startRealtime = 0; 588 user.unlockRealtime = 0; 589 } 590 } 591 } 592 } 593 594 // TODO b/28848102 Add support for test dependencies injection 595 @VisibleForTesting UserManagerService(Context context)596 UserManagerService(Context context) { 597 this(context, null, null, new Object(), context.getCacheDir()); 598 } 599 600 /** 601 * Called by package manager to create the service. This is closely 602 * associated with the package manager, and the given lock is the 603 * package manager's own lock. 604 */ UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock)605 UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, 606 Object packagesLock) { 607 this(context, pm, userDataPreparer, packagesLock, Environment.getDataDirectory()); 608 } 609 UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock, File dataDir)610 private UserManagerService(Context context, PackageManagerService pm, 611 UserDataPreparer userDataPreparer, Object packagesLock, File dataDir) { 612 mContext = context; 613 mPm = pm; 614 mPackagesLock = packagesLock; 615 mHandler = new MainHandler(); 616 mUserDataPreparer = userDataPreparer; 617 mUserTypes = UserTypeFactory.getUserTypes(); 618 synchronized (mPackagesLock) { 619 mUsersDir = new File(dataDir, USER_INFO_DIR); 620 mUsersDir.mkdirs(); 621 // Make zeroth user directory, for services to migrate their files to that location 622 File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM)); 623 userZeroDir.mkdirs(); 624 FileUtils.setPermissions(mUsersDir.toString(), 625 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, 626 -1, -1); 627 mUserListFile = new File(mUsersDir, USER_LIST_FILENAME); 628 initDefaultGuestRestrictions(); 629 readUserListLP(); 630 sInstance = this; 631 } 632 mSystemPackageInstaller = new UserSystemPackageInstaller(this, mUserTypes); 633 mLocalService = new LocalService(); 634 LocalServices.addService(UserManagerInternal.class, mLocalService); 635 mLockPatternUtils = new LockPatternUtils(mContext); 636 mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING); 637 } 638 systemReady()639 void systemReady() { 640 mAppOpsService = IAppOpsService.Stub.asInterface( 641 ServiceManager.getService(Context.APP_OPS_SERVICE)); 642 643 synchronized (mRestrictionsLock) { 644 applyUserRestrictionsLR(UserHandle.USER_SYSTEM); 645 } 646 647 mContext.registerReceiver(mDisableQuietModeCallback, 648 new IntentFilter(ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK), 649 null, mHandler); 650 } 651 652 /** 653 * This method retrieves the {@link UserManagerInternal} only for the purpose of 654 * PackageManagerService construction. 655 */ getInternalForInjectorOnly()656 UserManagerInternal getInternalForInjectorOnly() { 657 return mLocalService; 658 } 659 cleanupPartialUsers()660 void cleanupPartialUsers() { 661 // Prune out any partially created, partially removed and ephemeral users. 662 ArrayList<UserInfo> partials = new ArrayList<>(); 663 synchronized (mUsersLock) { 664 final int userSize = mUsers.size(); 665 for (int i = 0; i < userSize; i++) { 666 UserInfo ui = mUsers.valueAt(i).info; 667 if ((ui.partial || ui.guestToRemove || (ui.isEphemeral() && !ui.preCreated)) 668 && i != 0) { 669 partials.add(ui); 670 addRemovingUserIdLocked(ui.id); 671 ui.partial = true; 672 } 673 } 674 } 675 final int partialsSize = partials.size(); 676 for (int i = 0; i < partialsSize; i++) { 677 UserInfo ui = partials.get(i); 678 Slog.w(LOG_TAG, "Removing partially created user " + ui.id 679 + " (name=" + ui.name + ")"); 680 removeUserState(ui.id); 681 } 682 } 683 684 /** 685 * Removes any pre-created users from the system. Should be invoked after OTAs, to ensure 686 * pre-created users are not stale. New pre-created pool can be re-created after the update. 687 */ cleanupPreCreatedUsers()688 void cleanupPreCreatedUsers() { 689 final ArrayList<UserInfo> preCreatedUsers; 690 synchronized (mUsersLock) { 691 final int userSize = mUsers.size(); 692 preCreatedUsers = new ArrayList<>(userSize); 693 for (int i = 0; i < userSize; i++) { 694 UserInfo ui = mUsers.valueAt(i).info; 695 if (ui.preCreated) { 696 preCreatedUsers.add(ui); 697 addRemovingUserIdLocked(ui.id); 698 ui.flags |= UserInfo.FLAG_DISABLED; 699 ui.partial = true; 700 } 701 } 702 } 703 final int preCreatedSize = preCreatedUsers.size(); 704 for (int i = 0; i < preCreatedSize; i++) { 705 UserInfo ui = preCreatedUsers.get(i); 706 Slog.i(LOG_TAG, "Removing pre-created user " + ui.id); 707 removeUserState(ui.id); 708 } 709 } 710 711 @Override getUserAccount(@serIdInt int userId)712 public String getUserAccount(@UserIdInt int userId) { 713 checkManageUserAndAcrossUsersFullPermission("get user account"); 714 synchronized (mUsersLock) { 715 return mUsers.get(userId).account; 716 } 717 } 718 719 @Override setUserAccount(@serIdInt int userId, String accountName)720 public void setUserAccount(@UserIdInt int userId, String accountName) { 721 checkManageUserAndAcrossUsersFullPermission("set user account"); 722 UserData userToUpdate = null; 723 synchronized (mPackagesLock) { 724 synchronized (mUsersLock) { 725 final UserData userData = mUsers.get(userId); 726 if (userData == null) { 727 Slog.e(LOG_TAG, "User not found for setting user account: u" + userId); 728 return; 729 } 730 String currentAccount = userData.account; 731 if (!Objects.equals(currentAccount, accountName)) { 732 userData.account = accountName; 733 userToUpdate = userData; 734 } 735 } 736 737 if (userToUpdate != null) { 738 writeUserLP(userToUpdate); 739 } 740 } 741 } 742 743 @Override getPrimaryUser()744 public UserInfo getPrimaryUser() { 745 checkManageUsersPermission("query users"); 746 synchronized (mUsersLock) { 747 final int userSize = mUsers.size(); 748 for (int i = 0; i < userSize; i++) { 749 UserInfo ui = mUsers.valueAt(i).info; 750 if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) { 751 return ui; 752 } 753 } 754 } 755 return null; 756 } 757 getUsers(boolean excludeDying)758 public @NonNull List<UserInfo> getUsers(boolean excludeDying) { 759 return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ 760 true); 761 } 762 763 @Override getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)764 public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, 765 boolean excludePreCreated) { 766 checkManageOrCreateUsersPermission("query users"); 767 return getUsersInternal(excludePartial, excludeDying, excludePreCreated); 768 } 769 getUsersInternal(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)770 private @NonNull List<UserInfo> getUsersInternal(boolean excludePartial, boolean excludeDying, 771 boolean excludePreCreated) { 772 synchronized (mUsersLock) { 773 ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size()); 774 final int userSize = mUsers.size(); 775 for (int i = 0; i < userSize; i++) { 776 UserInfo ui = mUsers.valueAt(i).info; 777 if ((excludePartial && ui.partial) 778 || (excludeDying && mRemovingUserIds.get(ui.id)) 779 || (excludePreCreated && ui.preCreated)) { 780 continue; 781 } 782 users.add(userWithName(ui)); 783 } 784 return users; 785 } 786 } 787 788 @Override getProfiles(@serIdInt int userId, boolean enabledOnly)789 public List<UserInfo> getProfiles(@UserIdInt int userId, boolean enabledOnly) { 790 boolean returnFullInfo = true; 791 if (userId != UserHandle.getCallingUserId()) { 792 checkManageOrCreateUsersPermission("getting profiles related to user " + userId); 793 } else { 794 returnFullInfo = hasManageUsersPermission(); 795 } 796 final long ident = Binder.clearCallingIdentity(); 797 try { 798 synchronized (mUsersLock) { 799 return getProfilesLU(userId, /* userType */ null, enabledOnly, returnFullInfo); 800 } 801 } finally { 802 Binder.restoreCallingIdentity(ident); 803 } 804 } 805 806 // TODO(b/142482943): Will probably need a getProfiles(userType). But permissions may vary. 807 808 @Override getProfileIds(@serIdInt int userId, boolean enabledOnly)809 public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) { 810 return getProfileIds(userId, null, enabledOnly); 811 } 812 813 // TODO(b/142482943): Probably @Override and make this accessible in UserManager. 814 /** 815 * Returns all the users of type userType that are in the same profile group as userId 816 * (including userId itself, if it is of the appropriate user type). 817 * 818 * <p>If userType is non-{@code null}, only returns users that are of type userType. 819 * If enabledOnly, only returns users that are not {@link UserInfo#FLAG_DISABLED}. 820 */ getProfileIds(@serIdInt int userId, @Nullable String userType, boolean enabledOnly)821 public int[] getProfileIds(@UserIdInt int userId, @Nullable String userType, 822 boolean enabledOnly) { 823 if (userId != UserHandle.getCallingUserId()) { 824 checkManageOrCreateUsersPermission("getting profiles related to user " + userId); 825 } 826 final long ident = Binder.clearCallingIdentity(); 827 try { 828 synchronized (mUsersLock) { 829 return getProfileIdsLU(userId, userType, enabledOnly).toArray(); 830 } 831 } finally { 832 Binder.restoreCallingIdentity(ident); 833 } 834 } 835 836 /** Assume permissions already checked and caller's identity cleared */ 837 @GuardedBy("mUsersLock") getProfilesLU(@serIdInt int userId, @Nullable String userType, boolean enabledOnly, boolean fullInfo)838 private List<UserInfo> getProfilesLU(@UserIdInt int userId, @Nullable String userType, 839 boolean enabledOnly, boolean fullInfo) { 840 IntArray profileIds = getProfileIdsLU(userId, userType, enabledOnly); 841 ArrayList<UserInfo> users = new ArrayList<>(profileIds.size()); 842 for (int i = 0; i < profileIds.size(); i++) { 843 int profileId = profileIds.get(i); 844 UserInfo userInfo = mUsers.get(profileId).info; 845 // If full info is not required - clear PII data to prevent 3P apps from reading it 846 if (!fullInfo) { 847 userInfo = new UserInfo(userInfo); 848 userInfo.name = null; 849 userInfo.iconPath = null; 850 } else { 851 userInfo = userWithName(userInfo); 852 } 853 users.add(userInfo); 854 } 855 return users; 856 } 857 858 /** 859 * Assume permissions already checked and caller's identity cleared 860 * <p>If userType is {@code null}, returns all profiles for user; else, only returns 861 * profiles of that type. 862 */ 863 @GuardedBy("mUsersLock") getProfileIdsLU(@serIdInt int userId, @Nullable String userType, boolean enabledOnly)864 private IntArray getProfileIdsLU(@UserIdInt int userId, @Nullable String userType, 865 boolean enabledOnly) { 866 UserInfo user = getUserInfoLU(userId); 867 IntArray result = new IntArray(mUsers.size()); 868 if (user == null) { 869 // Probably a dying user 870 return result; 871 } 872 final int userSize = mUsers.size(); 873 for (int i = 0; i < userSize; i++) { 874 UserInfo profile = mUsers.valueAt(i).info; 875 if (!isProfileOf(user, profile)) { 876 continue; 877 } 878 if (enabledOnly && !profile.isEnabled()) { 879 continue; 880 } 881 if (mRemovingUserIds.get(profile.id)) { 882 continue; 883 } 884 if (profile.partial) { 885 continue; 886 } 887 if (userType != null && !userType.equals(profile.userType)) { 888 continue; 889 } 890 result.add(profile.id); 891 } 892 return result; 893 } 894 895 @Override getCredentialOwnerProfile(@serIdInt int userId)896 public int getCredentialOwnerProfile(@UserIdInt int userId) { 897 checkManageUsersPermission("get the credential owner"); 898 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { 899 synchronized (mUsersLock) { 900 UserInfo profileParent = getProfileParentLU(userId); 901 if (profileParent != null) { 902 return profileParent.id; 903 } 904 } 905 } 906 907 return userId; 908 } 909 910 @Override isSameProfileGroup(@serIdInt int userId, int otherUserId)911 public boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) { 912 if (userId == otherUserId) return true; 913 checkManageUsersPermission("check if in the same profile group"); 914 return isSameProfileGroupNoChecks(userId, otherUserId); 915 } 916 isSameProfileGroupNoChecks(@serIdInt int userId, int otherUserId)917 private boolean isSameProfileGroupNoChecks(@UserIdInt int userId, int otherUserId) { 918 synchronized (mUsersLock) { 919 UserInfo userInfo = getUserInfoLU(userId); 920 if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 921 return false; 922 } 923 UserInfo otherUserInfo = getUserInfoLU(otherUserId); 924 if (otherUserInfo == null 925 || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 926 return false; 927 } 928 return userInfo.profileGroupId == otherUserInfo.profileGroupId; 929 } 930 } 931 932 @Override getProfileParent(@serIdInt int userId)933 public UserInfo getProfileParent(@UserIdInt int userId) { 934 checkManageUsersPermission("get the profile parent"); 935 synchronized (mUsersLock) { 936 return getProfileParentLU(userId); 937 } 938 } 939 940 @Override getProfileParentId(@serIdInt int userId)941 public int getProfileParentId(@UserIdInt int userId) { 942 checkManageUsersPermission("get the profile parent"); 943 return mLocalService.getProfileParentId(userId); 944 } 945 946 @GuardedBy("mUsersLock") getProfileParentLU(@serIdInt int userId)947 private UserInfo getProfileParentLU(@UserIdInt int userId) { 948 UserInfo profile = getUserInfoLU(userId); 949 if (profile == null) { 950 return null; 951 } 952 int parentUserId = profile.profileGroupId; 953 if (parentUserId == userId || parentUserId == UserInfo.NO_PROFILE_GROUP_ID) { 954 return null; 955 } else { 956 return getUserInfoLU(parentUserId); 957 } 958 } 959 isProfileOf(UserInfo user, UserInfo profile)960 private static boolean isProfileOf(UserInfo user, UserInfo profile) { 961 return user.id == profile.id || 962 (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 963 && user.profileGroupId == profile.profileGroupId); 964 } 965 broadcastProfileAvailabilityChanges(UserHandle profileHandle, UserHandle parentHandle, boolean inQuietMode)966 private void broadcastProfileAvailabilityChanges(UserHandle profileHandle, 967 UserHandle parentHandle, boolean inQuietMode) { 968 Intent intent = new Intent(); 969 if (inQuietMode) { 970 intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); 971 } else { 972 intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); 973 } 974 intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); 975 intent.putExtra(Intent.EXTRA_USER, profileHandle); 976 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); 977 getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser( 978 intent, parentHandle, /* requiresPermission= */ true); 979 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 980 mContext.sendBroadcastAsUser(intent, parentHandle); 981 } 982 983 @Override requestQuietModeEnabled(@onNull String callingPackage, boolean enableQuietMode, @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags)984 public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode, 985 @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags) { 986 Objects.requireNonNull(callingPackage); 987 988 if (enableQuietMode && target != null) { 989 throw new IllegalArgumentException( 990 "target should only be specified when we are disabling quiet mode."); 991 } 992 993 final boolean dontAskCredential = 994 (flags & UserManager.QUIET_MODE_DISABLE_DONT_ASK_CREDENTIAL) != 0; 995 final boolean onlyIfCredentialNotRequired = 996 (flags & UserManager.QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED) != 0; 997 if (dontAskCredential && onlyIfCredentialNotRequired) { 998 throw new IllegalArgumentException("invalid flags: " + flags); 999 } 1000 1001 ensureCanModifyQuietMode( 1002 callingPackage, Binder.getCallingUid(), userId, target != null, dontAskCredential); 1003 1004 if (onlyIfCredentialNotRequired && callingPackage.equals( 1005 getPackageManagerInternal().getSystemUiServiceComponent().getPackageName())) { 1006 // This is to prevent SysUI from accidentally allowing the profile to turned on 1007 // without password when keyguard is still locked. 1008 throw new SecurityException("SystemUI is not allowed to set " 1009 + "QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED"); 1010 } 1011 1012 final long identity = Binder.clearCallingIdentity(); 1013 try { 1014 if (enableQuietMode) { 1015 setQuietModeEnabled( 1016 userId, true /* enableQuietMode */, target, callingPackage); 1017 return true; 1018 } 1019 if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(userId)) { 1020 KeyguardManager km = mContext.getSystemService(KeyguardManager.class); 1021 // Normally only attempt to auto-unlock unified challenge if keyguard is not showing 1022 // (to stop turning profile on automatically via the QS tile), except when we 1023 // are called with QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED, in which 1024 // case always attempt to auto-unlock. 1025 if (!km.isDeviceLocked(mLocalService.getProfileParentId(userId)) 1026 || onlyIfCredentialNotRequired) { 1027 mLockPatternUtils.tryUnlockWithCachedUnifiedChallenge(userId); 1028 } 1029 } 1030 final boolean needToShowConfirmCredential = !dontAskCredential 1031 && mLockPatternUtils.isSecure(userId) 1032 && !StorageManager.isUserKeyUnlocked(userId); 1033 if (needToShowConfirmCredential) { 1034 if (onlyIfCredentialNotRequired) { 1035 return false; 1036 } 1037 showConfirmCredentialToDisableQuietMode(userId, target); 1038 return false; 1039 } 1040 setQuietModeEnabled(userId, false /* enableQuietMode */, target, callingPackage); 1041 return true; 1042 } finally { 1043 Binder.restoreCallingIdentity(identity); 1044 } 1045 } 1046 1047 /** 1048 * The caller can modify quiet mode if it meets one of these conditions: 1049 * <ul> 1050 * <li>Has system UID or root UID</li> 1051 * <li>Has {@link Manifest.permission#MODIFY_QUIET_MODE}</li> 1052 * <li>Has {@link Manifest.permission#MANAGE_USERS}</li> 1053 * <li>Is the foreground default launcher app</li> 1054 * </ul> 1055 * <p> 1056 * If caller wants to start an intent after disabling the quiet mode, or if it is targeting a 1057 * user in a different profile group from the caller, it must have 1058 * {@link Manifest.permission#MANAGE_USERS}. 1059 */ ensureCanModifyQuietMode(String callingPackage, int callingUid, @UserIdInt int targetUserId, boolean startIntent, boolean dontAskCredential)1060 private void ensureCanModifyQuietMode(String callingPackage, int callingUid, 1061 @UserIdInt int targetUserId, boolean startIntent, boolean dontAskCredential) { 1062 verifyCallingPackage(callingPackage, callingUid); 1063 1064 if (hasManageUsersPermission()) { 1065 return; 1066 } 1067 if (startIntent) { 1068 throw new SecurityException("MANAGE_USERS permission is required to start intent " 1069 + "after disabling quiet mode."); 1070 } 1071 if (dontAskCredential) { 1072 throw new SecurityException("MANAGE_USERS permission is required to disable quiet " 1073 + "mode without credentials."); 1074 } 1075 if (!isSameProfileGroupNoChecks(UserHandle.getUserId(callingUid), targetUserId)) { 1076 throw new SecurityException("MANAGE_USERS permission is required to modify quiet mode " 1077 + "for a different profile group."); 1078 } 1079 final boolean hasModifyQuietModePermission = hasPermissionGranted( 1080 Manifest.permission.MODIFY_QUIET_MODE, callingUid); 1081 if (hasModifyQuietModePermission) { 1082 return; 1083 } 1084 1085 final ShortcutServiceInternal shortcutInternal = 1086 LocalServices.getService(ShortcutServiceInternal.class); 1087 if (shortcutInternal != null) { 1088 boolean isForegroundLauncher = 1089 shortcutInternal.isForegroundDefaultLauncher(callingPackage, callingUid); 1090 if (isForegroundLauncher) { 1091 return; 1092 } 1093 } 1094 throw new SecurityException("Can't modify quiet mode, caller is neither foreground " 1095 + "default launcher nor has MANAGE_USERS/MODIFY_QUIET_MODE permission"); 1096 } 1097 setQuietModeEnabled(@serIdInt int userId, boolean enableQuietMode, IntentSender target, @Nullable String callingPackage)1098 private void setQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode, 1099 IntentSender target, @Nullable String callingPackage) { 1100 final UserInfo profile, parent; 1101 final UserData profileUserData; 1102 synchronized (mUsersLock) { 1103 profile = getUserInfoLU(userId); 1104 parent = getProfileParentLU(userId); 1105 1106 if (profile == null || !profile.isManagedProfile()) { 1107 throw new IllegalArgumentException("User " + userId + " is not a profile"); 1108 } 1109 if (profile.isQuietModeEnabled() == enableQuietMode) { 1110 Slog.i(LOG_TAG, "Quiet mode is already " + enableQuietMode); 1111 return; 1112 } 1113 profile.flags ^= UserInfo.FLAG_QUIET_MODE; 1114 profileUserData = getUserDataLU(profile.id); 1115 } 1116 synchronized (mPackagesLock) { 1117 writeUserLP(profileUserData); 1118 } 1119 try { 1120 if (enableQuietMode) { 1121 ActivityManager.getService().stopUser(userId, /* force */true, null); 1122 LocalServices.getService(ActivityManagerInternal.class) 1123 .killForegroundAppsForUser(userId); 1124 } else { 1125 IProgressListener callback = target != null 1126 ? new DisableQuietModeUserUnlockedCallback(target) 1127 : null; 1128 ActivityManager.getService().startUserInBackgroundWithListener( 1129 userId, callback); 1130 } 1131 logQuietModeEnabled(userId, enableQuietMode, callingPackage); 1132 } catch (RemoteException e) { 1133 // Should not happen, same process. 1134 e.rethrowAsRuntimeException(); 1135 } 1136 broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(), 1137 enableQuietMode); 1138 } 1139 logQuietModeEnabled(@serIdInt int userId, boolean enableQuietMode, @Nullable String callingPackage)1140 private void logQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode, 1141 @Nullable String callingPackage) { 1142 UserData userData; 1143 synchronized (mUsersLock) { 1144 userData = getUserDataLU(userId); 1145 } 1146 if (userData == null) { 1147 return; 1148 } 1149 final long now = System.currentTimeMillis(); 1150 final long period = (userData.getLastRequestQuietModeEnabledMillis() != 0L 1151 ? now - userData.getLastRequestQuietModeEnabledMillis() 1152 : now - userData.info.creationTime); 1153 DevicePolicyEventLogger 1154 .createEvent(DevicePolicyEnums.REQUEST_QUIET_MODE_ENABLED) 1155 .setStrings(callingPackage) 1156 .setBoolean(enableQuietMode) 1157 .setTimePeriod(period) 1158 .write(); 1159 userData.setLastRequestQuietModeEnabledMillis(now); 1160 } 1161 1162 @Override isQuietModeEnabled(@serIdInt int userId)1163 public boolean isQuietModeEnabled(@UserIdInt int userId) { 1164 synchronized (mPackagesLock) { 1165 UserInfo info; 1166 synchronized (mUsersLock) { 1167 info = getUserInfoLU(userId); 1168 } 1169 if (info == null || !info.isManagedProfile()) { 1170 return false; 1171 } 1172 return info.isQuietModeEnabled(); 1173 } 1174 } 1175 1176 /** 1177 * Show confirm credential screen to unlock user in order to turn off quiet mode. 1178 */ showConfirmCredentialToDisableQuietMode( @serIdInt int userId, @Nullable IntentSender target)1179 private void showConfirmCredentialToDisableQuietMode( 1180 @UserIdInt int userId, @Nullable IntentSender target) { 1181 // otherwise, we show a profile challenge to trigger decryption of the user 1182 final KeyguardManager km = (KeyguardManager) mContext.getSystemService( 1183 Context.KEYGUARD_SERVICE); 1184 // We should use userId not credentialOwnerUserId here, as even if it is unified 1185 // lock, confirm screenlock page will know and show personal challenge, and unlock 1186 // work profile when personal challenge is correct 1187 final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, userId); 1188 if (unlockIntent == null) { 1189 return; 1190 } 1191 final Intent callBackIntent = new Intent( 1192 ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK); 1193 if (target != null) { 1194 callBackIntent.putExtra(Intent.EXTRA_INTENT, target); 1195 } 1196 callBackIntent.putExtra(Intent.EXTRA_USER_ID, userId); 1197 callBackIntent.setPackage(mContext.getPackageName()); 1198 callBackIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1199 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 1200 mContext, 1201 0, 1202 callBackIntent, 1203 PendingIntent.FLAG_CANCEL_CURRENT | 1204 PendingIntent.FLAG_ONE_SHOT | 1205 PendingIntent.FLAG_IMMUTABLE); 1206 // After unlocking the challenge, it will disable quiet mode and run the original 1207 // intentSender 1208 unlockIntent.putExtra(Intent.EXTRA_INTENT, pendingIntent.getIntentSender()); 1209 unlockIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 1210 mContext.startActivity(unlockIntent); 1211 } 1212 1213 @Override setUserEnabled(@serIdInt int userId)1214 public void setUserEnabled(@UserIdInt int userId) { 1215 checkManageUsersPermission("enable user"); 1216 synchronized (mPackagesLock) { 1217 UserInfo info; 1218 synchronized (mUsersLock) { 1219 info = getUserInfoLU(userId); 1220 } 1221 if (info != null && !info.isEnabled()) { 1222 info.flags ^= UserInfo.FLAG_DISABLED; 1223 writeUserLP(getUserDataLU(info.id)); 1224 } 1225 } 1226 } 1227 1228 @Override setUserAdmin(@serIdInt int userId)1229 public void setUserAdmin(@UserIdInt int userId) { 1230 checkManageUserAndAcrossUsersFullPermission("set user admin"); 1231 1232 synchronized (mPackagesLock) { 1233 UserInfo info; 1234 synchronized (mUsersLock) { 1235 info = getUserInfoLU(userId); 1236 } 1237 if (info == null || info.isAdmin()) { 1238 // Exit if no user found with that id, or the user is already an Admin. 1239 return; 1240 } 1241 1242 info.flags ^= UserInfo.FLAG_ADMIN; 1243 writeUserLP(getUserDataLU(info.id)); 1244 } 1245 } 1246 1247 /** 1248 * Evicts a user's CE key by stopping and restarting the user. 1249 * 1250 * The key is evicted automatically by the user controller when the user has stopped. 1251 */ 1252 @Override evictCredentialEncryptionKey(@serIdInt int userId)1253 public void evictCredentialEncryptionKey(@UserIdInt int userId) { 1254 checkManageUsersPermission("evict CE key"); 1255 final IActivityManager am = ActivityManagerNative.getDefault(); 1256 final long identity = Binder.clearCallingIdentity(); 1257 try { 1258 am.restartUserInBackground(userId); 1259 } catch (RemoteException re) { 1260 throw re.rethrowAsRuntimeException(); 1261 } finally { 1262 Binder.restoreCallingIdentity(identity); 1263 } 1264 } 1265 1266 /** 1267 * Returns whether the given user (specified by userId) is of the given user type, such as 1268 * {@link UserManager#USER_TYPE_FULL_GUEST}. 1269 */ 1270 @Override isUserOfType(@serIdInt int userId, String userType)1271 public boolean isUserOfType(@UserIdInt int userId, String userType) { 1272 checkManageUsersPermission("check user type"); 1273 return userType != null && userType.equals(getUserTypeNoChecks(userId)); 1274 } 1275 1276 /** 1277 * Returns the user type of the given userId, or null if the user doesn't exist. 1278 * <p>No permissions checks are made (but userId checks may be made). 1279 */ getUserTypeNoChecks(@serIdInt int userId)1280 private @Nullable String getUserTypeNoChecks(@UserIdInt int userId) { 1281 synchronized (mUsersLock) { 1282 final UserInfo userInfo = getUserInfoLU(userId); 1283 return userInfo != null ? userInfo.userType : null; 1284 } 1285 } 1286 1287 /** 1288 * Returns the UserTypeDetails of the given userId's user type, or null if the no such user. 1289 * <p>No permissions checks are made (but userId checks may be made). 1290 */ getUserTypeDetailsNoChecks(@serIdInt int userId)1291 private @Nullable UserTypeDetails getUserTypeDetailsNoChecks(@UserIdInt int userId) { 1292 final String typeStr = getUserTypeNoChecks(userId); 1293 return typeStr != null ? mUserTypes.get(typeStr) : null; 1294 } 1295 1296 /** 1297 * Returns the UserTypeDetails of the given userInfo's user type (or null for a null userInfo). 1298 */ getUserTypeDetails(@ullable UserInfo userInfo)1299 private @Nullable UserTypeDetails getUserTypeDetails(@Nullable UserInfo userInfo) { 1300 final String typeStr = userInfo != null ? userInfo.userType : null; 1301 return typeStr != null ? mUserTypes.get(typeStr) : null; 1302 } 1303 1304 @Override getUserInfo(@serIdInt int userId)1305 public UserInfo getUserInfo(@UserIdInt int userId) { 1306 checkManageOrCreateUsersPermission("query user"); 1307 synchronized (mUsersLock) { 1308 return userWithName(getUserInfoLU(userId)); 1309 } 1310 } 1311 1312 /** 1313 * Returns a UserInfo object with the name filled in, for Owner, or the original 1314 * if the name is already set. 1315 */ userWithName(UserInfo orig)1316 private UserInfo userWithName(UserInfo orig) { 1317 if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) { 1318 UserInfo withName = new UserInfo(orig); 1319 withName.name = getOwnerName(); 1320 return withName; 1321 } else { 1322 return orig; 1323 } 1324 } 1325 1326 /** Returns whether the given user type is one of the FULL user types. */ isUserTypeSubtypeOfFull(String userType)1327 boolean isUserTypeSubtypeOfFull(String userType) { 1328 UserTypeDetails userTypeDetails = mUserTypes.get(userType); 1329 return userTypeDetails != null && userTypeDetails.isFull(); 1330 } 1331 1332 /** Returns whether the given user type is one of the PROFILE user types. */ isUserTypeSubtypeOfProfile(String userType)1333 boolean isUserTypeSubtypeOfProfile(String userType) { 1334 UserTypeDetails userTypeDetails = mUserTypes.get(userType); 1335 return userTypeDetails != null && userTypeDetails.isProfile(); 1336 } 1337 1338 /** Returns whether the given user type is one of the SYSTEM user types. */ isUserTypeSubtypeOfSystem(String userType)1339 boolean isUserTypeSubtypeOfSystem(String userType) { 1340 UserTypeDetails userTypeDetails = mUserTypes.get(userType); 1341 return userTypeDetails != null && userTypeDetails.isSystem(); 1342 } 1343 1344 @Override hasBadge(@serIdInt int userId)1345 public boolean hasBadge(@UserIdInt int userId) { 1346 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "hasBadge"); 1347 final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId); 1348 return userTypeDetails != null && userTypeDetails.hasBadge(); 1349 } 1350 1351 @Override getUserBadgeLabelResId(@serIdInt int userId)1352 public @StringRes int getUserBadgeLabelResId(@UserIdInt int userId) { 1353 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, 1354 "getUserBadgeLabelResId"); 1355 final UserInfo userInfo = getUserInfoNoChecks(userId); 1356 final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo); 1357 if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) { 1358 Slog.e(LOG_TAG, "Requested badge label for non-badged user " + userId); 1359 return Resources.ID_NULL; 1360 } 1361 final int badgeIndex = userInfo.profileBadge; 1362 return userTypeDetails.getBadgeLabel(badgeIndex); 1363 } 1364 1365 /** 1366 * @return the color (not the resource ID) to be used for the user's badge in light theme 1367 */ 1368 @Override getUserBadgeColorResId(@serIdInt int userId)1369 public @ColorRes int getUserBadgeColorResId(@UserIdInt int userId) { 1370 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, 1371 "getUserBadgeColorResId"); 1372 final UserInfo userInfo = getUserInfoNoChecks(userId); 1373 final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo); 1374 if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) { 1375 Slog.e(LOG_TAG, "Requested badge dark color for non-badged user " + userId); 1376 return Resources.ID_NULL; 1377 } 1378 return userTypeDetails.getBadgeColor(userInfo.profileBadge); 1379 } 1380 1381 /** 1382 * @return the color (not the resource ID) to be used for the user's badge in dark theme 1383 */ 1384 @Override getUserBadgeDarkColorResId(@serIdInt int userId)1385 public @ColorRes int getUserBadgeDarkColorResId(@UserIdInt int userId) { 1386 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, 1387 "getUserBadgeDarkColorResId"); 1388 final UserInfo userInfo = getUserInfoNoChecks(userId); 1389 final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo); 1390 if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) { 1391 Slog.e(LOG_TAG, "Requested badge color for non-badged user " + userId); 1392 return Resources.ID_NULL; 1393 } 1394 return userTypeDetails.getDarkThemeBadgeColor(userInfo.profileBadge); 1395 } 1396 1397 @Override getUserIconBadgeResId(@serIdInt int userId)1398 public @DrawableRes int getUserIconBadgeResId(@UserIdInt int userId) { 1399 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserIconBadgeResId"); 1400 final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId); 1401 if (userTypeDetails == null || !userTypeDetails.hasBadge()) { 1402 Slog.e(LOG_TAG, "Requested icon badge for non-badged user " + userId); 1403 return Resources.ID_NULL; 1404 } 1405 return userTypeDetails.getIconBadge(); 1406 } 1407 1408 @Override getUserBadgeResId(@serIdInt int userId)1409 public @DrawableRes int getUserBadgeResId(@UserIdInt int userId) { 1410 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserBadgeResId"); 1411 final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId); 1412 if (userTypeDetails == null || !userTypeDetails.hasBadge()) { 1413 Slog.e(LOG_TAG, "Requested badge for non-badged user " + userId); 1414 return Resources.ID_NULL; 1415 } 1416 return userTypeDetails.getBadgePlain(); 1417 } 1418 1419 @Override getUserBadgeNoBackgroundResId(@serIdInt int userId)1420 public @DrawableRes int getUserBadgeNoBackgroundResId(@UserIdInt int userId) { 1421 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, 1422 "getUserBadgeNoBackgroundResId"); 1423 final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId); 1424 if (userTypeDetails == null || !userTypeDetails.hasBadge()) { 1425 Slog.e(LOG_TAG, "Requested badge (no background) for non-badged user " + userId); 1426 return Resources.ID_NULL; 1427 } 1428 return userTypeDetails.getBadgeNoBackground(); 1429 } 1430 1431 @Override isProfile(@serIdInt int userId)1432 public boolean isProfile(@UserIdInt int userId) { 1433 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isProfile"); 1434 synchronized (mUsersLock) { 1435 UserInfo userInfo = getUserInfoLU(userId); 1436 return userInfo != null && userInfo.isProfile(); 1437 } 1438 } 1439 1440 @Override isManagedProfile(@serIdInt int userId)1441 public boolean isManagedProfile(@UserIdInt int userId) { 1442 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isManagedProfile"); 1443 synchronized (mUsersLock) { 1444 UserInfo userInfo = getUserInfoLU(userId); 1445 return userInfo != null && userInfo.isManagedProfile(); 1446 } 1447 } 1448 1449 @Override isUserUnlockingOrUnlocked(@serIdInt int userId)1450 public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) { 1451 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, 1452 "isUserUnlockingOrUnlocked"); 1453 return mLocalService.isUserUnlockingOrUnlocked(userId); 1454 } 1455 1456 @Override isUserUnlocked(@serIdInt int userId)1457 public boolean isUserUnlocked(@UserIdInt int userId) { 1458 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isUserUnlocked"); 1459 return mLocalService.isUserUnlocked(userId); 1460 } 1461 1462 @Override isUserRunning(@serIdInt int userId)1463 public boolean isUserRunning(@UserIdInt int userId) { 1464 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isUserRunning"); 1465 return mLocalService.isUserRunning(userId); 1466 } 1467 1468 @Override getUserName()1469 public String getUserName() { 1470 if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) { 1471 throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED " 1472 + "permissions to: get user name"); 1473 } 1474 final int userId = UserHandle.getUserId(Binder.getCallingUid()); 1475 synchronized (mUsersLock) { 1476 UserInfo userInfo = userWithName(getUserInfoLU(userId)); 1477 return userInfo == null ? "" : userInfo.name; 1478 } 1479 } 1480 1481 @Override getUserStartRealtime()1482 public long getUserStartRealtime() { 1483 final int userId = UserHandle.getUserId(Binder.getCallingUid()); 1484 synchronized (mUsersLock) { 1485 final UserData user = getUserDataLU(userId); 1486 if (user != null) { 1487 return user.startRealtime; 1488 } 1489 return 0; 1490 } 1491 } 1492 1493 @Override getUserUnlockRealtime()1494 public long getUserUnlockRealtime() { 1495 synchronized (mUsersLock) { 1496 final UserData user = getUserDataLU(UserHandle.getUserId(Binder.getCallingUid())); 1497 if (user != null) { 1498 return user.unlockRealtime; 1499 } 1500 return 0; 1501 } 1502 } 1503 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(@serIdInt int userId, String name)1504 private void checkManageOrInteractPermissionIfCallerInOtherProfileGroup(@UserIdInt int userId, 1505 String name) { 1506 final int callingUserId = UserHandle.getCallingUserId(); 1507 if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) || 1508 hasManageUsersPermission()) { 1509 return; 1510 } 1511 if (!hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, 1512 Binder.getCallingUid())) { 1513 throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS permission " 1514 + "to: check " + name); 1515 } 1516 } 1517 1518 @Override isDemoUser(@serIdInt int userId)1519 public boolean isDemoUser(@UserIdInt int userId) { 1520 final int callingUserId = UserHandle.getCallingUserId(); 1521 if (callingUserId != userId && !hasManageUsersPermission()) { 1522 throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId 1523 + " is a demo user"); 1524 } 1525 synchronized (mUsersLock) { 1526 UserInfo userInfo = getUserInfoLU(userId); 1527 return userInfo != null && userInfo.isDemo(); 1528 } 1529 } 1530 1531 @Override isPreCreated(@serIdInt int userId)1532 public boolean isPreCreated(@UserIdInt int userId) { 1533 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isPreCreated"); 1534 synchronized (mUsersLock) { 1535 UserInfo userInfo = getUserInfoLU(userId); 1536 return userInfo != null && userInfo.preCreated; 1537 } 1538 } 1539 1540 @Override isRestricted()1541 public boolean isRestricted() { 1542 synchronized (mUsersLock) { 1543 return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted(); 1544 } 1545 } 1546 1547 @Override canHaveRestrictedProfile(@serIdInt int userId)1548 public boolean canHaveRestrictedProfile(@UserIdInt int userId) { 1549 checkManageUsersPermission("canHaveRestrictedProfile"); 1550 synchronized (mUsersLock) { 1551 final UserInfo userInfo = getUserInfoLU(userId); 1552 if (userInfo == null || !userInfo.canHaveProfile()) { 1553 return false; 1554 } 1555 if (!userInfo.isAdmin()) { 1556 return false; 1557 } 1558 // restricted profile can be created if there is no DO set and the admin user has no PO; 1559 return !mIsDeviceManaged && !mIsUserManaged.get(userId); 1560 } 1561 } 1562 1563 @Override hasRestrictedProfiles()1564 public boolean hasRestrictedProfiles() { 1565 checkManageUsersPermission("hasRestrictedProfiles"); 1566 final int callingUserId = UserHandle.getCallingUserId(); 1567 synchronized (mUsersLock) { 1568 final int userSize = mUsers.size(); 1569 for (int i = 0; i < userSize; i++) { 1570 UserInfo profile = mUsers.valueAt(i).info; 1571 if (callingUserId != profile.id 1572 && profile.restrictedProfileParentId == callingUserId) { 1573 return true; 1574 } 1575 } 1576 return false; 1577 } 1578 } 1579 1580 /* 1581 * Should be locked on mUsers before calling this. 1582 */ 1583 @GuardedBy("mUsersLock") getUserInfoLU(@serIdInt int userId)1584 private UserInfo getUserInfoLU(@UserIdInt int userId) { 1585 final UserData userData = mUsers.get(userId); 1586 // If it is partial and not in the process of being removed, return as unknown user. 1587 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 1588 Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); 1589 return null; 1590 } 1591 return userData != null ? userData.info : null; 1592 } 1593 1594 @GuardedBy("mUsersLock") getUserDataLU(@serIdInt int userId)1595 private UserData getUserDataLU(@UserIdInt int userId) { 1596 final UserData userData = mUsers.get(userId); 1597 // If it is partial and not in the process of being removed, return as unknown user. 1598 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 1599 return null; 1600 } 1601 return userData; 1602 } 1603 1604 /** 1605 * Obtains {@link #mUsersLock} and return UserInfo from mUsers. 1606 * <p>No permissions checking or any addition checks are made</p> 1607 */ getUserInfoNoChecks(@serIdInt int userId)1608 private UserInfo getUserInfoNoChecks(@UserIdInt int userId) { 1609 synchronized (mUsersLock) { 1610 final UserData userData = mUsers.get(userId); 1611 return userData != null ? userData.info : null; 1612 } 1613 } 1614 1615 /** 1616 * Obtains {@link #mUsersLock} and return UserData from mUsers. 1617 * <p>No permissions checking or any addition checks are made</p> 1618 */ getUserDataNoChecks(@serIdInt int userId)1619 private UserData getUserDataNoChecks(@UserIdInt int userId) { 1620 synchronized (mUsersLock) { 1621 return mUsers.get(userId); 1622 } 1623 } 1624 1625 /** Called by PackageManagerService */ exists(@serIdInt int userId)1626 public boolean exists(@UserIdInt int userId) { 1627 return mLocalService.exists(userId); 1628 } 1629 1630 @Override setUserName(@serIdInt int userId, String name)1631 public void setUserName(@UserIdInt int userId, String name) { 1632 checkManageUsersPermission("rename users"); 1633 boolean changed = false; 1634 synchronized (mPackagesLock) { 1635 UserData userData = getUserDataNoChecks(userId); 1636 if (userData == null || userData.info.partial) { 1637 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId); 1638 return; 1639 } 1640 if (name != null && !name.equals(userData.info.name)) { 1641 userData.info.name = name; 1642 writeUserLP(userData); 1643 changed = true; 1644 } 1645 } 1646 if (changed) { 1647 long ident = Binder.clearCallingIdentity(); 1648 try { 1649 sendUserInfoChangedBroadcast(userId); 1650 } finally { 1651 Binder.restoreCallingIdentity(ident); 1652 } 1653 } 1654 } 1655 1656 @Override setUserIcon(@serIdInt int userId, Bitmap bitmap)1657 public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) { 1658 try { 1659 checkManageUsersPermission("update users"); 1660 enforceUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId, 1661 "Cannot set user icon"); 1662 mLocalService.setUserIcon(userId, bitmap); 1663 } catch (UserManager.CheckedUserOperationException e) { 1664 throw e.toServiceSpecificException(); 1665 } 1666 } 1667 1668 1669 sendUserInfoChangedBroadcast(@serIdInt int userId)1670 private void sendUserInfoChangedBroadcast(@UserIdInt int userId) { 1671 Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED); 1672 changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 1673 changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 1674 mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL); 1675 } 1676 1677 @Override getUserIcon(int targetUserId)1678 public ParcelFileDescriptor getUserIcon(int targetUserId) { 1679 if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) { 1680 throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED " 1681 + "permissions to: get user icon"); 1682 } 1683 String iconPath; 1684 synchronized (mPackagesLock) { 1685 UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId); 1686 if (targetUserInfo == null || targetUserInfo.partial) { 1687 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId); 1688 return null; 1689 } 1690 1691 final int callingUserId = UserHandle.getCallingUserId(); 1692 final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId; 1693 final int targetGroupId = targetUserInfo.profileGroupId; 1694 final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID 1695 && callingGroupId == targetGroupId); 1696 if ((callingUserId != targetUserId) && !sameGroup) { 1697 checkManageUsersPermission("get the icon of a user who is not related"); 1698 } 1699 1700 if (targetUserInfo.iconPath == null) { 1701 return null; 1702 } 1703 iconPath = targetUserInfo.iconPath; 1704 } 1705 1706 try { 1707 return ParcelFileDescriptor.open( 1708 new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY); 1709 } catch (FileNotFoundException e) { 1710 Slog.e(LOG_TAG, "Couldn't find icon file", e); 1711 } 1712 return null; 1713 } 1714 makeInitialized(@serIdInt int userId)1715 public void makeInitialized(@UserIdInt int userId) { 1716 checkManageUsersPermission("makeInitialized"); 1717 boolean scheduleWriteUser = false; 1718 UserData userData; 1719 synchronized (mUsersLock) { 1720 userData = mUsers.get(userId); 1721 if (userData == null || userData.info.partial) { 1722 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId); 1723 return; 1724 } 1725 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 1726 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 1727 scheduleWriteUser = true; 1728 } 1729 } 1730 if (scheduleWriteUser) { 1731 scheduleWriteUser(userData); 1732 } 1733 } 1734 1735 /** 1736 * If default guest restrictions haven't been initialized yet, add the basic 1737 * restrictions. 1738 */ initDefaultGuestRestrictions()1739 private void initDefaultGuestRestrictions() { 1740 synchronized (mGuestRestrictions) { 1741 if (mGuestRestrictions.isEmpty()) { 1742 UserTypeDetails guestType = mUserTypes.get(UserManager.USER_TYPE_FULL_GUEST); 1743 if (guestType == null) { 1744 Slog.wtf(LOG_TAG, "Can't set default guest restrictions: type doesn't exist."); 1745 return; 1746 } 1747 guestType.addDefaultRestrictionsTo(mGuestRestrictions); 1748 } 1749 } 1750 } 1751 1752 @Override getDefaultGuestRestrictions()1753 public Bundle getDefaultGuestRestrictions() { 1754 checkManageUsersPermission("getDefaultGuestRestrictions"); 1755 synchronized (mGuestRestrictions) { 1756 return new Bundle(mGuestRestrictions); 1757 } 1758 } 1759 1760 @Override setDefaultGuestRestrictions(Bundle restrictions)1761 public void setDefaultGuestRestrictions(Bundle restrictions) { 1762 checkManageUsersPermission("setDefaultGuestRestrictions"); 1763 synchronized (mGuestRestrictions) { 1764 mGuestRestrictions.clear(); 1765 mGuestRestrictions.putAll(restrictions); 1766 } 1767 synchronized (mPackagesLock) { 1768 writeUserListLP(); 1769 } 1770 } 1771 1772 /** 1773 * See {@link UserManagerInternal#setDevicePolicyUserRestrictions} 1774 */ setDevicePolicyUserRestrictionsInner(@serIdInt int originatingUserId, @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner)1775 private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId, 1776 @NonNull Bundle global, @NonNull RestrictionsSet local, 1777 boolean isDeviceOwner) { 1778 boolean globalChanged, localChanged; 1779 List<Integer> updatedLocalTargetUserIds; 1780 synchronized (mRestrictionsLock) { 1781 // Update global and local restrictions if they were changed. 1782 globalChanged = mDevicePolicyGlobalUserRestrictions 1783 .updateRestrictions(originatingUserId, global); 1784 updatedLocalTargetUserIds = getUpdatedTargetUserIdsFromLocalRestrictions( 1785 originatingUserId, local); 1786 localChanged = updateLocalRestrictionsForTargetUsersLR(originatingUserId, local, 1787 updatedLocalTargetUserIds); 1788 1789 if (isDeviceOwner) { 1790 // Remember the global restriction owner userId to be able to make a distinction 1791 // in getUserRestrictionSource on who set local policies. 1792 mDeviceOwnerUserId = originatingUserId; 1793 } else { 1794 if (mDeviceOwnerUserId == originatingUserId) { 1795 // When profile owner sets restrictions it passes null global bundle and we 1796 // reset global restriction owner userId. 1797 // This means this user used to have DO, but now the DO is gone and the user 1798 // instead has PO. 1799 mDeviceOwnerUserId = UserHandle.USER_NULL; 1800 } 1801 } 1802 } 1803 if (DBG) { 1804 Slog.d(LOG_TAG, "setDevicePolicyUserRestrictions: " 1805 + " originatingUserId=" + originatingUserId 1806 + " global=" + global + (globalChanged ? " (changed)" : "") 1807 + " local=" + local + (localChanged ? " (changed)" : "") 1808 ); 1809 } 1810 // Don't call them within the mRestrictionsLock. 1811 synchronized (mPackagesLock) { 1812 if (globalChanged || localChanged) { 1813 if (updatedLocalTargetUserIds.size() == 1 1814 && updatedLocalTargetUserIds.contains(originatingUserId)) { 1815 writeUserLP(getUserDataNoChecks(originatingUserId)); 1816 } else { 1817 if (globalChanged) { 1818 writeUserLP(getUserDataNoChecks(originatingUserId)); 1819 } 1820 if (localChanged) { 1821 for (int targetUserId : updatedLocalTargetUserIds) { 1822 writeAllTargetUsersLP(targetUserId); 1823 } 1824 } 1825 } 1826 } 1827 } 1828 1829 synchronized (mRestrictionsLock) { 1830 if (globalChanged) { 1831 applyUserRestrictionsForAllUsersLR(); 1832 } else if (localChanged) { 1833 for (int targetUserId : updatedLocalTargetUserIds) { 1834 applyUserRestrictionsLR(targetUserId); 1835 } 1836 } 1837 } 1838 } 1839 1840 /** 1841 * @return the list of updated target user ids in device policy local restrictions for a 1842 * given originating user id. 1843 */ getUpdatedTargetUserIdsFromLocalRestrictions(int originatingUserId, @NonNull RestrictionsSet local)1844 private List<Integer> getUpdatedTargetUserIdsFromLocalRestrictions(int originatingUserId, 1845 @NonNull RestrictionsSet local) { 1846 List<Integer> targetUserIds = new ArrayList<>(); 1847 // Update all the target user ids from the local restrictions set 1848 for (int i = 0; i < local.size(); i++) { 1849 targetUserIds.add(local.keyAt(i)); 1850 } 1851 // Update the target user id from device policy local restrictions if the local 1852 // restrictions set does not contain the target user id. 1853 for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) { 1854 int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i); 1855 RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i); 1856 if (!local.containsKey(targetUserId) 1857 && restrictionsSet.containsKey(originatingUserId)) { 1858 targetUserIds.add(targetUserId); 1859 } 1860 } 1861 return targetUserIds; 1862 } 1863 1864 /** 1865 * Update restrictions for all target users in the restriction set. If a target user does not 1866 * exist in device policy local restrictions, remove the restrictions bundle for that target 1867 * user originating from the specified originating user. 1868 */ updateLocalRestrictionsForTargetUsersLR(int originatingUserId, RestrictionsSet local, List<Integer> updatedTargetUserIds)1869 private boolean updateLocalRestrictionsForTargetUsersLR(int originatingUserId, 1870 RestrictionsSet local, List<Integer> updatedTargetUserIds) { 1871 boolean changed = false; 1872 for (int targetUserId : updatedTargetUserIds) { 1873 Bundle restrictions = local.getRestrictions(targetUserId); 1874 if (restrictions == null) { 1875 restrictions = new Bundle(); 1876 } 1877 if (getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId) 1878 .updateRestrictions(originatingUserId, restrictions)) { 1879 changed = true; 1880 } 1881 } 1882 return changed; 1883 } 1884 1885 /** 1886 * A new restriction set is created if a restriction set does not already exist for a given 1887 * target user. 1888 * 1889 * @return restrictions set for a given target user. 1890 */ getDevicePolicyLocalRestrictionsForTargetUserLR( int targetUserId)1891 private @NonNull RestrictionsSet getDevicePolicyLocalRestrictionsForTargetUserLR( 1892 int targetUserId) { 1893 RestrictionsSet result = mDevicePolicyLocalUserRestrictions.get(targetUserId); 1894 if (result == null) { 1895 result = new RestrictionsSet(); 1896 mDevicePolicyLocalUserRestrictions.put(targetUserId, result); 1897 } 1898 return result; 1899 } 1900 1901 @GuardedBy("mRestrictionsLock") computeEffectiveUserRestrictionsLR(@serIdInt int userId)1902 private Bundle computeEffectiveUserRestrictionsLR(@UserIdInt int userId) { 1903 final Bundle baseRestrictions = 1904 UserRestrictionsUtils.nonNull(mBaseUserRestrictions.getRestrictions(userId)); 1905 final Bundle global = mDevicePolicyGlobalUserRestrictions.mergeAll(); 1906 final RestrictionsSet local = getDevicePolicyLocalRestrictionsForTargetUserLR(userId); 1907 1908 if (UserRestrictionsUtils.isEmpty(global) && local.isEmpty()) { 1909 // Common case first. 1910 return baseRestrictions; 1911 } 1912 final Bundle effective = UserRestrictionsUtils.clone(baseRestrictions); 1913 UserRestrictionsUtils.merge(effective, global); 1914 UserRestrictionsUtils.merge(effective, local.mergeAll()); 1915 1916 return effective; 1917 } 1918 1919 @GuardedBy("mRestrictionsLock") invalidateEffectiveUserRestrictionsLR(@serIdInt int userId)1920 private void invalidateEffectiveUserRestrictionsLR(@UserIdInt int userId) { 1921 if (DBG) { 1922 Slog.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId); 1923 } 1924 mCachedEffectiveUserRestrictions.remove(userId); 1925 } 1926 getEffectiveUserRestrictions(@serIdInt int userId)1927 private Bundle getEffectiveUserRestrictions(@UserIdInt int userId) { 1928 synchronized (mRestrictionsLock) { 1929 Bundle restrictions = mCachedEffectiveUserRestrictions.getRestrictions(userId); 1930 if (restrictions == null) { 1931 restrictions = computeEffectiveUserRestrictionsLR(userId); 1932 mCachedEffectiveUserRestrictions.updateRestrictions(userId, restrictions); 1933 } 1934 return restrictions; 1935 } 1936 } 1937 1938 /** @return a specific user restriction that's in effect currently. */ 1939 @Override hasUserRestriction(String restrictionKey, @UserIdInt int userId)1940 public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) { 1941 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "hasUserRestriction"); 1942 return mLocalService.hasUserRestriction(restrictionKey, userId); 1943 } 1944 1945 /** @return if any user has the given restriction. */ 1946 @Override hasUserRestrictionOnAnyUser(String restrictionKey)1947 public boolean hasUserRestrictionOnAnyUser(String restrictionKey) { 1948 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1949 return false; 1950 } 1951 final List<UserInfo> users = getUsers(/* excludeDying= */ true); 1952 for (int i = 0; i < users.size(); i++) { 1953 final int userId = users.get(i).id; 1954 Bundle restrictions = getEffectiveUserRestrictions(userId); 1955 if (restrictions != null && restrictions.getBoolean(restrictionKey)) { 1956 return true; 1957 } 1958 } 1959 return false; 1960 } 1961 1962 @Override isSettingRestrictedForUser(String setting, @UserIdInt int userId, String value, int callingUid)1963 public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId, 1964 String value, int callingUid) { 1965 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1966 throw new SecurityException("Non-system caller"); 1967 } 1968 return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId, 1969 value, callingUid); 1970 } 1971 1972 @Override addUserRestrictionsListener(final IUserRestrictionsListener listener)1973 public void addUserRestrictionsListener(final IUserRestrictionsListener listener) { 1974 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1975 throw new SecurityException("Non-system caller"); 1976 } 1977 1978 // NOTE: unregistering not supported; only client is the settings provider, 1979 // which installs a single static permanent listener. If that listener goes 1980 // bad it implies the whole system process is going to crash. 1981 mLocalService.addUserRestrictionsListener( 1982 (int userId, Bundle newRestrict, Bundle prevRestrict) -> { 1983 try { 1984 listener.onUserRestrictionsChanged(userId, newRestrict, prevRestrict); 1985 } catch (RemoteException re) { 1986 Slog.e("IUserRestrictionsListener", 1987 "Unable to invoke listener: " + re.getMessage()); 1988 } 1989 }); 1990 } 1991 1992 /** 1993 * @hide 1994 * 1995 * Returns who set a user restriction on a user. 1996 * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. 1997 * @param restrictionKey the string key representing the restriction 1998 * @param userId the id of the user for whom to retrieve the restrictions. 1999 * @return The source of user restriction. Any combination of 2000 * {@link UserManager#RESTRICTION_NOT_SET}, 2001 * {@link UserManager#RESTRICTION_SOURCE_SYSTEM}, 2002 * {@link UserManager#RESTRICTION_SOURCE_DEVICE_OWNER} 2003 * and {@link UserManager#RESTRICTION_SOURCE_PROFILE_OWNER} 2004 */ 2005 @Override getUserRestrictionSource(String restrictionKey, @UserIdInt int userId)2006 public int getUserRestrictionSource(String restrictionKey, @UserIdInt int userId) { 2007 List<EnforcingUser> enforcingUsers = getUserRestrictionSources(restrictionKey, userId); 2008 // Get "bitwise or" of restriction sources for all enforcing users. 2009 int result = UserManager.RESTRICTION_NOT_SET; 2010 for (int i = enforcingUsers.size() - 1; i >= 0; i--) { 2011 result |= enforcingUsers.get(i).getUserRestrictionSource(); 2012 } 2013 return result; 2014 } 2015 2016 @Override getUserRestrictionSources( String restrictionKey, @UserIdInt int userId)2017 public List<EnforcingUser> getUserRestrictionSources( 2018 String restrictionKey, @UserIdInt int userId) { 2019 checkManageUsersPermission("getUserRestrictionSource"); 2020 2021 // Shortcut for the most common case 2022 if (!hasUserRestriction(restrictionKey, userId)) { 2023 return Collections.emptyList(); 2024 } 2025 2026 final List<EnforcingUser> result = new ArrayList<>(); 2027 2028 // Check if it is base restriction. 2029 if (hasBaseUserRestriction(restrictionKey, userId)) { 2030 result.add(new EnforcingUser( 2031 UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM)); 2032 } 2033 2034 synchronized (mRestrictionsLock) { 2035 // Check if it is set as a local restriction. 2036 result.addAll(getDevicePolicyLocalRestrictionsForTargetUserLR(userId).getEnforcingUsers( 2037 restrictionKey, mDeviceOwnerUserId)); 2038 2039 // Check if it is set as a global restriction. 2040 result.addAll(mDevicePolicyGlobalUserRestrictions.getEnforcingUsers(restrictionKey, 2041 mDeviceOwnerUserId)); 2042 } 2043 return result; 2044 } 2045 2046 /** 2047 * @return UserRestrictions that are in effect currently. This always returns a new 2048 * {@link Bundle}. 2049 */ 2050 @Override getUserRestrictions(@serIdInt int userId)2051 public Bundle getUserRestrictions(@UserIdInt int userId) { 2052 checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserRestrictions"); 2053 return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId)); 2054 } 2055 2056 @Override hasBaseUserRestriction(String restrictionKey, @UserIdInt int userId)2057 public boolean hasBaseUserRestriction(String restrictionKey, @UserIdInt int userId) { 2058 checkManageOrCreateUsersPermission("hasBaseUserRestriction"); 2059 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 2060 return false; 2061 } 2062 synchronized (mRestrictionsLock) { 2063 Bundle bundle = mBaseUserRestrictions.getRestrictions(userId); 2064 return (bundle != null && bundle.getBoolean(restrictionKey, false)); 2065 } 2066 } 2067 2068 @Override setUserRestriction(String key, boolean value, @UserIdInt int userId)2069 public void setUserRestriction(String key, boolean value, @UserIdInt int userId) { 2070 checkManageUsersPermission("setUserRestriction"); 2071 if (!UserRestrictionsUtils.isValidRestriction(key)) { 2072 return; 2073 } 2074 synchronized (mRestrictionsLock) { 2075 // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create 2076 // a copy. 2077 final Bundle newRestrictions = UserRestrictionsUtils.clone( 2078 mBaseUserRestrictions.getRestrictions(userId)); 2079 newRestrictions.putBoolean(key, value); 2080 2081 updateUserRestrictionsInternalLR(newRestrictions, userId); 2082 } 2083 } 2084 2085 /** 2086 * Optionally updating user restrictions, calculate the effective user restrictions and also 2087 * propagate to other services and system settings. 2088 * 2089 * @param newBaseRestrictions User restrictions to set. 2090 * If null, will not update user restrictions and only does the propagation. 2091 * @param userId target user ID. 2092 */ 2093 @GuardedBy("mRestrictionsLock") updateUserRestrictionsInternalLR( @ullable Bundle newBaseRestrictions, @UserIdInt int userId)2094 private void updateUserRestrictionsInternalLR( 2095 @Nullable Bundle newBaseRestrictions, @UserIdInt int userId) { 2096 final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull( 2097 mAppliedUserRestrictions.getRestrictions(userId)); 2098 2099 // Update base restrictions. 2100 if (newBaseRestrictions != null) { 2101 // If newBaseRestrictions == the current one, it's probably a bug. 2102 final Bundle prevBaseRestrictions = mBaseUserRestrictions.getRestrictions(userId); 2103 2104 Preconditions.checkState(prevBaseRestrictions != newBaseRestrictions); 2105 Preconditions.checkState(mCachedEffectiveUserRestrictions.getRestrictions(userId) 2106 != newBaseRestrictions); 2107 2108 if (mBaseUserRestrictions.updateRestrictions(userId, newBaseRestrictions)) { 2109 scheduleWriteUser(getUserDataNoChecks(userId)); 2110 } 2111 } 2112 2113 final Bundle effective = computeEffectiveUserRestrictionsLR(userId); 2114 2115 mCachedEffectiveUserRestrictions.updateRestrictions(userId, effective); 2116 2117 // Apply the new restrictions. 2118 if (DBG) { 2119 debug("Applying user restrictions: userId=" + userId 2120 + " new=" + effective + " prev=" + prevAppliedRestrictions); 2121 } 2122 2123 if (mAppOpsService != null) { // We skip it until system-ready. 2124 mHandler.post(new Runnable() { 2125 @Override 2126 public void run() { 2127 try { 2128 mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId); 2129 } catch (RemoteException e) { 2130 Slog.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions"); 2131 } 2132 } 2133 }); 2134 } 2135 2136 propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions); 2137 2138 mAppliedUserRestrictions.updateRestrictions(userId, new Bundle(effective)); 2139 } 2140 propagateUserRestrictionsLR(final int userId, Bundle newRestrictions, Bundle prevRestrictions)2141 private void propagateUserRestrictionsLR(final int userId, 2142 Bundle newRestrictions, Bundle prevRestrictions) { 2143 // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock 2144 // actually, but we still need some kind of synchronization otherwise we might end up 2145 // calling listeners out-of-order, thus "LR". 2146 2147 if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) { 2148 return; 2149 } 2150 2151 final Bundle newRestrictionsFinal = new Bundle(newRestrictions); 2152 final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions); 2153 2154 mHandler.post(new Runnable() { 2155 @Override 2156 public void run() { 2157 UserRestrictionsUtils.applyUserRestrictions( 2158 mContext, userId, newRestrictionsFinal, prevRestrictionsFinal); 2159 2160 final UserRestrictionsListener[] listeners; 2161 synchronized (mUserRestrictionsListeners) { 2162 listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()]; 2163 mUserRestrictionsListeners.toArray(listeners); 2164 } 2165 for (int i = 0; i < listeners.length; i++) { 2166 listeners[i].onUserRestrictionsChanged(userId, 2167 newRestrictionsFinal, prevRestrictionsFinal); 2168 } 2169 2170 final Intent broadcast = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) 2171 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2172 mContext.sendBroadcastAsUser(broadcast, UserHandle.of(userId)); 2173 } 2174 }); 2175 } 2176 2177 // Package private for the inner class. 2178 @GuardedBy("mRestrictionsLock") applyUserRestrictionsLR(@serIdInt int userId)2179 void applyUserRestrictionsLR(@UserIdInt int userId) { 2180 updateUserRestrictionsInternalLR(null, userId); 2181 } 2182 2183 @GuardedBy("mRestrictionsLock") 2184 // Package private for the inner class. applyUserRestrictionsForAllUsersLR()2185 void applyUserRestrictionsForAllUsersLR() { 2186 if (DBG) { 2187 debug("applyUserRestrictionsForAllUsersLR"); 2188 } 2189 // First, invalidate all cached values. 2190 mCachedEffectiveUserRestrictions.removeAllRestrictions(); 2191 2192 // We don't want to call into ActivityManagerService while taking a lock, so we'll call 2193 // it on a handler. 2194 final Runnable r = new Runnable() { 2195 @Override 2196 public void run() { 2197 // Then get the list of running users. 2198 final int[] runningUsers; 2199 try { 2200 runningUsers = ActivityManager.getService().getRunningUserIds(); 2201 } catch (RemoteException e) { 2202 Slog.w(LOG_TAG, "Unable to access ActivityManagerService"); 2203 return; 2204 } 2205 // Then re-calculate the effective restrictions and apply, only for running users. 2206 // It's okay if a new user has started after the getRunningUserIds() call, 2207 // because we'll do the same thing (re-calculate the restrictions and apply) 2208 // when we start a user. 2209 synchronized (mRestrictionsLock) { 2210 for (int i = 0; i < runningUsers.length; i++) { 2211 applyUserRestrictionsLR(runningUsers[i]); 2212 } 2213 } 2214 } 2215 }; 2216 mHandler.post(r); 2217 } 2218 2219 /** 2220 * Check if we've hit the limit of how many users can be created. 2221 */ isUserLimitReached()2222 private boolean isUserLimitReached() { 2223 int count; 2224 synchronized (mUsersLock) { 2225 count = getAliveUsersExcludingGuestsCountLU(); 2226 } 2227 return count >= UserManager.getMaxSupportedUsers(); 2228 } 2229 2230 /** 2231 * Returns whether more users of the given type can be added (based on how many users of that 2232 * type already exist). 2233 * 2234 * <p>For checking whether more profiles can be added to a particular parent use 2235 * {@link #canAddMoreProfilesToUser}. 2236 */ canAddMoreUsersOfType(UserTypeDetails userTypeDetails)2237 private boolean canAddMoreUsersOfType(UserTypeDetails userTypeDetails) { 2238 final int max = userTypeDetails.getMaxAllowed(); 2239 if (max == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) { 2240 return true; // Indicates that there is no max. 2241 } 2242 return getNumberOfUsersOfType(userTypeDetails.getName()) < max; 2243 } 2244 2245 /** 2246 * Gets the number of users of the given user type. 2247 * Does not include users that are about to die. 2248 */ getNumberOfUsersOfType(String userType)2249 private int getNumberOfUsersOfType(String userType) { 2250 int count = 0; 2251 synchronized (mUsersLock) { 2252 final int size = mUsers.size(); 2253 for (int i = 0; i < size; i++) { 2254 final UserInfo user = mUsers.valueAt(i).info; 2255 if (user.userType.equals(userType) 2256 && !user.guestToRemove 2257 && !mRemovingUserIds.get(user.id) 2258 && !user.preCreated) { 2259 count++; 2260 } 2261 } 2262 } 2263 return count; 2264 } 2265 2266 @Override canAddMoreManagedProfiles(@serIdInt int userId, boolean allowedToRemoveOne)2267 public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) { 2268 return canAddMoreProfilesToUser(UserManager.USER_TYPE_PROFILE_MANAGED, userId, 2269 allowedToRemoveOne); 2270 } 2271 2272 /** Returns whether more profiles of the given type can be added to the given parent userId. */ 2273 @Override canAddMoreProfilesToUser(String userType, @UserIdInt int userId, boolean allowedToRemoveOne)2274 public boolean canAddMoreProfilesToUser(String userType, @UserIdInt int userId, 2275 boolean allowedToRemoveOne) { 2276 checkManageUsersPermission("check if more profiles can be added."); 2277 final UserTypeDetails type = mUserTypes.get(userType); 2278 if (type == null) { 2279 return false; 2280 } 2281 // Managed profiles have their own specific rules. 2282 final boolean isManagedProfile = type.isManagedProfile(); 2283 if (isManagedProfile) { 2284 if (!mContext.getPackageManager().hasSystemFeature( 2285 PackageManager.FEATURE_MANAGED_USERS)) { 2286 return false; 2287 } 2288 } 2289 synchronized (mUsersLock) { 2290 // Check if the parent exists and its type is even allowed to have a profile. 2291 UserInfo userInfo = getUserInfoLU(userId); 2292 if (userInfo == null || !userInfo.canHaveProfile()) { 2293 return false; 2294 } 2295 2296 // Limit the number of profiles that can be created 2297 final int maxUsersOfType = getMaxUsersOfTypePerParent(type); 2298 if (maxUsersOfType != UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) { 2299 final int userTypeCount = getProfileIds(userId, userType, false).length; 2300 final int profilesRemovedCount = userTypeCount > 0 && allowedToRemoveOne ? 1 : 0; 2301 if (userTypeCount - profilesRemovedCount >= maxUsersOfType) { 2302 return false; 2303 } 2304 // Allow creating a managed profile in the special case where there is only one user 2305 if (isManagedProfile) { 2306 int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU() 2307 - profilesRemovedCount; 2308 return usersCountAfterRemoving == 1 2309 || usersCountAfterRemoving < UserManager.getMaxSupportedUsers(); 2310 } 2311 } 2312 } 2313 return true; 2314 } 2315 2316 @GuardedBy("mUsersLock") getAliveUsersExcludingGuestsCountLU()2317 private int getAliveUsersExcludingGuestsCountLU() { 2318 int aliveUserCount = 0; 2319 final int totalUserCount = mUsers.size(); 2320 // Skip over users being removed 2321 for (int i = 0; i < totalUserCount; i++) { 2322 UserInfo user = mUsers.valueAt(i).info; 2323 if (!mRemovingUserIds.get(user.id) && !user.isGuest() && !user.preCreated) { 2324 aliveUserCount++; 2325 } 2326 } 2327 return aliveUserCount; 2328 } 2329 2330 /** 2331 * Enforces that only the system UID or root's UID or apps that have the 2332 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and 2333 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL} 2334 * permissions can make certain calls to the UserManager. 2335 * 2336 * @param message used as message if SecurityException is thrown 2337 * @throws SecurityException if the caller does not have enough privilege. 2338 */ checkManageUserAndAcrossUsersFullPermission(String message)2339 private static final void checkManageUserAndAcrossUsersFullPermission(String message) { 2340 final int uid = Binder.getCallingUid(); 2341 2342 if (uid == Process.SYSTEM_UID || uid == 0) { 2343 // System UID or root's UID are granted privilege. 2344 return; 2345 } 2346 2347 if (hasPermissionGranted(Manifest.permission.MANAGE_USERS, uid) 2348 && hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)) { 2349 // Apps with both permissions are granted privilege. 2350 return; 2351 } 2352 2353 throw new SecurityException( 2354 "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " + message); 2355 } 2356 hasPermissionGranted(String permission, int uid)2357 private static boolean hasPermissionGranted(String permission, int uid) { 2358 return ActivityManager.checkComponentPermission( 2359 permission, uid, /* owningUid = */-1, /* exported = */ true) == 2360 PackageManager.PERMISSION_GRANTED; 2361 } 2362 2363 /** 2364 * Enforces that only the system UID or root's UID or apps that have the 2365 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} 2366 * permission can make certain calls to the UserManager. 2367 * 2368 * @param message used as message if SecurityException is thrown 2369 * @throws SecurityException if the caller is not system or root 2370 * @see #hasManageUsersPermission() 2371 */ checkManageUsersPermission(String message)2372 private static final void checkManageUsersPermission(String message) { 2373 if (!hasManageUsersPermission()) { 2374 throw new SecurityException("You need MANAGE_USERS permission to: " + message); 2375 } 2376 } 2377 2378 /** 2379 * Enforces that only the system UID or root's UID or apps that have the 2380 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or 2381 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} 2382 * can make certain calls to the UserManager. 2383 * 2384 * @param message used as message if SecurityException is thrown 2385 * @throws SecurityException if the caller is not system or root 2386 * @see #hasManageOrCreateUsersPermission() 2387 */ checkManageOrCreateUsersPermission(String message)2388 private static final void checkManageOrCreateUsersPermission(String message) { 2389 if (!hasManageOrCreateUsersPermission()) { 2390 throw new SecurityException( 2391 "You either need MANAGE_USERS or CREATE_USERS permission to: " + message); 2392 } 2393 } 2394 2395 /** 2396 * Similar to {@link #checkManageOrCreateUsersPermission(String)} but when the caller is tries 2397 * to create user/profiles other than what is allowed for 2398 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} permission, then it will only 2399 * allow callers with {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} permission. 2400 */ checkManageOrCreateUsersPermission(int creationFlags)2401 private static final void checkManageOrCreateUsersPermission(int creationFlags) { 2402 if ((creationFlags & ~ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION) == 0) { 2403 if (!hasManageOrCreateUsersPermission()) { 2404 throw new SecurityException("You either need MANAGE_USERS or CREATE_USERS " 2405 + "permission to create an user with flags: " + creationFlags); 2406 } 2407 } else if (!hasManageUsersPermission()) { 2408 throw new SecurityException("You need MANAGE_USERS permission to create an user " 2409 + " with flags: " + creationFlags); 2410 } 2411 } 2412 2413 /** 2414 * @return whether the calling UID is system UID or root's UID or the calling app has the 2415 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}. 2416 */ hasManageUsersPermission()2417 private static final boolean hasManageUsersPermission() { 2418 final int callingUid = Binder.getCallingUid(); 2419 return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) 2420 || callingUid == Process.ROOT_UID 2421 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid); 2422 } 2423 2424 /** 2425 * @return whether the calling UID is system UID or root's UID or the calling app has the 2426 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or the provided permission. 2427 */ hasManageUsersOrPermission(String alternativePermission)2428 private static final boolean hasManageUsersOrPermission(String alternativePermission) { 2429 final int callingUid = Binder.getCallingUid(); 2430 return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) 2431 || callingUid == Process.ROOT_UID 2432 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid) 2433 || hasPermissionGranted(alternativePermission, callingUid); 2434 } 2435 2436 /** 2437 * @return whether the calling UID is system UID or root's UID or the calling app has the 2438 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or 2439 * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}. 2440 */ hasManageOrCreateUsersPermission()2441 private static final boolean hasManageOrCreateUsersPermission() { 2442 return hasManageUsersOrPermission(android.Manifest.permission.CREATE_USERS); 2443 } 2444 2445 /** 2446 * Enforces that only the system UID or root's UID (on any user) can make certain calls to the 2447 * UserManager. 2448 * 2449 * @param message used as message if SecurityException is thrown 2450 * @throws SecurityException if the caller is not system or root 2451 */ checkSystemOrRoot(String message)2452 private static void checkSystemOrRoot(String message) { 2453 final int uid = Binder.getCallingUid(); 2454 if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) { 2455 throw new SecurityException("Only system may: " + message); 2456 } 2457 } 2458 writeBitmapLP(UserInfo info, Bitmap bitmap)2459 private void writeBitmapLP(UserInfo info, Bitmap bitmap) { 2460 try { 2461 File dir = new File(mUsersDir, Integer.toString(info.id)); 2462 File file = new File(dir, USER_PHOTO_FILENAME); 2463 File tmp = new File(dir, USER_PHOTO_FILENAME_TMP); 2464 if (!dir.exists()) { 2465 dir.mkdir(); 2466 FileUtils.setPermissions( 2467 dir.getPath(), 2468 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 2469 -1, -1); 2470 } 2471 FileOutputStream os; 2472 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp)) 2473 && tmp.renameTo(file) && SELinux.restorecon(file)) { 2474 info.iconPath = file.getAbsolutePath(); 2475 } 2476 try { 2477 os.close(); 2478 } catch (IOException ioe) { 2479 // What the ... ! 2480 } 2481 tmp.delete(); 2482 } catch (FileNotFoundException e) { 2483 Slog.w(LOG_TAG, "Error setting photo for user ", e); 2484 } 2485 } 2486 2487 /** 2488 * Returns an array of user ids. 2489 * 2490 * <p>This array is cached here for quick access, so do not modify or cache it elsewhere. 2491 * 2492 * @return the array of user ids. 2493 */ getUserIds()2494 public @NonNull int[] getUserIds() { 2495 synchronized (mUsersLock) { 2496 return mUserIds; 2497 } 2498 } 2499 2500 /** 2501 * Returns an array of user ids, including pre-created users. 2502 * 2503 * <p>This method should only used for the specific cases that need to handle pre-created users; 2504 * most callers should call {@link #getUserIds()} instead. 2505 * 2506 * <p>This array is cached here for quick access, so do not modify or 2507 * cache it elsewhere. 2508 * 2509 * @return the array of user ids. 2510 */ getUserIdsIncludingPreCreated()2511 public @NonNull int[] getUserIdsIncludingPreCreated() { 2512 synchronized (mUsersLock) { 2513 return mUserIdsIncludingPreCreated; 2514 } 2515 } 2516 2517 @GuardedBy({"mRestrictionsLock", "mPackagesLock"}) readUserListLP()2518 private void readUserListLP() { 2519 if (!mUserListFile.exists()) { 2520 fallbackToSingleUserLP(); 2521 return; 2522 } 2523 FileInputStream fis = null; 2524 AtomicFile userListFile = new AtomicFile(mUserListFile); 2525 try { 2526 fis = userListFile.openRead(); 2527 XmlPullParser parser = Xml.newPullParser(); 2528 parser.setInput(fis, StandardCharsets.UTF_8.name()); 2529 int type; 2530 while ((type = parser.next()) != XmlPullParser.START_TAG 2531 && type != XmlPullParser.END_DOCUMENT) { 2532 // Skip 2533 } 2534 2535 if (type != XmlPullParser.START_TAG) { 2536 Slog.e(LOG_TAG, "Unable to read user list"); 2537 fallbackToSingleUserLP(); 2538 return; 2539 } 2540 2541 mNextSerialNumber = -1; 2542 if (parser.getName().equals(TAG_USERS)) { 2543 String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO); 2544 if (lastSerialNumber != null) { 2545 mNextSerialNumber = Integer.parseInt(lastSerialNumber); 2546 } 2547 String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION); 2548 if (versionNumber != null) { 2549 mUserVersion = Integer.parseInt(versionNumber); 2550 } 2551 } 2552 2553 // Pre-O global user restriction were stored as a single bundle (as opposed to per-user 2554 // currently), take care of it in case of upgrade. 2555 Bundle oldDevicePolicyGlobalUserRestrictions = null; 2556 2557 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 2558 if (type == XmlPullParser.START_TAG) { 2559 final String name = parser.getName(); 2560 if (name.equals(TAG_USER)) { 2561 String id = parser.getAttributeValue(null, ATTR_ID); 2562 2563 UserData userData = readUserLP(Integer.parseInt(id)); 2564 2565 if (userData != null) { 2566 synchronized (mUsersLock) { 2567 mUsers.put(userData.info.id, userData); 2568 if (mNextSerialNumber < 0 2569 || mNextSerialNumber <= userData.info.id) { 2570 mNextSerialNumber = userData.info.id + 1; 2571 } 2572 } 2573 } 2574 } else if (name.equals(TAG_GUEST_RESTRICTIONS)) { 2575 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2576 && type != XmlPullParser.END_TAG) { 2577 if (type == XmlPullParser.START_TAG) { 2578 if (parser.getName().equals(TAG_RESTRICTIONS)) { 2579 synchronized (mGuestRestrictions) { 2580 UserRestrictionsUtils 2581 .readRestrictions(parser, mGuestRestrictions); 2582 } 2583 } 2584 break; 2585 } 2586 } 2587 } else if (name.equals(TAG_DEVICE_OWNER_USER_ID) 2588 // Legacy name, should only be encountered when upgrading from pre-O. 2589 || name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) { 2590 String ownerUserId = parser.getAttributeValue(null, ATTR_ID); 2591 if (ownerUserId != null) { 2592 mDeviceOwnerUserId = Integer.parseInt(ownerUserId); 2593 } 2594 } else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) { 2595 // Should only happen when upgrading from pre-O (version < 7). 2596 oldDevicePolicyGlobalUserRestrictions = 2597 UserRestrictionsUtils.readRestrictions(parser); 2598 } 2599 } 2600 } 2601 2602 updateUserIds(); 2603 upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions); 2604 } catch (IOException | XmlPullParserException e) { 2605 fallbackToSingleUserLP(); 2606 } finally { 2607 IoUtils.closeQuietly(fis); 2608 } 2609 } 2610 2611 /** 2612 * Upgrade steps between versions, either for fixing bugs or changing the data format. 2613 * @param oldGlobalUserRestrictions Pre-O global device policy restrictions. 2614 */ 2615 @GuardedBy({"mRestrictionsLock", "mPackagesLock"}) upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions)2616 private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) { 2617 upgradeIfNecessaryLP(oldGlobalUserRestrictions, mUserVersion); 2618 } 2619 2620 /** 2621 * Version of {@link #upgradeIfNecessaryLP(Bundle)} that takes in the userVersion for testing 2622 * purposes. For non-tests, use {@link #upgradeIfNecessaryLP(Bundle)}. 2623 */ 2624 @GuardedBy({"mRestrictionsLock", "mPackagesLock"}) 2625 @VisibleForTesting upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion)2626 void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion) { 2627 Set<Integer> userIdsToWrite = new ArraySet<>(); 2628 final int originalVersion = mUserVersion; 2629 if (userVersion < 1) { 2630 // Assign a proper name for the owner, if not initialized correctly before 2631 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 2632 if ("Primary".equals(userData.info.name)) { 2633 userData.info.name = 2634 mContext.getResources().getString(com.android.internal.R.string.owner_name); 2635 userIdsToWrite.add(userData.info.id); 2636 } 2637 userVersion = 1; 2638 } 2639 2640 if (userVersion < 2) { 2641 // Owner should be marked as initialized 2642 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 2643 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 2644 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 2645 userIdsToWrite.add(userData.info.id); 2646 } 2647 userVersion = 2; 2648 } 2649 2650 2651 if (userVersion < 4) { 2652 userVersion = 4; 2653 } 2654 2655 if (userVersion < 5) { 2656 initDefaultGuestRestrictions(); 2657 userVersion = 5; 2658 } 2659 2660 if (userVersion < 6) { 2661 final boolean splitSystemUser = UserManager.isSplitSystemUser(); 2662 synchronized (mUsersLock) { 2663 for (int i = 0; i < mUsers.size(); i++) { 2664 UserData userData = mUsers.valueAt(i); 2665 // In non-split mode, only user 0 can have restricted profiles 2666 if (!splitSystemUser && userData.info.isRestricted() 2667 && (userData.info.restrictedProfileParentId 2668 == UserInfo.NO_PROFILE_GROUP_ID)) { 2669 userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM; 2670 userIdsToWrite.add(userData.info.id); 2671 } 2672 } 2673 } 2674 userVersion = 6; 2675 } 2676 2677 if (userVersion < 7) { 2678 // Previously only one user could enforce global restrictions, now it is per-user. 2679 synchronized (mRestrictionsLock) { 2680 if (!UserRestrictionsUtils.isEmpty(oldGlobalUserRestrictions) 2681 && mDeviceOwnerUserId != UserHandle.USER_NULL) { 2682 mDevicePolicyGlobalUserRestrictions.updateRestrictions( 2683 mDeviceOwnerUserId, oldGlobalUserRestrictions); 2684 } 2685 // ENSURE_VERIFY_APPS is now enforced globally even if put by profile owner, so move 2686 // it from local to global bundle for all users who set it. 2687 UserRestrictionsUtils.moveRestriction(UserManager.ENSURE_VERIFY_APPS, 2688 mDevicePolicyLocalUserRestrictions, mDevicePolicyGlobalUserRestrictions 2689 ); 2690 } 2691 // DISALLOW_CONFIG_WIFI was made a default guest restriction some time during version 6. 2692 final UserInfo currentGuestUser = findCurrentGuestUser(); 2693 if (currentGuestUser != null && !hasUserRestriction( 2694 UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) { 2695 setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id); 2696 } 2697 userVersion = 7; 2698 } 2699 2700 if (userVersion < 8) { 2701 // Added FLAG_FULL and FLAG_SYSTEM flags. 2702 synchronized (mUsersLock) { 2703 UserData userData = mUsers.get(UserHandle.USER_SYSTEM); 2704 userData.info.flags |= UserInfo.FLAG_SYSTEM; 2705 if (!UserManager.isHeadlessSystemUserMode()) { 2706 userData.info.flags |= UserInfo.FLAG_FULL; 2707 } 2708 userIdsToWrite.add(userData.info.id); 2709 2710 // Mark FULL all non-profile users except USER_SYSTEM. 2711 // Start index at 1 since USER_SYSTEM is the smallest userId and we're skipping it. 2712 for (int i = 1; i < mUsers.size(); i++) { 2713 userData = mUsers.valueAt(i); 2714 if ((userData.info.flags & UserInfo.FLAG_MANAGED_PROFILE) == 0) { 2715 userData.info.flags |= UserInfo.FLAG_FULL; 2716 userIdsToWrite.add(userData.info.id); 2717 } 2718 } 2719 } 2720 userVersion = 8; 2721 } 2722 2723 if (userVersion < 9) { 2724 // Convert from UserInfo flags to UserTypes. Apply FLAG_PROFILE to FLAG_MANAGED_PROFILE. 2725 synchronized (mUsersLock) { 2726 for (int i = 0; i < mUsers.size(); i++) { 2727 UserData userData = mUsers.valueAt(i); 2728 final int flags = userData.info.flags; 2729 if ((flags & UserInfo.FLAG_SYSTEM) != 0) { 2730 if ((flags & UserInfo.FLAG_FULL) != 0) { 2731 userData.info.userType = UserManager.USER_TYPE_FULL_SYSTEM; 2732 } else { 2733 userData.info.userType = UserManager.USER_TYPE_SYSTEM_HEADLESS; 2734 } 2735 } else { 2736 try { 2737 userData.info.userType = UserInfo.getDefaultUserType(flags); 2738 } catch (IllegalArgumentException e) { 2739 // TODO(b/142482943): What should we do here? Delete user? Crashloop? 2740 throw new IllegalStateException("Cannot upgrade user with flags " 2741 + Integer.toHexString(flags) + " because it doesn't correspond " 2742 + "to a valid user type.", e); 2743 } 2744 } 2745 // OEMs are responsible for their own custom upgrade logic here. 2746 2747 final UserTypeDetails userTypeDetails = mUserTypes.get(userData.info.userType); 2748 if (userTypeDetails == null) { 2749 throw new IllegalStateException( 2750 "Cannot upgrade user with flags " + Integer.toHexString(flags) 2751 + " because " + userData.info.userType + " isn't defined" 2752 + " on this device!"); 2753 } 2754 userData.info.flags |= userTypeDetails.getDefaultUserInfoFlags(); 2755 userIdsToWrite.add(userData.info.id); 2756 } 2757 } 2758 userVersion = 9; 2759 } 2760 2761 if (userVersion < USER_VERSION) { 2762 Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to " 2763 + USER_VERSION); 2764 } else { 2765 mUserVersion = userVersion; 2766 2767 if (originalVersion < mUserVersion) { 2768 for (int userId : userIdsToWrite) { 2769 UserData userData = getUserDataNoChecks(userId); 2770 if (userData != null) { 2771 writeUserLP(userData); 2772 } 2773 } 2774 writeUserListLP(); 2775 } 2776 } 2777 } 2778 2779 @GuardedBy({"mPackagesLock", "mRestrictionsLock"}) fallbackToSingleUserLP()2780 private void fallbackToSingleUserLP() { 2781 int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN 2782 | UserInfo.FLAG_PRIMARY; 2783 // Create the system user 2784 String systemUserType = UserManager.isHeadlessSystemUserMode() ? 2785 UserManager.USER_TYPE_SYSTEM_HEADLESS : UserManager.USER_TYPE_FULL_SYSTEM; 2786 flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags(); 2787 UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags, systemUserType); 2788 UserData userData = putUserInfo(system); 2789 mNextSerialNumber = MIN_USER_ID; 2790 mUserVersion = USER_VERSION; 2791 2792 Bundle restrictions = new Bundle(); 2793 try { 2794 final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray( 2795 com.android.internal.R.array.config_defaultFirstUserRestrictions); 2796 for (String userRestriction : defaultFirstUserRestrictions) { 2797 if (UserRestrictionsUtils.isValidRestriction(userRestriction)) { 2798 restrictions.putBoolean(userRestriction, true); 2799 } 2800 } 2801 } catch (Resources.NotFoundException e) { 2802 Slog.e(LOG_TAG, "Couldn't find resource: config_defaultFirstUserRestrictions", e); 2803 } 2804 2805 if (!restrictions.isEmpty()) { 2806 synchronized (mRestrictionsLock) { 2807 mBaseUserRestrictions.updateRestrictions(UserHandle.USER_SYSTEM, 2808 restrictions); 2809 } 2810 } 2811 2812 updateUserIds(); 2813 initDefaultGuestRestrictions(); 2814 2815 writeUserLP(userData); 2816 writeUserListLP(); 2817 } 2818 getOwnerName()2819 private String getOwnerName() { 2820 return mContext.getResources().getString(com.android.internal.R.string.owner_name); 2821 } 2822 scheduleWriteUser(UserData userData)2823 private void scheduleWriteUser(UserData userData) { 2824 if (DBG) { 2825 debug("scheduleWriteUser"); 2826 } 2827 // No need to wrap it within a lock -- worst case, we'll just post the same message 2828 // twice. 2829 if (!mHandler.hasMessages(WRITE_USER_MSG, userData)) { 2830 Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userData); 2831 mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); 2832 } 2833 } 2834 writeAllTargetUsersLP(int originatingUserId)2835 private void writeAllTargetUsersLP(int originatingUserId) { 2836 for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) { 2837 int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i); 2838 RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i); 2839 if (restrictionsSet.containsKey(originatingUserId)) { 2840 writeUserLP(getUserDataNoChecks(targetUserId)); 2841 } 2842 } 2843 } 2844 writeUserLP(UserData userData)2845 private void writeUserLP(UserData userData) { 2846 if (DBG) { 2847 debug("writeUserLP " + userData); 2848 } 2849 FileOutputStream fos = null; 2850 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX)); 2851 try { 2852 fos = userFile.startWrite(); 2853 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2854 writeUserLP(userData, bos); 2855 userFile.finishWrite(fos); 2856 } catch (Exception ioe) { 2857 Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe); 2858 userFile.failWrite(fos); 2859 } 2860 } 2861 2862 /* 2863 * Writes the user file in this format: 2864 * 2865 * <user flags="20039023" id="0"> 2866 * <name>Primary</name> 2867 * </user> 2868 */ 2869 @VisibleForTesting writeUserLP(UserData userData, OutputStream os)2870 void writeUserLP(UserData userData, OutputStream os) 2871 throws IOException, XmlPullParserException { 2872 // XmlSerializer serializer = XmlUtils.serializerInstance(); 2873 final XmlSerializer serializer = new FastXmlSerializer(); 2874 serializer.setOutput(os, StandardCharsets.UTF_8.name()); 2875 serializer.startDocument(null, true); 2876 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2877 2878 final UserInfo userInfo = userData.info; 2879 serializer.startTag(null, TAG_USER); 2880 serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); 2881 serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber)); 2882 serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); 2883 serializer.attribute(null, ATTR_TYPE, userInfo.userType); 2884 serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime)); 2885 serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME, 2886 Long.toString(userInfo.lastLoggedInTime)); 2887 if (userInfo.lastLoggedInFingerprint != null) { 2888 serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT, 2889 userInfo.lastLoggedInFingerprint); 2890 } 2891 if (userInfo.iconPath != null) { 2892 serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); 2893 } 2894 if (userInfo.partial) { 2895 serializer.attribute(null, ATTR_PARTIAL, "true"); 2896 } 2897 if (userInfo.preCreated) { 2898 serializer.attribute(null, ATTR_PRE_CREATED, "true"); 2899 } 2900 if (userInfo.convertedFromPreCreated) { 2901 serializer.attribute(null, ATTR_CONVERTED_FROM_PRE_CREATED, "true"); 2902 } 2903 if (userInfo.guestToRemove) { 2904 serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true"); 2905 } 2906 if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 2907 serializer.attribute(null, ATTR_PROFILE_GROUP_ID, 2908 Integer.toString(userInfo.profileGroupId)); 2909 } 2910 serializer.attribute(null, ATTR_PROFILE_BADGE, 2911 Integer.toString(userInfo.profileBadge)); 2912 if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) { 2913 serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID, 2914 Integer.toString(userInfo.restrictedProfileParentId)); 2915 } 2916 // Write seed data 2917 if (userData.persistSeedData) { 2918 if (userData.seedAccountName != null) { 2919 serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName); 2920 } 2921 if (userData.seedAccountType != null) { 2922 serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType); 2923 } 2924 } 2925 if (userInfo.name != null) { 2926 serializer.startTag(null, TAG_NAME); 2927 serializer.text(userInfo.name); 2928 serializer.endTag(null, TAG_NAME); 2929 } 2930 synchronized (mRestrictionsLock) { 2931 UserRestrictionsUtils.writeRestrictions(serializer, 2932 mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS); 2933 getDevicePolicyLocalRestrictionsForTargetUserLR(userInfo.id).writeRestrictions( 2934 serializer, TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS); 2935 UserRestrictionsUtils.writeRestrictions(serializer, 2936 mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id), 2937 TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS); 2938 } 2939 2940 if (userData.account != null) { 2941 serializer.startTag(null, TAG_ACCOUNT); 2942 serializer.text(userData.account); 2943 serializer.endTag(null, TAG_ACCOUNT); 2944 } 2945 2946 if (userData.persistSeedData && userData.seedAccountOptions != null) { 2947 serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS); 2948 userData.seedAccountOptions.saveToXml(serializer); 2949 serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS); 2950 } 2951 2952 if (userData.getLastRequestQuietModeEnabledMillis() != 0L) { 2953 serializer.startTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL); 2954 serializer.text(String.valueOf(userData.getLastRequestQuietModeEnabledMillis())); 2955 serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL); 2956 } 2957 2958 serializer.endTag(null, TAG_USER); 2959 2960 serializer.endDocument(); 2961 } 2962 2963 /* 2964 * Writes the user list file in this format: 2965 * 2966 * <users nextSerialNumber="3"> 2967 * <user id="0"></user> 2968 * <user id="2"></user> 2969 * </users> 2970 */ 2971 @GuardedBy({"mRestrictionsLock", "mPackagesLock"}) writeUserListLP()2972 private void writeUserListLP() { 2973 if (DBG) { 2974 debug("writeUserList"); 2975 } 2976 FileOutputStream fos = null; 2977 AtomicFile userListFile = new AtomicFile(mUserListFile); 2978 try { 2979 fos = userListFile.startWrite(); 2980 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2981 2982 // XmlSerializer serializer = XmlUtils.serializerInstance(); 2983 final XmlSerializer serializer = new FastXmlSerializer(); 2984 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 2985 serializer.startDocument(null, true); 2986 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2987 2988 serializer.startTag(null, TAG_USERS); 2989 serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber)); 2990 serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); 2991 2992 serializer.startTag(null, TAG_GUEST_RESTRICTIONS); 2993 synchronized (mGuestRestrictions) { 2994 UserRestrictionsUtils 2995 .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS); 2996 } 2997 serializer.endTag(null, TAG_GUEST_RESTRICTIONS); 2998 serializer.startTag(null, TAG_DEVICE_OWNER_USER_ID); 2999 serializer.attribute(null, ATTR_ID, Integer.toString(mDeviceOwnerUserId)); 3000 serializer.endTag(null, TAG_DEVICE_OWNER_USER_ID); 3001 int[] userIdsToWrite; 3002 synchronized (mUsersLock) { 3003 userIdsToWrite = new int[mUsers.size()]; 3004 for (int i = 0; i < userIdsToWrite.length; i++) { 3005 UserInfo user = mUsers.valueAt(i).info; 3006 userIdsToWrite[i] = user.id; 3007 } 3008 } 3009 for (int id : userIdsToWrite) { 3010 serializer.startTag(null, TAG_USER); 3011 serializer.attribute(null, ATTR_ID, Integer.toString(id)); 3012 serializer.endTag(null, TAG_USER); 3013 } 3014 3015 serializer.endTag(null, TAG_USERS); 3016 3017 serializer.endDocument(); 3018 userListFile.finishWrite(fos); 3019 } catch (Exception e) { 3020 userListFile.failWrite(fos); 3021 Slog.e(LOG_TAG, "Error writing user list"); 3022 } 3023 } 3024 readUserLP(int id)3025 private UserData readUserLP(int id) { 3026 FileInputStream fis = null; 3027 try { 3028 AtomicFile userFile = 3029 new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX)); 3030 fis = userFile.openRead(); 3031 return readUserLP(id, fis); 3032 } catch (IOException ioe) { 3033 Slog.e(LOG_TAG, "Error reading user list"); 3034 } catch (XmlPullParserException pe) { 3035 Slog.e(LOG_TAG, "Error reading user list"); 3036 } finally { 3037 IoUtils.closeQuietly(fis); 3038 } 3039 return null; 3040 } 3041 3042 @VisibleForTesting readUserLP(int id, InputStream is)3043 UserData readUserLP(int id, InputStream is) throws IOException, 3044 XmlPullParserException { 3045 int flags = 0; 3046 String userType = null; 3047 int serialNumber = id; 3048 String name = null; 3049 String account = null; 3050 String iconPath = null; 3051 long creationTime = 0L; 3052 long lastLoggedInTime = 0L; 3053 long lastRequestQuietModeEnabledTimestamp = 0L; 3054 String lastLoggedInFingerprint = null; 3055 int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; 3056 int profileBadge = 0; 3057 int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID; 3058 boolean partial = false; 3059 boolean preCreated = false; 3060 boolean converted = false; 3061 boolean guestToRemove = false; 3062 boolean persistSeedData = false; 3063 String seedAccountName = null; 3064 String seedAccountType = null; 3065 PersistableBundle seedAccountOptions = null; 3066 Bundle baseRestrictions = null; 3067 Bundle legacyLocalRestrictions = null; 3068 RestrictionsSet localRestrictions = null; 3069 Bundle globalRestrictions = null; 3070 3071 XmlPullParser parser = Xml.newPullParser(); 3072 parser.setInput(is, StandardCharsets.UTF_8.name()); 3073 int type; 3074 while ((type = parser.next()) != XmlPullParser.START_TAG 3075 && type != XmlPullParser.END_DOCUMENT) { 3076 // Skip 3077 } 3078 3079 if (type != XmlPullParser.START_TAG) { 3080 Slog.e(LOG_TAG, "Unable to read user " + id); 3081 return null; 3082 } 3083 3084 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) { 3085 int storedId = readIntAttribute(parser, ATTR_ID, -1); 3086 if (storedId != id) { 3087 Slog.e(LOG_TAG, "User id does not match the file name"); 3088 return null; 3089 } 3090 serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id); 3091 flags = readIntAttribute(parser, ATTR_FLAGS, 0); 3092 userType = parser.getAttributeValue(null, ATTR_TYPE); 3093 userType = userType != null ? userType.intern() : null; 3094 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); 3095 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0); 3096 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0); 3097 lastLoggedInFingerprint = parser.getAttributeValue(null, 3098 ATTR_LAST_LOGGED_IN_FINGERPRINT); 3099 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID, 3100 UserInfo.NO_PROFILE_GROUP_ID); 3101 profileBadge = readIntAttribute(parser, ATTR_PROFILE_BADGE, 0); 3102 restrictedProfileParentId = readIntAttribute(parser, 3103 ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID); 3104 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); 3105 if ("true".equals(valueString)) { 3106 partial = true; 3107 } 3108 valueString = parser.getAttributeValue(null, ATTR_PRE_CREATED); 3109 if ("true".equals(valueString)) { 3110 preCreated = true; 3111 } 3112 valueString = parser.getAttributeValue(null, ATTR_CONVERTED_FROM_PRE_CREATED); 3113 if ("true".equals(valueString)) { 3114 converted = true; 3115 } 3116 valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE); 3117 if ("true".equals(valueString)) { 3118 guestToRemove = true; 3119 } 3120 3121 seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME); 3122 seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE); 3123 if (seedAccountName != null || seedAccountType != null) { 3124 persistSeedData = true; 3125 } 3126 3127 int outerDepth = parser.getDepth(); 3128 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3129 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3130 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3131 continue; 3132 } 3133 String tag = parser.getName(); 3134 if (TAG_NAME.equals(tag)) { 3135 type = parser.next(); 3136 if (type == XmlPullParser.TEXT) { 3137 name = parser.getText(); 3138 } 3139 } else if (TAG_RESTRICTIONS.equals(tag)) { 3140 baseRestrictions = UserRestrictionsUtils.readRestrictions(parser); 3141 } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) { 3142 legacyLocalRestrictions = UserRestrictionsUtils.readRestrictions(parser); 3143 } else if (TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS.equals(tag)) { 3144 localRestrictions = RestrictionsSet.readRestrictions(parser, 3145 TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS); 3146 } else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) { 3147 globalRestrictions = UserRestrictionsUtils.readRestrictions(parser); 3148 } else if (TAG_ACCOUNT.equals(tag)) { 3149 type = parser.next(); 3150 if (type == XmlPullParser.TEXT) { 3151 account = parser.getText(); 3152 } 3153 } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) { 3154 seedAccountOptions = PersistableBundle.restoreFromXml(parser); 3155 persistSeedData = true; 3156 } else if (TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL.equals(tag)) { 3157 type = parser.next(); 3158 if (type == XmlPullParser.TEXT) { 3159 lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText()); 3160 } 3161 } 3162 } 3163 } 3164 3165 // Create the UserInfo object that gets passed around 3166 UserInfo userInfo = new UserInfo(id, name, iconPath, flags, userType); 3167 userInfo.serialNumber = serialNumber; 3168 userInfo.creationTime = creationTime; 3169 userInfo.lastLoggedInTime = lastLoggedInTime; 3170 userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint; 3171 userInfo.partial = partial; 3172 userInfo.preCreated = preCreated; 3173 userInfo.convertedFromPreCreated = converted; 3174 userInfo.guestToRemove = guestToRemove; 3175 userInfo.profileGroupId = profileGroupId; 3176 userInfo.profileBadge = profileBadge; 3177 userInfo.restrictedProfileParentId = restrictedProfileParentId; 3178 3179 // Create the UserData object that's internal to this class 3180 UserData userData = new UserData(); 3181 userData.info = userInfo; 3182 userData.account = account; 3183 userData.seedAccountName = seedAccountName; 3184 userData.seedAccountType = seedAccountType; 3185 userData.persistSeedData = persistSeedData; 3186 userData.seedAccountOptions = seedAccountOptions; 3187 userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp); 3188 3189 synchronized (mRestrictionsLock) { 3190 if (baseRestrictions != null) { 3191 mBaseUserRestrictions.updateRestrictions(id, baseRestrictions); 3192 } 3193 if (localRestrictions != null) { 3194 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions); 3195 if (legacyLocalRestrictions != null) { 3196 Slog.wtf(LOG_TAG, "Seeing both legacy and current local restrictions in xml"); 3197 } 3198 } else if (legacyLocalRestrictions != null) { 3199 mDevicePolicyLocalUserRestrictions.put(id, 3200 new RestrictionsSet(id, legacyLocalRestrictions)); 3201 } 3202 if (globalRestrictions != null) { 3203 mDevicePolicyGlobalUserRestrictions.updateRestrictions(id, 3204 globalRestrictions); 3205 } 3206 } 3207 return userData; 3208 } 3209 readIntAttribute(XmlPullParser parser, String attr, int defaultValue)3210 private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) { 3211 String valueString = parser.getAttributeValue(null, attr); 3212 if (valueString == null) return defaultValue; 3213 try { 3214 return Integer.parseInt(valueString); 3215 } catch (NumberFormatException nfe) { 3216 return defaultValue; 3217 } 3218 } 3219 readLongAttribute(XmlPullParser parser, String attr, long defaultValue)3220 private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) { 3221 String valueString = parser.getAttributeValue(null, attr); 3222 if (valueString == null) return defaultValue; 3223 try { 3224 return Long.parseLong(valueString); 3225 } catch (NumberFormatException nfe) { 3226 return defaultValue; 3227 } 3228 } 3229 3230 /** 3231 * Removes the app restrictions file for a specific package and user id, if it exists. 3232 * 3233 * @return whether there were any restrictions. 3234 */ cleanAppRestrictionsForPackageLAr(String pkg, @UserIdInt int userId)3235 private static boolean cleanAppRestrictionsForPackageLAr(String pkg, @UserIdInt int userId) { 3236 final File dir = Environment.getUserSystemDirectory(userId); 3237 final File resFile = new File(dir, packageToRestrictionsFileName(pkg)); 3238 if (resFile.exists()) { 3239 resFile.delete(); 3240 return true; 3241 } 3242 return false; 3243 } 3244 3245 /** 3246 * Creates a profile user. Used for actual profiles, like 3247 * {@link UserManager#USER_TYPE_PROFILE_MANAGED}, 3248 * as well as for {@link UserManager#USER_TYPE_FULL_RESTRICTED}. 3249 */ 3250 @Override createProfileForUserWithThrow(String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)3251 public UserInfo createProfileForUserWithThrow(String name, @NonNull String userType, 3252 @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) 3253 throws ServiceSpecificException { 3254 checkManageOrCreateUsersPermission(flags); 3255 try { 3256 return createUserInternal(name, userType, flags, userId, disallowedPackages); 3257 } catch (UserManager.CheckedUserOperationException e) { 3258 throw e.toServiceSpecificException(); 3259 } 3260 } 3261 3262 /** 3263 * @see #createProfileForUser 3264 */ 3265 @Override createProfileForUserEvenWhenDisallowedWithThrow(String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)3266 public UserInfo createProfileForUserEvenWhenDisallowedWithThrow(String name, 3267 @NonNull String userType, 3268 @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) 3269 throws ServiceSpecificException { 3270 checkManageOrCreateUsersPermission(flags); 3271 try { 3272 return createUserInternalUnchecked(name, userType, flags, userId, 3273 /* preCreate= */ false, disallowedPackages); 3274 } catch (UserManager.CheckedUserOperationException e) { 3275 throw e.toServiceSpecificException(); 3276 } 3277 } 3278 3279 @Override createUserWithThrow(String name, @NonNull String userType, @UserInfoFlag int flags)3280 public UserInfo createUserWithThrow(String name, @NonNull String userType, 3281 @UserInfoFlag int flags) 3282 throws ServiceSpecificException { 3283 checkManageOrCreateUsersPermission(flags); 3284 try { 3285 return createUserInternal(name, userType, flags, UserHandle.USER_NULL, 3286 /* disallowedPackages= */ null); 3287 } catch (UserManager.CheckedUserOperationException e) { 3288 throw e.toServiceSpecificException(); 3289 } 3290 } 3291 3292 @Override preCreateUserWithThrow(String userType)3293 public UserInfo preCreateUserWithThrow(String userType) throws ServiceSpecificException { 3294 final UserTypeDetails userTypeDetails = mUserTypes.get(userType); 3295 final int flags = userTypeDetails != null ? userTypeDetails.getDefaultUserInfoFlags() : 0; 3296 3297 checkManageOrCreateUsersPermission(flags); 3298 3299 Preconditions.checkArgument(isUserTypeEligibleForPreCreation(userTypeDetails), 3300 "cannot pre-create user of type " + userType); 3301 Slog.i(LOG_TAG, "Pre-creating user of type " + userType); 3302 3303 try { 3304 return createUserInternalUnchecked(/* name= */ null, userType, flags, 3305 /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true, 3306 /* disallowedPackages= */ null); 3307 } catch (UserManager.CheckedUserOperationException e) { 3308 throw e.toServiceSpecificException(); 3309 } 3310 } 3311 createUserInternal(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, @Nullable String[] disallowedPackages)3312 private UserInfo createUserInternal(@Nullable String name, @NonNull String userType, 3313 @UserInfoFlag int flags, @UserIdInt int parentId, 3314 @Nullable String[] disallowedPackages) 3315 throws UserManager.CheckedUserOperationException { 3316 String restriction = (UserManager.isUserTypeManagedProfile(userType)) 3317 ? UserManager.DISALLOW_ADD_MANAGED_PROFILE 3318 : UserManager.DISALLOW_ADD_USER; 3319 enforceUserRestriction(restriction, UserHandle.getCallingUserId(), 3320 "Cannot add user"); 3321 return createUserInternalUnchecked(name, userType, flags, parentId, 3322 /* preCreate= */ false, disallowedPackages); 3323 } 3324 createUserInternalUnchecked(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages)3325 private UserInfo createUserInternalUnchecked(@Nullable String name, 3326 @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, 3327 boolean preCreate, @Nullable String[] disallowedPackages) 3328 throws UserManager.CheckedUserOperationException { 3329 final int nextProbableUserId = getNextAvailableId(); 3330 final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); 3331 t.traceBegin("createUser-" + flags); 3332 final long sessionId = logUserCreateJourneyBegin(nextProbableUserId, userType, flags); 3333 UserInfo newUser = null; 3334 try { 3335 newUser = createUserInternalUncheckedNoTracing(name, userType, flags, parentId, 3336 preCreate, disallowedPackages, t); 3337 return newUser; 3338 } finally { 3339 logUserCreateJourneyFinish(sessionId, nextProbableUserId, newUser != null); 3340 t.traceEnd(); 3341 } 3342 } 3343 logUserCreateJourneyBegin(@serIdInt int userId, String userType, @UserInfoFlag int flags)3344 private long logUserCreateJourneyBegin(@UserIdInt int userId, String userType, 3345 @UserInfoFlag int flags) { 3346 final long sessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE); 3347 // log the journey atom with the user metadata 3348 FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, sessionId, 3349 FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE, 3350 /* origin_user= */ -1, userId, UserManager.getUserTypeForStatsd(userType), flags); 3351 // log the event atom to indicate the event start 3352 FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, 3353 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER, 3354 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN); 3355 return sessionId; 3356 } 3357 logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId, boolean finish)3358 private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId, boolean finish) { 3359 FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, 3360 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER, 3361 finish ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH 3362 : FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE); 3363 } 3364 createUserInternalUncheckedNoTracing(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t)3365 private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name, 3366 @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, 3367 boolean preCreate, @Nullable String[] disallowedPackages, 3368 @NonNull TimingsTraceAndSlog t) throws UserManager.CheckedUserOperationException { 3369 final UserTypeDetails userTypeDetails = mUserTypes.get(userType); 3370 if (userTypeDetails == null) { 3371 Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType); 3372 return null; 3373 } 3374 userType = userType.intern(); // Now that we know it's valid, we can intern it. 3375 flags |= userTypeDetails.getDefaultUserInfoFlags(); 3376 if (!checkUserTypeConsistency(flags)) { 3377 Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags) 3378 + ") and userTypeDetails (" + userType + ") are inconsistent."); 3379 return null; 3380 } 3381 if ((flags & UserInfo.FLAG_SYSTEM) != 0) { 3382 Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags) 3383 + ") indicated SYSTEM user, which cannot be created."); 3384 return null; 3385 } 3386 synchronized (mUsersLock) { 3387 if (mForceEphemeralUsers) { 3388 flags |= UserInfo.FLAG_EPHEMERAL; 3389 } 3390 } 3391 3392 // Try to use a pre-created user (if available). 3393 if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) { 3394 final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name); 3395 if (preCreatedUser != null) { 3396 return preCreatedUser; 3397 } 3398 } 3399 3400 DeviceStorageMonitorInternal dsm = LocalServices 3401 .getService(DeviceStorageMonitorInternal.class); 3402 if (dsm.isMemoryLow()) { 3403 throwCheckedUserOperationException("Cannot add user. Not enough space on disk.", 3404 UserManager.USER_OPERATION_ERROR_LOW_STORAGE); 3405 } 3406 3407 final boolean isProfile = userTypeDetails.isProfile(); 3408 final boolean isGuest = UserManager.isUserTypeGuest(userType); 3409 final boolean isRestricted = UserManager.isUserTypeRestricted(userType); 3410 final boolean isDemo = UserManager.isUserTypeDemo(userType); 3411 3412 final long ident = Binder.clearCallingIdentity(); 3413 UserInfo userInfo; 3414 UserData userData; 3415 final int userId; 3416 try { 3417 synchronized (mPackagesLock) { 3418 UserData parent = null; 3419 if (parentId != UserHandle.USER_NULL) { 3420 synchronized (mUsersLock) { 3421 parent = getUserDataLU(parentId); 3422 } 3423 if (parent == null) { 3424 throwCheckedUserOperationException( 3425 "Cannot find user data for parent user " + parentId, 3426 UserManager.USER_OPERATION_ERROR_UNKNOWN); 3427 } 3428 } 3429 if (!preCreate && !canAddMoreUsersOfType(userTypeDetails)) { 3430 throwCheckedUserOperationException("Cannot add more users of type " + userType 3431 + ". Maximum number of that type already exists.", 3432 UserManager.USER_OPERATION_ERROR_MAX_USERS); 3433 } 3434 // TODO(b/142482943): Perhaps let the following code apply to restricted users too. 3435 if (isProfile && !canAddMoreProfilesToUser(userType, parentId, false)) { 3436 throwCheckedUserOperationException( 3437 "Cannot add more profiles of type " + userType 3438 + " for user " + parentId, 3439 UserManager.USER_OPERATION_ERROR_MAX_USERS); 3440 } 3441 if (!isGuest && !isProfile && !isDemo && isUserLimitReached()) { 3442 // If we're not adding a guest/demo user or a profile and the 'user limit' has 3443 // been reached, cannot add a user. 3444 throwCheckedUserOperationException( 3445 "Cannot add user. Maximum user limit is reached.", 3446 UserManager.USER_OPERATION_ERROR_MAX_USERS); 3447 } 3448 // In legacy mode, restricted profile's parent can only be the owner user 3449 if (isRestricted && !UserManager.isSplitSystemUser() 3450 && (parentId != UserHandle.USER_SYSTEM)) { 3451 throwCheckedUserOperationException( 3452 "Cannot add restricted profile - parent user must be owner", 3453 UserManager.USER_OPERATION_ERROR_UNKNOWN); 3454 } 3455 if (isRestricted && UserManager.isSplitSystemUser()) { 3456 if (parent == null) { 3457 throwCheckedUserOperationException( 3458 "Cannot add restricted profile - parent user must be specified", 3459 UserManager.USER_OPERATION_ERROR_UNKNOWN); 3460 } 3461 if (!parent.info.canHaveProfile()) { 3462 throwCheckedUserOperationException( 3463 "Cannot add restricted profile - profiles cannot be created for " 3464 + "the specified parent user id " 3465 + parentId, 3466 UserManager.USER_OPERATION_ERROR_UNKNOWN); 3467 } 3468 } 3469 3470 userId = getNextAvailableId(); 3471 Environment.getUserSystemDirectory(userId).mkdirs(); 3472 3473 synchronized (mUsersLock) { 3474 // Inherit ephemeral flag from parent. 3475 if (parent != null && parent.info.isEphemeral()) { 3476 flags |= UserInfo.FLAG_EPHEMERAL; 3477 } 3478 3479 // Always clear EPHEMERAL for pre-created users, otherwise the storage key 3480 // won't be persisted. The flag will be re-added (if needed) when the 3481 // pre-created user is "converted" to a normal user. 3482 if (preCreate) { 3483 flags &= ~UserInfo.FLAG_EPHEMERAL; 3484 } 3485 3486 userInfo = new UserInfo(userId, name, null, flags, userType); 3487 userInfo.serialNumber = mNextSerialNumber++; 3488 userInfo.creationTime = getCreationTime(); 3489 userInfo.partial = true; 3490 userInfo.preCreated = preCreate; 3491 userInfo.lastLoggedInFingerprint = Build.FINGERPRINT; 3492 if (userTypeDetails.hasBadge() && parentId != UserHandle.USER_NULL) { 3493 userInfo.profileBadge = getFreeProfileBadgeLU(parentId, userType); 3494 } 3495 userData = new UserData(); 3496 userData.info = userInfo; 3497 mUsers.put(userId, userData); 3498 } 3499 writeUserLP(userData); 3500 writeUserListLP(); 3501 if (parent != null) { 3502 if (isProfile) { 3503 if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 3504 parent.info.profileGroupId = parent.info.id; 3505 writeUserLP(parent); 3506 } 3507 userInfo.profileGroupId = parent.info.profileGroupId; 3508 } else if (isRestricted) { 3509 if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) { 3510 parent.info.restrictedProfileParentId = parent.info.id; 3511 writeUserLP(parent); 3512 } 3513 userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId; 3514 } 3515 } 3516 } 3517 3518 t.traceBegin("createUserKey"); 3519 final StorageManager storage = mContext.getSystemService(StorageManager.class); 3520 storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral()); 3521 t.traceEnd(); 3522 3523 t.traceBegin("prepareUserData"); 3524 mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber, 3525 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 3526 t.traceEnd(); 3527 3528 final Set<String> userTypeInstallablePackages = 3529 mSystemPackageInstaller.getInstallablePackagesForUserType(userType); 3530 t.traceBegin("PM.createNewUser"); 3531 mPm.createNewUser(userId, userTypeInstallablePackages, disallowedPackages); 3532 t.traceEnd(); 3533 3534 userInfo.partial = false; 3535 synchronized (mPackagesLock) { 3536 writeUserLP(userData); 3537 } 3538 updateUserIds(); 3539 3540 Bundle restrictions = new Bundle(); 3541 if (isGuest) { 3542 // Guest default restrictions can be modified via setDefaultGuestRestrictions. 3543 synchronized (mGuestRestrictions) { 3544 restrictions.putAll(mGuestRestrictions); 3545 } 3546 } else { 3547 userTypeDetails.addDefaultRestrictionsTo(restrictions); 3548 } 3549 synchronized (mRestrictionsLock) { 3550 mBaseUserRestrictions.updateRestrictions(userId, restrictions); 3551 } 3552 3553 t.traceBegin("PM.onNewUserCreated-" + userId); 3554 mPm.onNewUserCreated(userId); 3555 t.traceEnd(); 3556 if (preCreate) { 3557 // Must start user (which will be stopped right away, through 3558 // UserController.finishUserUnlockedCompleted) so services can properly 3559 // intialize it. 3560 // TODO(b/143092698): in the long-term, it might be better to add a onCreateUser() 3561 // callback on SystemService instead. 3562 Slog.i(LOG_TAG, "starting pre-created user " + userInfo.toFullString()); 3563 final IActivityManager am = ActivityManager.getService(); 3564 try { 3565 am.startUserInBackground(userId); 3566 } catch (RemoteException e) { 3567 Slog.w(LOG_TAG, "could not start pre-created user " + userId, e); 3568 } 3569 } else { 3570 dispatchUserAdded(userInfo); 3571 } 3572 3573 } finally { 3574 Binder.restoreCallingIdentity(ident); 3575 } 3576 3577 // TODO(b/143092698): it's possible to reach "max users overflow" when the user is created 3578 // "from scratch" (i.e., not from a pre-created user) and reaches the maximum number of 3579 // users without counting the pre-created one. Then when the pre-created is converted, the 3580 // "effective" number of max users is exceeds. Example: 3581 // Max: 3 Current: 2 full (u0 and u10) + 1 pre-created (u11) 3582 // Step 1: create(/* flags doesn't match u11 */): u12 is created, "effective max" is now 3 3583 // (u0, u10, u12) but "real" max is 4 (u0, u10, u11, u12) 3584 // Step 2: create(/* flags match u11 */): u11 is converted, now "effective max" is also 4 3585 // (u0, u10, u11, u12) 3586 // One way to avoid this issue is by removing a pre-created user from the pool when the 3587 // "real" max exceeds the max here. 3588 3589 return userInfo; 3590 } 3591 3592 /** 3593 * Finds and converts a previously pre-created user into a regular user, if possible. 3594 * 3595 * @return the converted user, or {@code null} if no pre-created user could be converted. 3596 */ convertPreCreatedUserIfPossible(String userType, @UserInfoFlag int flags, String name)3597 private @Nullable UserInfo convertPreCreatedUserIfPossible(String userType, 3598 @UserInfoFlag int flags, String name) { 3599 final UserData preCreatedUserData; 3600 synchronized (mUsersLock) { 3601 preCreatedUserData = getPreCreatedUserLU(userType); 3602 } 3603 if (preCreatedUserData == null) { 3604 return null; 3605 } 3606 final UserInfo preCreatedUser = preCreatedUserData.info; 3607 final int newFlags = preCreatedUser.flags | flags; 3608 if (!checkUserTypeConsistency(newFlags)) { 3609 Slog.wtf(LOG_TAG, "Cannot reuse pre-created user " + preCreatedUser.id 3610 + " of type " + userType + " because flags are inconsistent. " 3611 + "Flags (" + Integer.toHexString(flags) + "); preCreatedUserFlags ( " 3612 + Integer.toHexString(preCreatedUser.flags) + ")."); 3613 return null; 3614 } 3615 Slog.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " of type " 3616 + userType + " and bestowing on it flags " + UserInfo.flagsToString(flags)); 3617 preCreatedUser.name = name; 3618 preCreatedUser.flags = newFlags; 3619 preCreatedUser.preCreated = false; 3620 preCreatedUser.convertedFromPreCreated = true; 3621 preCreatedUser.creationTime = getCreationTime(); 3622 3623 synchronized (mPackagesLock) { 3624 writeUserLP(preCreatedUserData); 3625 writeUserListLP(); 3626 } 3627 updateUserIds(); 3628 if (!mPm.readPermissionStateForUser(preCreatedUser.id)) { 3629 // Could not read the existing permissions, re-grant them. 3630 mPm.onNewUserCreated(preCreatedUser.id); 3631 } 3632 dispatchUserAdded(preCreatedUser); 3633 return preCreatedUser; 3634 } 3635 3636 /** Checks that the flags do not contain mutually exclusive types/properties. */ checkUserTypeConsistency(@serInfoFlag int flags)3637 static boolean checkUserTypeConsistency(@UserInfoFlag int flags) { 3638 // Mask to check that flags don't refer to multiple user types. 3639 final int userTypeFlagMask = UserInfo.FLAG_GUEST | UserInfo.FLAG_DEMO 3640 | UserInfo.FLAG_RESTRICTED | UserInfo.FLAG_PROFILE; 3641 return isAtMostOneFlag(flags & userTypeFlagMask) 3642 && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_FULL)) 3643 && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_SYSTEM)); 3644 } 3645 3646 /** Returns whether the given flags contains at most one 1. */ isAtMostOneFlag(int flags)3647 private static boolean isAtMostOneFlag(int flags) { 3648 return (flags & (flags - 1)) == 0; 3649 // If !=0, this means that flags is not a power of 2, and therefore is multiple types. 3650 } 3651 3652 /** Install/uninstall system packages for all users based on their user-type, as applicable. */ installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> existingPackages)3653 boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, 3654 @Nullable ArraySet<String> existingPackages) { 3655 return mSystemPackageInstaller.installWhitelistedSystemPackages( 3656 isFirstBoot, isUpgrade, existingPackages); 3657 } 3658 getCreationTime()3659 private long getCreationTime() { 3660 final long now = System.currentTimeMillis(); 3661 return (now > EPOCH_PLUS_30_YEARS) ? now : 0; 3662 } 3663 dispatchUserAdded(@onNull UserInfo userInfo)3664 private void dispatchUserAdded(@NonNull UserInfo userInfo) { 3665 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED); 3666 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id); 3667 // Also, add the UserHandle for mainline modules which can't use the @hide 3668 // EXTRA_USER_HANDLE. 3669 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userInfo.id)); 3670 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 3671 android.Manifest.permission.MANAGE_USERS); 3672 MetricsLogger.count(mContext, userInfo.isGuest() ? TRON_GUEST_CREATED 3673 : (userInfo.isDemo() ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1); 3674 3675 if (!userInfo.isProfile()) { 3676 // If the user switch hasn't been explicitly toggled on or off by the user, turn it on. 3677 if (android.provider.Settings.Global.getString(mContext.getContentResolver(), 3678 android.provider.Settings.Global.USER_SWITCHER_ENABLED) == null) { 3679 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 3680 android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1); 3681 } 3682 } 3683 } 3684 3685 /** 3686 * Gets a pre-created user for the given user type. 3687 * 3688 * <p>Should be used only during user creation, so the pre-created user can be used (instead of 3689 * creating and initializing a new user from scratch). 3690 */ 3691 // TODO(b/143092698): add unit test 3692 @GuardedBy("mUsersLock") getPreCreatedUserLU(String userType)3693 private @Nullable UserData getPreCreatedUserLU(String userType) { 3694 if (DBG) Slog.d(LOG_TAG, "getPreCreatedUser(): userType= " + userType); 3695 final int userSize = mUsers.size(); 3696 for (int i = 0; i < userSize; i++) { 3697 final UserData user = mUsers.valueAt(i); 3698 if (DBG) Slog.d(LOG_TAG, i + ":" + user.info.toFullString()); 3699 if (user.info.preCreated && user.info.userType.equals(userType)) { 3700 if (!user.info.isInitialized()) { 3701 Slog.w(LOG_TAG, "found pre-created user of type " + userType 3702 + ", but it's not initialized yet: " + user.info.toFullString()); 3703 continue; 3704 } 3705 return user; 3706 } 3707 } 3708 return null; 3709 } 3710 3711 /** 3712 * Returns whether a user with the given userTypeDetails is eligible to be 3713 * {@link UserInfo#preCreated}. 3714 */ isUserTypeEligibleForPreCreation(UserTypeDetails userTypeDetails)3715 private static boolean isUserTypeEligibleForPreCreation(UserTypeDetails userTypeDetails) { 3716 if (userTypeDetails == null) { 3717 return false; 3718 } 3719 return !userTypeDetails.isProfile() 3720 && !userTypeDetails.getName().equals(UserManager.USER_TYPE_FULL_RESTRICTED); 3721 } 3722 3723 @VisibleForTesting putUserInfo(UserInfo userInfo)3724 UserData putUserInfo(UserInfo userInfo) { 3725 final UserData userData = new UserData(); 3726 userData.info = userInfo; 3727 synchronized (mUsers) { 3728 mUsers.put(userInfo.id, userData); 3729 } 3730 return userData; 3731 } 3732 3733 @VisibleForTesting removeUserInfo(@serIdInt int userId)3734 void removeUserInfo(@UserIdInt int userId) { 3735 synchronized (mUsers) { 3736 mUsers.remove(userId); 3737 } 3738 } 3739 3740 /** 3741 * @hide 3742 */ 3743 @Override createRestrictedProfileWithThrow(String name, int parentUserId)3744 public UserInfo createRestrictedProfileWithThrow(String name, int parentUserId) { 3745 checkManageOrCreateUsersPermission("setupRestrictedProfile"); 3746 final UserInfo user = createProfileForUserWithThrow( 3747 name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null); 3748 if (user == null) { 3749 return null; 3750 } 3751 long identity = Binder.clearCallingIdentity(); 3752 try { 3753 setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id); 3754 // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise 3755 // the putIntForUser() will fail. 3756 android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(), 3757 android.provider.Settings.Secure.LOCATION_MODE, 3758 android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id); 3759 setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id); 3760 } finally { 3761 Binder.restoreCallingIdentity(identity); 3762 } 3763 return user; 3764 } 3765 3766 /** 3767 * Find the current guest user. If the Guest user is partial, 3768 * then do not include it in the results as it is about to die. 3769 * 3770 * @return The current guest user. Null if it doesn't exist. 3771 * @hide 3772 */ 3773 @Override findCurrentGuestUser()3774 public UserInfo findCurrentGuestUser() { 3775 checkManageUsersPermission("findCurrentGuestUser"); 3776 synchronized (mUsersLock) { 3777 final int size = mUsers.size(); 3778 for (int i = 0; i < size; i++) { 3779 final UserInfo user = mUsers.valueAt(i).info; 3780 if (user.isGuest() && !user.guestToRemove && !user.preCreated 3781 && !mRemovingUserIds.get(user.id)) { 3782 return user; 3783 } 3784 } 3785 } 3786 return null; 3787 } 3788 3789 /** 3790 * Mark this guest user for deletion to allow us to create another guest 3791 * and switch to that user before actually removing this guest. 3792 * @param userId the userid of the current guest 3793 * @return whether the user could be marked for deletion 3794 */ 3795 @Override markGuestForDeletion(@serIdInt int userId)3796 public boolean markGuestForDeletion(@UserIdInt int userId) { 3797 checkManageUsersPermission("Only the system can remove users"); 3798 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 3799 UserManager.DISALLOW_REMOVE_USER, false)) { 3800 Slog.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 3801 return false; 3802 } 3803 3804 long ident = Binder.clearCallingIdentity(); 3805 try { 3806 final UserData userData; 3807 synchronized (mPackagesLock) { 3808 synchronized (mUsersLock) { 3809 userData = mUsers.get(userId); 3810 if (userId == 0 || userData == null || mRemovingUserIds.get(userId)) { 3811 return false; 3812 } 3813 } 3814 if (!userData.info.isGuest()) { 3815 return false; 3816 } 3817 // We set this to a guest user that is to be removed. This is a temporary state 3818 // where we are allowed to add new Guest users, even if this one is still not 3819 // removed. This user will still show up in getUserInfo() calls. 3820 // If we don't get around to removing this Guest user, it will be purged on next 3821 // startup. 3822 userData.info.guestToRemove = true; 3823 // Mark it as disabled, so that it isn't returned any more when 3824 // profiles are queried. 3825 userData.info.flags |= UserInfo.FLAG_DISABLED; 3826 writeUserLP(userData); 3827 } 3828 } finally { 3829 Binder.restoreCallingIdentity(ident); 3830 } 3831 return true; 3832 } 3833 3834 /** 3835 * Removes a user and all data directories created for that user. This method should be called 3836 * after the user's processes have been terminated. 3837 * @param userId the user's id 3838 */ 3839 @Override removeUser(@serIdInt int userId)3840 public boolean removeUser(@UserIdInt int userId) { 3841 Slog.i(LOG_TAG, "removeUser u" + userId); 3842 checkManageOrCreateUsersPermission("Only the system can remove users"); 3843 3844 final boolean isManagedProfile; 3845 synchronized (mUsersLock) { 3846 UserInfo userInfo = getUserInfoLU(userId); 3847 isManagedProfile = userInfo != null && userInfo.isManagedProfile(); 3848 } 3849 String restriction = isManagedProfile 3850 ? UserManager.DISALLOW_REMOVE_MANAGED_PROFILE : UserManager.DISALLOW_REMOVE_USER; 3851 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) { 3852 Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled."); 3853 return false; 3854 } 3855 return removeUserUnchecked(userId); 3856 } 3857 3858 @Override removeUserEvenWhenDisallowed(@serIdInt int userId)3859 public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) { 3860 checkManageOrCreateUsersPermission("Only the system can remove users"); 3861 return removeUserUnchecked(userId); 3862 } 3863 removeUserUnchecked(@serIdInt int userId)3864 private boolean removeUserUnchecked(@UserIdInt int userId) { 3865 long ident = Binder.clearCallingIdentity(); 3866 try { 3867 final UserData userData; 3868 int currentUser = ActivityManager.getCurrentUser(); 3869 if (currentUser == userId) { 3870 Slog.w(LOG_TAG, "Current user cannot be removed."); 3871 return false; 3872 } 3873 synchronized (mPackagesLock) { 3874 synchronized (mUsersLock) { 3875 userData = mUsers.get(userId); 3876 if (userId == UserHandle.USER_SYSTEM) { 3877 Slog.e(LOG_TAG, "System user cannot be removed."); 3878 return false; 3879 } 3880 3881 if (userData == null) { 3882 Slog.e(LOG_TAG, String.format( 3883 "Cannot remove user %d, invalid user id provided.", userId)); 3884 return false; 3885 } 3886 3887 if (mRemovingUserIds.get(userId)) { 3888 Slog.e(LOG_TAG, String.format( 3889 "User %d is already scheduled for removal.", userId)); 3890 return false; 3891 } 3892 3893 addRemovingUserIdLocked(userId); 3894 } 3895 3896 // Set this to a partially created user, so that the user will be purged 3897 // on next startup, in case the runtime stops now before stopping and 3898 // removing the user completely. 3899 userData.info.partial = true; 3900 // Mark it as disabled, so that it isn't returned any more when 3901 // profiles are queried. 3902 userData.info.flags |= UserInfo.FLAG_DISABLED; 3903 writeUserLP(userData); 3904 } 3905 try { 3906 mAppOpsService.removeUser(userId); 3907 } catch (RemoteException e) { 3908 Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e); 3909 } 3910 3911 // TODO(b/142482943): Send some sort of broadcast for profiles even if non-managed? 3912 if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 3913 && userData.info.isManagedProfile()) { 3914 // Send broadcast to notify system that the user removed was a 3915 // managed user. 3916 sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id); 3917 } 3918 3919 if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId); 3920 int res; 3921 try { 3922 res = ActivityManager.getService().stopUser(userId, /* force= */ true, 3923 new IStopUserCallback.Stub() { 3924 @Override 3925 public void userStopped(int userIdParam) { 3926 finishRemoveUser(userIdParam); 3927 } 3928 @Override 3929 public void userStopAborted(int userIdParam) { 3930 } 3931 }); 3932 } catch (RemoteException e) { 3933 Slog.w(LOG_TAG, "Failed to stop user during removal.", e); 3934 return false; 3935 } 3936 return res == ActivityManager.USER_OP_SUCCESS; 3937 } finally { 3938 Binder.restoreCallingIdentity(ident); 3939 } 3940 } 3941 3942 @GuardedBy("mUsersLock") 3943 @VisibleForTesting addRemovingUserIdLocked(@serIdInt int userId)3944 void addRemovingUserIdLocked(@UserIdInt int userId) { 3945 // We remember deleted user IDs to prevent them from being 3946 // reused during the current boot; they can still be reused 3947 // after a reboot or recycling of userIds. 3948 mRemovingUserIds.put(userId, true); 3949 mRecentlyRemovedIds.add(userId); 3950 // Keep LRU queue of recently removed IDs for recycling 3951 if (mRecentlyRemovedIds.size() > MAX_RECENTLY_REMOVED_IDS_SIZE) { 3952 mRecentlyRemovedIds.removeFirst(); 3953 } 3954 } 3955 finishRemoveUser(final @UserIdInt int userId)3956 void finishRemoveUser(final @UserIdInt int userId) { 3957 if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userId); 3958 // Let other services shutdown any activity and clean up their state before completely 3959 // wiping the user's system directory and removing from the user list 3960 long ident = Binder.clearCallingIdentity(); 3961 try { 3962 Intent removedIntent = new Intent(Intent.ACTION_USER_REMOVED); 3963 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3964 // Also, add the UserHandle for mainline modules which can't use the @hide 3965 // EXTRA_USER_HANDLE. 3966 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); 3967 mContext.sendOrderedBroadcastAsUser(removedIntent, UserHandle.ALL, 3968 android.Manifest.permission.MANAGE_USERS, 3969 3970 new BroadcastReceiver() { 3971 @Override 3972 public void onReceive(Context context, Intent intent) { 3973 if (DBG) { 3974 Slog.i(LOG_TAG, 3975 "USER_REMOVED broadcast sent, cleaning up user data " 3976 + userId); 3977 } 3978 new Thread() { 3979 @Override 3980 public void run() { 3981 LocalServices.getService(ActivityManagerInternal.class) 3982 .onUserRemoved(userId); 3983 removeUserState(userId); 3984 } 3985 }.start(); 3986 } 3987 }, 3988 3989 null, Activity.RESULT_OK, null, null); 3990 } finally { 3991 Binder.restoreCallingIdentity(ident); 3992 } 3993 } 3994 removeUserState(final @UserIdInt int userId)3995 private void removeUserState(final @UserIdInt int userId) { 3996 try { 3997 mContext.getSystemService(StorageManager.class).destroyUserKey(userId); 3998 } catch (IllegalStateException e) { 3999 // This may be simply because the user was partially created. 4000 Slog.i(LOG_TAG, "Destroying key for user " + userId + " failed, continuing anyway", e); 4001 } 4002 4003 // Cleanup gatekeeper secure user id 4004 try { 4005 final IGateKeeperService gk = GateKeeper.getService(); 4006 if (gk != null) { 4007 gk.clearSecureUserId(userId); 4008 } 4009 } catch (Exception ex) { 4010 Slog.w(LOG_TAG, "unable to clear GK secure user id"); 4011 } 4012 4013 // Cleanup package manager settings 4014 mPm.cleanUpUser(this, userId); 4015 4016 // Clean up all data before removing metadata 4017 mUserDataPreparer.destroyUserData(userId, 4018 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 4019 4020 // Remove this user from the list 4021 synchronized (mUsersLock) { 4022 mUsers.remove(userId); 4023 mIsUserManaged.delete(userId); 4024 } 4025 synchronized (mUserStates) { 4026 mUserStates.delete(userId); 4027 } 4028 synchronized (mRestrictionsLock) { 4029 mBaseUserRestrictions.remove(userId); 4030 mAppliedUserRestrictions.remove(userId); 4031 mCachedEffectiveUserRestrictions.remove(userId); 4032 // Remove local restrictions affecting user 4033 mDevicePolicyLocalUserRestrictions.delete(userId); 4034 // Remove local restrictions set by user 4035 boolean changed = false; 4036 for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) { 4037 int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i); 4038 changed |= getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId) 4039 .remove(userId); 4040 } 4041 changed |= mDevicePolicyGlobalUserRestrictions.remove(userId); 4042 if (changed) { 4043 applyUserRestrictionsForAllUsersLR(); 4044 } 4045 } 4046 // Update the user list 4047 synchronized (mPackagesLock) { 4048 writeUserListLP(); 4049 } 4050 // Remove user file 4051 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userId + XML_SUFFIX)); 4052 userFile.delete(); 4053 updateUserIds(); 4054 if (RELEASE_DELETED_USER_ID) { 4055 synchronized (mUsers) { 4056 mRemovingUserIds.delete(userId); 4057 } 4058 } 4059 } 4060 sendProfileRemovedBroadcast(int parentUserId, int removedUserId)4061 private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { 4062 Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); 4063 managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); 4064 managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); 4065 final UserHandle parentHandle = new UserHandle(parentUserId); 4066 getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser( 4067 managedProfileIntent, parentHandle, /* requiresPermission= */ false); 4068 managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4069 | Intent.FLAG_RECEIVER_FOREGROUND); 4070 mContext.sendBroadcastAsUser(managedProfileIntent, parentHandle, 4071 /* receiverPermission= */null); 4072 } 4073 4074 @Override getApplicationRestrictions(String packageName)4075 public Bundle getApplicationRestrictions(String packageName) { 4076 return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId()); 4077 } 4078 4079 @Override getApplicationRestrictionsForUser(String packageName, @UserIdInt int userId)4080 public Bundle getApplicationRestrictionsForUser(String packageName, @UserIdInt int userId) { 4081 if (UserHandle.getCallingUserId() != userId 4082 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { 4083 checkSystemOrRoot("get application restrictions for other user/app " + packageName); 4084 } 4085 synchronized (mAppRestrictionsLock) { 4086 // Read the restrictions from XML 4087 return readApplicationRestrictionsLAr(packageName, userId); 4088 } 4089 } 4090 4091 @Override setApplicationRestrictions(String packageName, Bundle restrictions, @UserIdInt int userId)4092 public void setApplicationRestrictions(String packageName, Bundle restrictions, 4093 @UserIdInt int userId) { 4094 checkSystemOrRoot("set application restrictions"); 4095 if (restrictions != null) { 4096 restrictions.setDefusable(true); 4097 } 4098 final boolean changed; 4099 synchronized (mAppRestrictionsLock) { 4100 if (restrictions == null || restrictions.isEmpty()) { 4101 changed = cleanAppRestrictionsForPackageLAr(packageName, userId); 4102 } else { 4103 // Write the restrictions to XML 4104 writeApplicationRestrictionsLAr(packageName, restrictions, userId); 4105 // TODO(b/154323615): avoid unnecessary broadcast when there is no change. 4106 changed = true; 4107 } 4108 } 4109 4110 if (!changed) { 4111 return; 4112 } 4113 4114 // Notify package of changes via an intent - only sent to explicitly registered receivers. 4115 final Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); 4116 changeIntent.setPackage(packageName); 4117 changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 4118 mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId)); 4119 } 4120 getUidForPackage(String packageName)4121 private int getUidForPackage(String packageName) { 4122 long ident = Binder.clearCallingIdentity(); 4123 try { 4124 return mContext.getPackageManager().getApplicationInfo(packageName, 4125 PackageManager.MATCH_ANY_USER).uid; 4126 } catch (NameNotFoundException nnfe) { 4127 return -1; 4128 } finally { 4129 Binder.restoreCallingIdentity(ident); 4130 } 4131 } 4132 4133 @GuardedBy("mAppRestrictionsLock") readApplicationRestrictionsLAr(String packageName, @UserIdInt int userId)4134 private static Bundle readApplicationRestrictionsLAr(String packageName, 4135 @UserIdInt int userId) { 4136 AtomicFile restrictionsFile = 4137 new AtomicFile(new File(Environment.getUserSystemDirectory(userId), 4138 packageToRestrictionsFileName(packageName))); 4139 return readApplicationRestrictionsLAr(restrictionsFile); 4140 } 4141 4142 @VisibleForTesting 4143 @GuardedBy("mAppRestrictionsLock") readApplicationRestrictionsLAr(AtomicFile restrictionsFile)4144 static Bundle readApplicationRestrictionsLAr(AtomicFile restrictionsFile) { 4145 final Bundle restrictions = new Bundle(); 4146 final ArrayList<String> values = new ArrayList<>(); 4147 if (!restrictionsFile.getBaseFile().exists()) { 4148 return restrictions; 4149 } 4150 4151 FileInputStream fis = null; 4152 try { 4153 fis = restrictionsFile.openRead(); 4154 XmlPullParser parser = Xml.newPullParser(); 4155 parser.setInput(fis, StandardCharsets.UTF_8.name()); 4156 XmlUtils.nextElement(parser); 4157 if (parser.getEventType() != XmlPullParser.START_TAG) { 4158 Slog.e(LOG_TAG, "Unable to read restrictions file " 4159 + restrictionsFile.getBaseFile()); 4160 return restrictions; 4161 } 4162 while (parser.next() != XmlPullParser.END_DOCUMENT) { 4163 readEntry(restrictions, values, parser); 4164 } 4165 } catch (IOException|XmlPullParserException e) { 4166 Slog.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e); 4167 } finally { 4168 IoUtils.closeQuietly(fis); 4169 } 4170 return restrictions; 4171 } 4172 readEntry(Bundle restrictions, ArrayList<String> values, XmlPullParser parser)4173 private static void readEntry(Bundle restrictions, ArrayList<String> values, 4174 XmlPullParser parser) throws XmlPullParserException, IOException { 4175 int type = parser.getEventType(); 4176 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) { 4177 String key = parser.getAttributeValue(null, ATTR_KEY); 4178 String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE); 4179 String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE); 4180 if (multiple != null) { 4181 values.clear(); 4182 int count = Integer.parseInt(multiple); 4183 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) { 4184 if (type == XmlPullParser.START_TAG 4185 && parser.getName().equals(TAG_VALUE)) { 4186 values.add(parser.nextText().trim()); 4187 count--; 4188 } 4189 } 4190 String [] valueStrings = new String[values.size()]; 4191 values.toArray(valueStrings); 4192 restrictions.putStringArray(key, valueStrings); 4193 } else if (ATTR_TYPE_BUNDLE.equals(valType)) { 4194 restrictions.putBundle(key, readBundleEntry(parser, values)); 4195 } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) { 4196 final int outerDepth = parser.getDepth(); 4197 ArrayList<Bundle> bundleList = new ArrayList<>(); 4198 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 4199 Bundle childBundle = readBundleEntry(parser, values); 4200 bundleList.add(childBundle); 4201 } 4202 restrictions.putParcelableArray(key, 4203 bundleList.toArray(new Bundle[bundleList.size()])); 4204 } else { 4205 String value = parser.nextText().trim(); 4206 if (ATTR_TYPE_BOOLEAN.equals(valType)) { 4207 restrictions.putBoolean(key, Boolean.parseBoolean(value)); 4208 } else if (ATTR_TYPE_INTEGER.equals(valType)) { 4209 restrictions.putInt(key, Integer.parseInt(value)); 4210 } else { 4211 restrictions.putString(key, value); 4212 } 4213 } 4214 } 4215 } 4216 readBundleEntry(XmlPullParser parser, ArrayList<String> values)4217 private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values) 4218 throws IOException, XmlPullParserException { 4219 Bundle childBundle = new Bundle(); 4220 final int outerDepth = parser.getDepth(); 4221 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 4222 readEntry(childBundle, values, parser); 4223 } 4224 return childBundle; 4225 } 4226 4227 @GuardedBy("mAppRestrictionsLock") writeApplicationRestrictionsLAr(String packageName, Bundle restrictions, @UserIdInt int userId)4228 private static void writeApplicationRestrictionsLAr(String packageName, 4229 Bundle restrictions, @UserIdInt int userId) { 4230 AtomicFile restrictionsFile = new AtomicFile( 4231 new File(Environment.getUserSystemDirectory(userId), 4232 packageToRestrictionsFileName(packageName))); 4233 writeApplicationRestrictionsLAr(restrictions, restrictionsFile); 4234 } 4235 4236 @VisibleForTesting 4237 @GuardedBy("mAppRestrictionsLock") writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile)4238 static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) { 4239 FileOutputStream fos = null; 4240 try { 4241 fos = restrictionsFile.startWrite(); 4242 final BufferedOutputStream bos = new BufferedOutputStream(fos); 4243 4244 final XmlSerializer serializer = new FastXmlSerializer(); 4245 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 4246 serializer.startDocument(null, true); 4247 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 4248 4249 serializer.startTag(null, TAG_RESTRICTIONS); 4250 writeBundle(restrictions, serializer); 4251 serializer.endTag(null, TAG_RESTRICTIONS); 4252 4253 serializer.endDocument(); 4254 restrictionsFile.finishWrite(fos); 4255 } catch (Exception e) { 4256 restrictionsFile.failWrite(fos); 4257 Slog.e(LOG_TAG, "Error writing application restrictions list", e); 4258 } 4259 } 4260 writeBundle(Bundle restrictions, XmlSerializer serializer)4261 private static void writeBundle(Bundle restrictions, XmlSerializer serializer) 4262 throws IOException { 4263 for (String key : restrictions.keySet()) { 4264 Object value = restrictions.get(key); 4265 serializer.startTag(null, TAG_ENTRY); 4266 serializer.attribute(null, ATTR_KEY, key); 4267 4268 if (value instanceof Boolean) { 4269 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN); 4270 serializer.text(value.toString()); 4271 } else if (value instanceof Integer) { 4272 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER); 4273 serializer.text(value.toString()); 4274 } else if (value == null || value instanceof String) { 4275 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING); 4276 serializer.text(value != null ? (String) value : ""); 4277 } else if (value instanceof Bundle) { 4278 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 4279 writeBundle((Bundle) value, serializer); 4280 } else if (value instanceof Parcelable[]) { 4281 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY); 4282 Parcelable[] array = (Parcelable[]) value; 4283 for (Parcelable parcelable : array) { 4284 if (!(parcelable instanceof Bundle)) { 4285 throw new IllegalArgumentException("bundle-array can only hold Bundles"); 4286 } 4287 serializer.startTag(null, TAG_ENTRY); 4288 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 4289 writeBundle((Bundle) parcelable, serializer); 4290 serializer.endTag(null, TAG_ENTRY); 4291 } 4292 } else { 4293 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY); 4294 String[] values = (String[]) value; 4295 serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length)); 4296 for (String choice : values) { 4297 serializer.startTag(null, TAG_VALUE); 4298 serializer.text(choice != null ? choice : ""); 4299 serializer.endTag(null, TAG_VALUE); 4300 } 4301 } 4302 serializer.endTag(null, TAG_ENTRY); 4303 } 4304 } 4305 4306 @Override getUserSerialNumber(@serIdInt int userId)4307 public int getUserSerialNumber(@UserIdInt int userId) { 4308 synchronized (mUsersLock) { 4309 final UserInfo userInfo = getUserInfoLU(userId); 4310 return userInfo != null ? userInfo.serialNumber : -1; 4311 } 4312 } 4313 4314 @Override isUserNameSet(@serIdInt int userId)4315 public boolean isUserNameSet(@UserIdInt int userId) { 4316 if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) { 4317 throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED " 4318 + "permissions to: get whether user name is set"); 4319 } 4320 synchronized (mUsersLock) { 4321 final UserInfo userInfo = getUserInfoLU(userId); 4322 return userInfo != null && userInfo.name != null; 4323 } 4324 } 4325 4326 @Override getUserHandle(int userSerialNumber)4327 public int getUserHandle(int userSerialNumber) { 4328 synchronized (mUsersLock) { 4329 for (int userId : mUserIds) { 4330 UserInfo info = getUserInfoLU(userId); 4331 if (info != null && info.serialNumber == userSerialNumber) return userId; 4332 } 4333 // Not found 4334 return -1; 4335 } 4336 } 4337 4338 @Override getUserCreationTime(@serIdInt int userId)4339 public long getUserCreationTime(@UserIdInt int userId) { 4340 int callingUserId = UserHandle.getCallingUserId(); 4341 UserInfo userInfo = null; 4342 synchronized (mUsersLock) { 4343 if (callingUserId == userId) { 4344 userInfo = getUserInfoLU(userId); 4345 } else { 4346 UserInfo parent = getProfileParentLU(userId); 4347 if (parent != null && parent.id == callingUserId) { 4348 userInfo = getUserInfoLU(userId); 4349 } 4350 } 4351 } 4352 if (userInfo == null) { 4353 throw new SecurityException("userId can only be the calling user or a managed " 4354 + "profile associated with this user"); 4355 } 4356 return userInfo.creationTime; 4357 } 4358 4359 /** 4360 * Caches the list of user ids in an array, adjusting the array size when necessary. 4361 */ updateUserIds()4362 private void updateUserIds() { 4363 int num = 0; 4364 int numIncludingPreCreated = 0; 4365 synchronized (mUsersLock) { 4366 final int userSize = mUsers.size(); 4367 for (int i = 0; i < userSize; i++) { 4368 final UserInfo userInfo = mUsers.valueAt(i).info; 4369 if (!userInfo.partial) { 4370 numIncludingPreCreated++; 4371 if (!userInfo.preCreated) { 4372 num++; 4373 } 4374 } 4375 } 4376 if (DBG) { 4377 Slog.d(LOG_TAG, "updateUserIds(): numberUsers= " + num 4378 + " includingPreCreated=" + numIncludingPreCreated); 4379 } 4380 final int[] newUsers = new int[num]; 4381 final int[] newUsersIncludingPreCreated = new int[numIncludingPreCreated]; 4382 4383 int n = 0; 4384 int nIncludingPreCreated = 0; 4385 for (int i = 0; i < userSize; i++) { 4386 final UserInfo userInfo = mUsers.valueAt(i).info; 4387 if (!userInfo.partial) { 4388 final int userId = mUsers.keyAt(i); 4389 newUsersIncludingPreCreated[nIncludingPreCreated++] = userId; 4390 if (!userInfo.preCreated) { 4391 newUsers[n++] = userId; 4392 } 4393 } 4394 } 4395 mUserIds = newUsers; 4396 mUserIdsIncludingPreCreated = newUsersIncludingPreCreated; 4397 if (DBG) { 4398 Slog.d(LOG_TAG, "updateUserIds(): userIds= " + Arrays.toString(mUserIds) 4399 + " includingPreCreated=" + Arrays.toString(mUserIdsIncludingPreCreated)); 4400 } 4401 } 4402 } 4403 4404 /** 4405 * Called right before a user is started. This gives us a chance to prepare 4406 * app storage and apply any user restrictions. 4407 */ onBeforeStartUser(@serIdInt int userId)4408 public void onBeforeStartUser(@UserIdInt int userId) { 4409 UserInfo userInfo = getUserInfo(userId); 4410 if (userInfo == null) { 4411 return; 4412 } 4413 TimingsTraceAndSlog t = new TimingsTraceAndSlog(); 4414 t.traceBegin("onBeforeStartUser-" + userId); 4415 final int userSerial = userInfo.serialNumber; 4416 // Migrate only if build fingerprints mismatch 4417 boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); 4418 t.traceBegin("prepareUserData"); 4419 mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE); 4420 t.traceEnd(); 4421 t.traceBegin("reconcileAppsData"); 4422 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData); 4423 t.traceEnd(); 4424 4425 if (userId != UserHandle.USER_SYSTEM) { 4426 t.traceBegin("applyUserRestrictions"); 4427 synchronized (mRestrictionsLock) { 4428 applyUserRestrictionsLR(userId); 4429 } 4430 t.traceEnd(); 4431 } 4432 t.traceEnd(); // onBeforeStartUser 4433 } 4434 4435 /** 4436 * Called right before a user is unlocked. This gives us a chance to prepare 4437 * app storage. 4438 */ onBeforeUnlockUser(@serIdInt int userId)4439 public void onBeforeUnlockUser(@UserIdInt int userId) { 4440 UserInfo userInfo = getUserInfo(userId); 4441 if (userInfo == null) { 4442 return; 4443 } 4444 final int userSerial = userInfo.serialNumber; 4445 // Migrate only if build fingerprints mismatch 4446 boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); 4447 mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); 4448 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData); 4449 } 4450 4451 /** 4452 * Examine all users present on given mounted volume, and destroy data 4453 * belonging to users that are no longer valid, or whose user ID has been 4454 * recycled. 4455 */ reconcileUsers(String volumeUuid)4456 void reconcileUsers(String volumeUuid) { 4457 mUserDataPreparer.reconcileUsers(volumeUuid, getUsers( 4458 /* excludePartial= */ true, 4459 /* excludeDying= */ true, 4460 /* excludePreCreated= */ false)); 4461 } 4462 4463 /** 4464 * Make a note of the last started time of a user and do some cleanup. 4465 * This is called with ActivityManagerService lock held. 4466 * @param userId the user that was just foregrounded 4467 */ onUserLoggedIn(@serIdInt int userId)4468 public void onUserLoggedIn(@UserIdInt int userId) { 4469 UserData userData = getUserDataNoChecks(userId); 4470 if (userData == null || userData.info.partial) { 4471 Slog.w(LOG_TAG, "userForeground: unknown user #" + userId); 4472 return; 4473 } 4474 4475 final long now = System.currentTimeMillis(); 4476 if (now > EPOCH_PLUS_30_YEARS) { 4477 userData.info.lastLoggedInTime = now; 4478 } 4479 userData.info.lastLoggedInFingerprint = Build.FINGERPRINT; 4480 scheduleWriteUser(userData); 4481 } 4482 4483 /** 4484 * Returns the next available user id, filling in any holes in the ids. 4485 */ 4486 @VisibleForTesting getNextAvailableId()4487 int getNextAvailableId() { 4488 int nextId; 4489 synchronized (mUsersLock) { 4490 nextId = scanNextAvailableIdLocked(); 4491 if (nextId >= 0) { 4492 return nextId; 4493 } 4494 // All ids up to MAX_USER_ID were used. Remove all mRemovingUserIds, 4495 // except most recently removed 4496 if (mRemovingUserIds.size() > 0) { 4497 Slog.i(LOG_TAG, "All available IDs are used. Recycling LRU ids."); 4498 mRemovingUserIds.clear(); 4499 for (Integer recentlyRemovedId : mRecentlyRemovedIds) { 4500 mRemovingUserIds.put(recentlyRemovedId, true); 4501 } 4502 nextId = scanNextAvailableIdLocked(); 4503 } 4504 } 4505 if (nextId < 0) { 4506 throw new IllegalStateException("No user id available!"); 4507 } 4508 return nextId; 4509 } 4510 4511 @GuardedBy("mUsersLock") scanNextAvailableIdLocked()4512 private int scanNextAvailableIdLocked() { 4513 for (int i = MIN_USER_ID; i < MAX_USER_ID; i++) { 4514 if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) { 4515 return i; 4516 } 4517 } 4518 return -1; 4519 } 4520 packageToRestrictionsFileName(String packageName)4521 private static String packageToRestrictionsFileName(String packageName) { 4522 return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX; 4523 } 4524 4525 @Override setSeedAccountData(@serIdInt int userId, String accountName, String accountType, PersistableBundle accountOptions, boolean persist)4526 public void setSeedAccountData(@UserIdInt int userId, String accountName, String accountType, 4527 PersistableBundle accountOptions, boolean persist) { 4528 checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data"); 4529 synchronized (mPackagesLock) { 4530 final UserData userData; 4531 synchronized (mUsersLock) { 4532 userData = getUserDataLU(userId); 4533 if (userData == null) { 4534 Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); 4535 return; 4536 } 4537 userData.seedAccountName = accountName; 4538 userData.seedAccountType = accountType; 4539 userData.seedAccountOptions = accountOptions; 4540 userData.persistSeedData = persist; 4541 } 4542 if (persist) { 4543 writeUserLP(userData); 4544 } 4545 } 4546 } 4547 4548 @Override getSeedAccountName()4549 public String getSeedAccountName() throws RemoteException { 4550 checkManageUsersPermission("Cannot get seed account information"); 4551 synchronized (mUsersLock) { 4552 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 4553 return userData.seedAccountName; 4554 } 4555 } 4556 4557 @Override getSeedAccountType()4558 public String getSeedAccountType() throws RemoteException { 4559 checkManageUsersPermission("Cannot get seed account information"); 4560 synchronized (mUsersLock) { 4561 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 4562 return userData.seedAccountType; 4563 } 4564 } 4565 4566 @Override getSeedAccountOptions()4567 public PersistableBundle getSeedAccountOptions() throws RemoteException { 4568 checkManageUsersPermission("Cannot get seed account information"); 4569 synchronized (mUsersLock) { 4570 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 4571 return userData.seedAccountOptions; 4572 } 4573 } 4574 4575 @Override clearSeedAccountData()4576 public void clearSeedAccountData() throws RemoteException { 4577 checkManageUsersPermission("Cannot clear seed account information"); 4578 synchronized (mPackagesLock) { 4579 UserData userData; 4580 synchronized (mUsersLock) { 4581 userData = getUserDataLU(UserHandle.getCallingUserId()); 4582 if (userData == null) return; 4583 userData.clearSeedAccountData(); 4584 } 4585 writeUserLP(userData); 4586 } 4587 } 4588 4589 @Override someUserHasSeedAccount(String accountName, String accountType)4590 public boolean someUserHasSeedAccount(String accountName, String accountType) 4591 throws RemoteException { 4592 checkManageUsersPermission("Cannot check seed account information"); 4593 synchronized (mUsersLock) { 4594 final int userSize = mUsers.size(); 4595 for (int i = 0; i < userSize; i++) { 4596 final UserData data = mUsers.valueAt(i); 4597 if (data.info.isInitialized()) continue; 4598 if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) { 4599 continue; 4600 } 4601 if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) { 4602 continue; 4603 } 4604 return true; 4605 } 4606 } 4607 return false; 4608 } 4609 4610 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)4611 public void onShellCommand(FileDescriptor in, FileDescriptor out, 4612 FileDescriptor err, String[] args, ShellCallback callback, 4613 ResultReceiver resultReceiver) { 4614 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 4615 } 4616 onShellCommand(Shell shell, String cmd)4617 int onShellCommand(Shell shell, String cmd) { 4618 if (cmd == null) { 4619 return shell.handleDefaultCommands(cmd); 4620 } 4621 4622 final PrintWriter pw = shell.getOutPrintWriter(); 4623 try { 4624 switch(cmd) { 4625 case "list": 4626 return runList(pw, shell); 4627 case "report-system-user-package-whitelist-problems": 4628 return runReportPackageWhitelistProblems(pw, shell); 4629 default: 4630 return shell.handleDefaultCommands(cmd); 4631 } 4632 } catch (RemoteException e) { 4633 pw.println("Remote exception: " + e); 4634 } 4635 return -1; 4636 } 4637 runList(PrintWriter pw, Shell shell)4638 private int runList(PrintWriter pw, Shell shell) throws RemoteException { 4639 boolean all = false; 4640 boolean verbose = false; 4641 String opt; 4642 while ((opt = shell.getNextOption()) != null) { 4643 switch (opt) { 4644 case "-v": 4645 verbose = true; 4646 break; 4647 case "--all": 4648 all = true; 4649 break; 4650 default: 4651 pw.println("Invalid option: " + opt); 4652 return -1; 4653 } 4654 } 4655 final IActivityManager am = ActivityManager.getService(); 4656 final List<UserInfo> users = getUsers(/* excludePartial= */ !all, 4657 /* excludingDying=*/ false, /* excludePreCreated= */ !all); 4658 if (users == null) { 4659 pw.println("Error: couldn't get users"); 4660 return 1; 4661 } else { 4662 final int size = users.size(); 4663 int currentUser = UserHandle.USER_NULL; 4664 if (verbose) { 4665 pw.printf("%d users:\n\n", size); 4666 currentUser = am.getCurrentUser().id; 4667 } else { 4668 // NOTE: the standard "list users" command is used by integration tests and 4669 // hence should not be changed. If you need to add more info, use the 4670 // verbose option. 4671 pw.println("Users:"); 4672 } 4673 for (int i = 0; i < size; i++) { 4674 final UserInfo user = users.get(i); 4675 final boolean running = am.isUserRunning(user.id, 0); 4676 final boolean current = user.id == currentUser; 4677 if (verbose) { 4678 pw.printf("%d: id=%d, name=%s, flags=%s%s%s%s%s\n", i, user.id, user.name, 4679 UserInfo.flagsToString(user.flags), 4680 running ? " (running)" : "", 4681 user.partial ? " (partial)" : "", 4682 user.preCreated ? " (pre-created)" : "", 4683 user.convertedFromPreCreated ? " (converted)" : "", 4684 current ? " (current)" : ""); 4685 } else { 4686 // NOTE: the standard "list users" command is used by integration tests and 4687 // hence should not be changed. If you need to add more info, use the 4688 // verbose option. 4689 pw.printf("\t%s%s\n", user, running ? " running" : ""); 4690 } 4691 } 4692 return 0; 4693 } 4694 } 4695 runReportPackageWhitelistProblems(PrintWriter pw, Shell shell)4696 private int runReportPackageWhitelistProblems(PrintWriter pw, Shell shell) { 4697 boolean verbose = false; 4698 boolean criticalOnly = false; 4699 int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE; 4700 String opt; 4701 while ((opt = shell.getNextOption()) != null) { 4702 switch (opt) { 4703 case "-v": 4704 case "--verbose": 4705 verbose = true; 4706 break; 4707 case "--critical-only": 4708 criticalOnly = true; 4709 break; 4710 case "--mode": 4711 mode = Integer.parseInt(shell.getNextArgRequired()); 4712 break; 4713 default: 4714 pw.println("Invalid option: " + opt); 4715 return -1; 4716 } 4717 } 4718 4719 Slog.d(LOG_TAG, "runReportPackageWhitelistProblems(): verbose=" + verbose 4720 + ", criticalOnly=" + criticalOnly 4721 + ", mode=" + UserSystemPackageInstaller.modeToString(mode)); 4722 4723 try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { 4724 mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, criticalOnly); 4725 } 4726 return 0; 4727 } 4728 4729 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)4730 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4731 if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; 4732 4733 long now = System.currentTimeMillis(); 4734 final long nowRealtime = SystemClock.elapsedRealtime(); 4735 4736 final ActivityManagerInternal amInternal = LocalServices 4737 .getService(ActivityManagerInternal.class); 4738 pw.print("Current user: "); 4739 if (amInternal != null) { 4740 pw.println(amInternal.getCurrentUserId()); 4741 } else { 4742 pw.println("N/A"); 4743 } 4744 4745 StringBuilder sb = new StringBuilder(); 4746 synchronized (mPackagesLock) { 4747 synchronized (mUsersLock) { 4748 pw.println("Users:"); 4749 for (int i = 0; i < mUsers.size(); i++) { 4750 UserData userData = mUsers.valueAt(i); 4751 if (userData == null) { 4752 continue; 4753 } 4754 UserInfo userInfo = userData.info; 4755 final int userId = userInfo.id; 4756 pw.print(" "); pw.print(userInfo); 4757 pw.print(" serialNo="); pw.print(userInfo.serialNumber); 4758 pw.print(" isPrimary="); pw.print(userInfo.isPrimary()); 4759 if (mRemovingUserIds.get(userId)) { 4760 pw.print(" <removing> "); 4761 } 4762 if (userInfo.partial) { 4763 pw.print(" <partial>"); 4764 } 4765 if (userInfo.preCreated) { 4766 pw.print(" <pre-created>"); 4767 } 4768 if (userInfo.convertedFromPreCreated) { 4769 pw.print(" <converted>"); 4770 } 4771 pw.println(); 4772 pw.print(" Type: "); pw.println(userInfo.userType); 4773 pw.print(" Flags: "); pw.print(userInfo.flags); pw.print(" ("); 4774 pw.print(UserInfo.flagsToString(userInfo.flags)); pw.println(")"); 4775 pw.print(" State: "); 4776 final int state; 4777 synchronized (mUserStates) { 4778 state = mUserStates.get(userId, -1); 4779 } 4780 pw.println(UserState.stateToString(state)); 4781 pw.print(" Created: "); 4782 dumpTimeAgo(pw, sb, now, userInfo.creationTime); 4783 4784 pw.print(" Last logged in: "); 4785 dumpTimeAgo(pw, sb, now, userInfo.lastLoggedInTime); 4786 4787 pw.print(" Last logged in fingerprint: "); 4788 pw.println(userInfo.lastLoggedInFingerprint); 4789 4790 pw.print(" Start time: "); 4791 dumpTimeAgo(pw, sb, nowRealtime, userData.startRealtime); 4792 4793 pw.print(" Unlock time: "); 4794 dumpTimeAgo(pw, sb, nowRealtime, userData.unlockRealtime); 4795 4796 pw.print(" Has profile owner: "); 4797 pw.println(mIsUserManaged.get(userId)); 4798 pw.println(" Restrictions:"); 4799 synchronized (mRestrictionsLock) { 4800 UserRestrictionsUtils.dumpRestrictions( 4801 pw, " ", mBaseUserRestrictions.getRestrictions(userInfo.id)); 4802 pw.println(" Device policy global restrictions:"); 4803 UserRestrictionsUtils.dumpRestrictions( 4804 pw, " ", 4805 mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id)); 4806 pw.println(" Device policy local restrictions:"); 4807 getDevicePolicyLocalRestrictionsForTargetUserLR( 4808 userInfo.id).dumpRestrictions(pw, " "); 4809 pw.println(" Effective restrictions:"); 4810 UserRestrictionsUtils.dumpRestrictions( 4811 pw, " ", 4812 mCachedEffectiveUserRestrictions.getRestrictions(userInfo.id)); 4813 } 4814 4815 if (userData.account != null) { 4816 pw.print(" Account name: " + userData.account); 4817 pw.println(); 4818 } 4819 4820 if (userData.seedAccountName != null) { 4821 pw.print(" Seed account name: " + userData.seedAccountName); 4822 pw.println(); 4823 if (userData.seedAccountType != null) { 4824 pw.print(" account type: " + userData.seedAccountType); 4825 pw.println(); 4826 } 4827 if (userData.seedAccountOptions != null) { 4828 pw.print(" account options exist"); 4829 pw.println(); 4830 } 4831 } 4832 } 4833 } 4834 pw.println(); 4835 pw.println(" Device owner id:" + mDeviceOwnerUserId); 4836 pw.println(); 4837 pw.println(" Guest restrictions:"); 4838 synchronized (mGuestRestrictions) { 4839 UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions); 4840 } 4841 synchronized (mUsersLock) { 4842 pw.println(); 4843 pw.println(" Device managed: " + mIsDeviceManaged); 4844 if (mRemovingUserIds.size() > 0) { 4845 pw.println(); 4846 pw.println(" Recently removed userIds: " + mRecentlyRemovedIds); 4847 } 4848 } 4849 synchronized (mUserStates) { 4850 pw.println(" Started users state: " + mUserStates); 4851 } 4852 synchronized (mUsersLock) { 4853 pw.print(" Cached user IDs: "); 4854 pw.println(Arrays.toString(mUserIds)); 4855 pw.print(" Cached user IDs (including pre-created): "); 4856 pw.println(Arrays.toString(mUserIdsIncludingPreCreated)); 4857 } 4858 4859 } // synchronized (mPackagesLock) 4860 4861 // Dump some capabilities 4862 pw.println(); 4863 pw.print(" Max users: " + UserManager.getMaxSupportedUsers()); 4864 pw.println(" (limit reached: " + isUserLimitReached() + ")"); 4865 pw.println(" Supports switchable users: " + UserManager.supportsMultipleUsers()); 4866 pw.println(" All guests ephemeral: " + Resources.getSystem().getBoolean( 4867 com.android.internal.R.bool.config_guestUserEphemeral)); 4868 pw.println(" Force ephemeral users: " + mForceEphemeralUsers); 4869 pw.println(" Is split-system user: " + UserManager.isSplitSystemUser()); 4870 pw.println(" Is headless-system mode: " + UserManager.isHeadlessSystemUserMode()); 4871 pw.println(" User version: " + mUserVersion); 4872 4873 // Dump UserTypes 4874 pw.println(); 4875 pw.println(" User types (" + mUserTypes.size() + " types):"); 4876 for (int i = 0; i < mUserTypes.size(); i++) { 4877 pw.println(" " + mUserTypes.keyAt(i) + ": "); 4878 mUserTypes.valueAt(i).dump(pw); 4879 } 4880 4881 // Dump package whitelist 4882 pw.println(); 4883 mSystemPackageInstaller.dump(pw); 4884 } 4885 dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time)4886 private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) { 4887 if (time == 0) { 4888 pw.println("<unknown>"); 4889 } else { 4890 sb.setLength(0); 4891 TimeUtils.formatDuration(nowTime - time, sb); 4892 sb.append(" ago"); 4893 pw.println(sb); 4894 } 4895 } 4896 4897 final class MainHandler extends Handler { 4898 4899 @Override handleMessage(Message msg)4900 public void handleMessage(Message msg) { 4901 switch (msg.what) { 4902 case WRITE_USER_MSG: 4903 removeMessages(WRITE_USER_MSG, msg.obj); 4904 synchronized (mPackagesLock) { 4905 int userId = ((UserData) msg.obj).info.id; 4906 UserData userData = getUserDataNoChecks(userId); 4907 if (userData != null) { 4908 writeUserLP(userData); 4909 } 4910 } 4911 } 4912 } 4913 } 4914 4915 /** 4916 * @param userId 4917 * @return whether the user has been initialized yet 4918 */ isUserInitialized(@serIdInt int userId)4919 boolean isUserInitialized(@UserIdInt int userId) { 4920 return mLocalService.isUserInitialized(userId); 4921 } 4922 4923 private class LocalService extends UserManagerInternal { 4924 @Override setDevicePolicyUserRestrictions(@serIdInt int originatingUserId, @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner)4925 public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId, 4926 @NonNull Bundle global, @NonNull RestrictionsSet local, 4927 boolean isDeviceOwner) { 4928 UserManagerService.this.setDevicePolicyUserRestrictionsInner(originatingUserId, 4929 global, local, isDeviceOwner); 4930 } 4931 4932 @Override getBaseUserRestrictions(@serIdInt int userId)4933 public Bundle getBaseUserRestrictions(@UserIdInt int userId) { 4934 synchronized (mRestrictionsLock) { 4935 return mBaseUserRestrictions.getRestrictions(userId); 4936 } 4937 } 4938 4939 @Override setBaseUserRestrictionsByDpmsForMigration( @serIdInt int userId, Bundle baseRestrictions)4940 public void setBaseUserRestrictionsByDpmsForMigration( 4941 @UserIdInt int userId, Bundle baseRestrictions) { 4942 synchronized (mRestrictionsLock) { 4943 if (mBaseUserRestrictions.updateRestrictions(userId, 4944 new Bundle(baseRestrictions))) { 4945 invalidateEffectiveUserRestrictionsLR(userId); 4946 } 4947 } 4948 4949 final UserData userData = getUserDataNoChecks(userId); 4950 synchronized (mPackagesLock) { 4951 if (userData != null) { 4952 writeUserLP(userData); 4953 } else { 4954 Slog.w(LOG_TAG, "UserInfo not found for " + userId); 4955 } 4956 } 4957 } 4958 4959 @Override getUserRestriction(@serIdInt int userId, String key)4960 public boolean getUserRestriction(@UserIdInt int userId, String key) { 4961 return getUserRestrictions(userId).getBoolean(key); 4962 } 4963 4964 @Override addUserRestrictionsListener(UserRestrictionsListener listener)4965 public void addUserRestrictionsListener(UserRestrictionsListener listener) { 4966 synchronized (mUserRestrictionsListeners) { 4967 mUserRestrictionsListeners.add(listener); 4968 } 4969 } 4970 4971 @Override removeUserRestrictionsListener(UserRestrictionsListener listener)4972 public void removeUserRestrictionsListener(UserRestrictionsListener listener) { 4973 synchronized (mUserRestrictionsListeners) { 4974 mUserRestrictionsListeners.remove(listener); 4975 } 4976 } 4977 4978 @Override setDeviceManaged(boolean isManaged)4979 public void setDeviceManaged(boolean isManaged) { 4980 synchronized (mUsersLock) { 4981 mIsDeviceManaged = isManaged; 4982 } 4983 } 4984 4985 @Override isDeviceManaged()4986 public boolean isDeviceManaged() { 4987 synchronized (mUsersLock) { 4988 return mIsDeviceManaged; 4989 } 4990 } 4991 4992 @Override setUserManaged(@serIdInt int userId, boolean isManaged)4993 public void setUserManaged(@UserIdInt int userId, boolean isManaged) { 4994 synchronized (mUsersLock) { 4995 mIsUserManaged.put(userId, isManaged); 4996 } 4997 } 4998 4999 @Override isUserManaged(@serIdInt int userId)5000 public boolean isUserManaged(@UserIdInt int userId) { 5001 synchronized (mUsersLock) { 5002 return mIsUserManaged.get(userId); 5003 } 5004 } 5005 5006 @Override setUserIcon(@serIdInt int userId, Bitmap bitmap)5007 public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) { 5008 long ident = Binder.clearCallingIdentity(); 5009 try { 5010 synchronized (mPackagesLock) { 5011 UserData userData = getUserDataNoChecks(userId); 5012 if (userData == null || userData.info.partial) { 5013 Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId); 5014 return; 5015 } 5016 writeBitmapLP(userData.info, bitmap); 5017 writeUserLP(userData); 5018 } 5019 sendUserInfoChangedBroadcast(userId); 5020 } finally { 5021 Binder.restoreCallingIdentity(ident); 5022 } 5023 } 5024 5025 @Override setForceEphemeralUsers(boolean forceEphemeralUsers)5026 public void setForceEphemeralUsers(boolean forceEphemeralUsers) { 5027 synchronized (mUsersLock) { 5028 mForceEphemeralUsers = forceEphemeralUsers; 5029 } 5030 } 5031 5032 @Override removeAllUsers()5033 public void removeAllUsers() { 5034 if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) { 5035 // Remove the non-system users straight away. 5036 removeNonSystemUsers(); 5037 } else { 5038 // Switch to the system user first and then remove the other users. 5039 BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() { 5040 @Override 5041 public void onReceive(Context context, Intent intent) { 5042 int userId = 5043 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 5044 if (userId != UserHandle.USER_SYSTEM) { 5045 return; 5046 } 5047 mContext.unregisterReceiver(this); 5048 removeNonSystemUsers(); 5049 } 5050 }; 5051 IntentFilter userSwitchedFilter = new IntentFilter(); 5052 userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED); 5053 mContext.registerReceiver( 5054 userSwitchedReceiver, userSwitchedFilter, null, mHandler); 5055 5056 // Switch to the system user. 5057 ActivityManager am = 5058 (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 5059 am.switchUser(UserHandle.USER_SYSTEM); 5060 } 5061 } 5062 5063 @Override onEphemeralUserStop(@serIdInt int userId)5064 public void onEphemeralUserStop(@UserIdInt int userId) { 5065 synchronized (mUsersLock) { 5066 UserInfo userInfo = getUserInfoLU(userId); 5067 if (userInfo != null && userInfo.isEphemeral()) { 5068 // Do not allow switching back to the ephemeral user again as the user is going 5069 // to be deleted. 5070 userInfo.flags |= UserInfo.FLAG_DISABLED; 5071 if (userInfo.isGuest()) { 5072 // Indicate that the guest will be deleted after it stops. 5073 userInfo.guestToRemove = true; 5074 } 5075 } 5076 } 5077 } 5078 5079 @Override createUserEvenWhenDisallowed(String name, @NonNull String userType, @UserInfoFlag int flags, String[] disallowedPackages)5080 public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType, 5081 @UserInfoFlag int flags, String[] disallowedPackages) 5082 throws UserManager.CheckedUserOperationException { 5083 return createUserInternalUnchecked(name, userType, flags, 5084 UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages); 5085 } 5086 5087 @Override removeUserEvenWhenDisallowed(@serIdInt int userId)5088 public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) { 5089 return removeUserUnchecked(userId); 5090 } 5091 5092 @Override isUserRunning(@serIdInt int userId)5093 public boolean isUserRunning(@UserIdInt int userId) { 5094 synchronized (mUserStates) { 5095 return mUserStates.get(userId, -1) >= 0; 5096 } 5097 } 5098 5099 @Override setUserState(@serIdInt int userId, int userState)5100 public void setUserState(@UserIdInt int userId, int userState) { 5101 synchronized (mUserStates) { 5102 mUserStates.put(userId, userState); 5103 } 5104 } 5105 5106 @Override removeUserState(@serIdInt int userId)5107 public void removeUserState(@UserIdInt int userId) { 5108 synchronized (mUserStates) { 5109 mUserStates.delete(userId); 5110 } 5111 } 5112 5113 @Override getUserIds()5114 public int[] getUserIds() { 5115 return UserManagerService.this.getUserIds(); 5116 } 5117 5118 @Override getUsers(boolean excludeDying)5119 public @NonNull List<UserInfo> getUsers(boolean excludeDying) { 5120 return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); 5121 } 5122 5123 @Override getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)5124 public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, 5125 boolean excludePreCreated) { 5126 return UserManagerService.this.getUsersInternal(excludePartial, excludeDying, 5127 excludePreCreated); 5128 } 5129 5130 @Override isUserUnlockingOrUnlocked(@serIdInt int userId)5131 public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) { 5132 int state; 5133 synchronized (mUserStates) { 5134 state = mUserStates.get(userId, -1); 5135 } 5136 // Special case, in the stopping/shutdown state user key can still be unlocked 5137 if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) { 5138 return StorageManager.isUserKeyUnlocked(userId); 5139 } 5140 return (state == UserState.STATE_RUNNING_UNLOCKING) 5141 || (state == UserState.STATE_RUNNING_UNLOCKED); 5142 } 5143 5144 /** 5145 * The return values of this method are cached in clients. If the 5146 * logic in this function changes then the cache invalidation code 5147 * may need to be revisited. 5148 */ 5149 @Override isUserUnlocked(@serIdInt int userId)5150 public boolean isUserUnlocked(@UserIdInt int userId) { 5151 int state; 5152 synchronized (mUserStates) { 5153 state = mUserStates.get(userId, -1); 5154 } 5155 // Special case, in the stopping/shutdown state user key can still be unlocked 5156 if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) { 5157 return StorageManager.isUserKeyUnlocked(userId); 5158 } 5159 return state == UserState.STATE_RUNNING_UNLOCKED; 5160 } 5161 5162 @Override isUserInitialized(@serIdInt int userId)5163 public boolean isUserInitialized(@UserIdInt int userId) { 5164 return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0; 5165 } 5166 5167 @Override exists(@serIdInt int userId)5168 public boolean exists(@UserIdInt int userId) { 5169 return getUserInfoNoChecks(userId) != null; 5170 } 5171 5172 @Override isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException)5173 public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, 5174 boolean throwSecurityException) { 5175 if (targetUserId == callingUserId) { 5176 return true; 5177 } 5178 synchronized (mUsersLock) { 5179 UserInfo callingUserInfo = getUserInfoLU(callingUserId); 5180 if (callingUserInfo == null || callingUserInfo.isProfile()) { 5181 if (throwSecurityException) { 5182 throw new SecurityException( 5183 debugMsg + " for another profile " 5184 + targetUserId + " from " + callingUserId); 5185 } 5186 } 5187 5188 UserInfo targetUserInfo = getUserInfoLU(targetUserId); 5189 if (targetUserInfo == null || !targetUserInfo.isEnabled()) { 5190 // Do not throw any exception here as this could happen due to race conditions 5191 // between the system updating its state and the client getting notified. 5192 if (throwSecurityException) { 5193 Slog.w(LOG_TAG, debugMsg + " for disabled profile " 5194 + targetUserId + " from " + callingUserId); 5195 } 5196 return false; 5197 } 5198 5199 if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || 5200 targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 5201 if (throwSecurityException) { 5202 throw new SecurityException( 5203 debugMsg + " for unrelated profile " + targetUserId); 5204 } 5205 return false; 5206 } 5207 } 5208 return true; 5209 } 5210 5211 @Override getProfileParentId(@serIdInt int userId)5212 public int getProfileParentId(@UserIdInt int userId) { 5213 synchronized (mUsersLock) { 5214 UserInfo profileParent = getProfileParentLU(userId); 5215 if (profileParent == null) { 5216 return userId; 5217 } 5218 return profileParent.id; 5219 } 5220 } 5221 5222 @Override isSettingRestrictedForUser(String setting, @UserIdInt int userId, String value, int callingUid)5223 public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId, 5224 String value, int callingUid) { 5225 return UserManagerService.this.isSettingRestrictedForUser(setting, userId, 5226 value, callingUid); 5227 } 5228 5229 @Override hasUserRestriction(String restrictionKey, @UserIdInt int userId)5230 public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) { 5231 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 5232 return false; 5233 } 5234 Bundle restrictions = getEffectiveUserRestrictions(userId); 5235 return restrictions != null && restrictions.getBoolean(restrictionKey); 5236 } 5237 5238 @Override getUserInfo(@serIdInt int userId)5239 public @Nullable UserInfo getUserInfo(@UserIdInt int userId) { 5240 UserData userData; 5241 synchronized (mUsersLock) { 5242 userData = mUsers.get(userId); 5243 } 5244 return userData == null ? null : userData.info; 5245 } 5246 getUserInfos()5247 public @NonNull UserInfo[] getUserInfos() { 5248 synchronized (mUsersLock) { 5249 int userSize = mUsers.size(); 5250 UserInfo[] allInfos = new UserInfo[userSize]; 5251 for (int i = 0; i < userSize; i++) { 5252 allInfos[i] = mUsers.valueAt(i).info; 5253 } 5254 return allInfos; 5255 } 5256 } 5257 } 5258 5259 /** 5260 * Check if user has restrictions 5261 * @param restriction restrictions to check 5262 * @param userId id of the user 5263 * 5264 * @throws {@link android.os.UserManager.CheckedUserOperationException} if user has any of the 5265 * specified restrictions 5266 */ enforceUserRestriction(String restriction, @UserIdInt int userId, String message)5267 private void enforceUserRestriction(String restriction, @UserIdInt int userId, String message) 5268 throws UserManager.CheckedUserOperationException { 5269 if (hasUserRestriction(restriction, userId)) { 5270 String errorMessage = (message != null ? (message + ": ") : "") 5271 + restriction + " is enabled."; 5272 Slog.w(LOG_TAG, errorMessage); 5273 throw new UserManager.CheckedUserOperationException(errorMessage, 5274 UserManager.USER_OPERATION_ERROR_UNKNOWN); 5275 } 5276 } 5277 5278 /** 5279 * Throws CheckedUserOperationException and shows error log 5280 * @param message message for exception and logging 5281 * @param userOperationResult result/error code 5282 * @throws UserManager.CheckedUserOperationException 5283 */ throwCheckedUserOperationException(@onNull String message, @UserManager.UserOperationResult int userOperationResult)5284 private void throwCheckedUserOperationException(@NonNull String message, 5285 @UserManager.UserOperationResult int userOperationResult) 5286 throws UserManager.CheckedUserOperationException { 5287 Slog.e(LOG_TAG, message); 5288 throw new UserManager.CheckedUserOperationException(message, userOperationResult); 5289 } 5290 5291 /* Remove all the users except of the system one. */ removeNonSystemUsers()5292 private void removeNonSystemUsers() { 5293 ArrayList<UserInfo> usersToRemove = new ArrayList<>(); 5294 synchronized (mUsersLock) { 5295 final int userSize = mUsers.size(); 5296 for (int i = 0; i < userSize; i++) { 5297 UserInfo ui = mUsers.valueAt(i).info; 5298 if (ui.id != UserHandle.USER_SYSTEM) { 5299 usersToRemove.add(ui); 5300 } 5301 } 5302 } 5303 for (UserInfo ui: usersToRemove) { 5304 removeUser(ui.id); 5305 } 5306 } 5307 5308 private class Shell extends ShellCommand { 5309 @Override onCommand(String cmd)5310 public int onCommand(String cmd) { 5311 return onShellCommand(this, cmd); 5312 } 5313 5314 @Override onHelp()5315 public void onHelp() { 5316 final PrintWriter pw = getOutPrintWriter(); 5317 pw.println("User manager (user) commands:"); 5318 pw.println(" help"); 5319 pw.println(" Prints this help text."); 5320 pw.println(""); 5321 pw.println(" list [-v] [-all]"); 5322 pw.println(" Prints all users on the system."); 5323 pw.println(" report-system-user-package-whitelist-problems [-v | --verbose] " 5324 + "[--critical-only] [--mode MODE]"); 5325 pw.println(" Reports all issues on user-type package whitelist XML files. Options:"); 5326 pw.println(" -v | --verbose : shows extra info, like number of issues"); 5327 pw.println(" --critical-only: show only critical issues, excluding warnings"); 5328 pw.println(" --mode MODE: shows what errors would be if device used mode MODE (where" 5329 + " MODE is the whitelist mode integer as defined by " 5330 + "config_userTypePackageWhitelistMode)"); 5331 } 5332 } 5333 debug(String message)5334 private static void debug(String message) { 5335 Slog.d(LOG_TAG, message 5336 + (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, " ") : "")); 5337 } 5338 5339 /** @see #getMaxUsersOfTypePerParent(UserTypeDetails) */ 5340 @VisibleForTesting getMaxUsersOfTypePerParent(String userType)5341 int getMaxUsersOfTypePerParent(String userType) { 5342 final UserTypeDetails type = mUserTypes.get(userType); 5343 if (type == null) { 5344 return 0; 5345 } 5346 return getMaxUsersOfTypePerParent(type); 5347 } 5348 5349 /** 5350 * Returns the maximum number of users allowed for the given userTypeDetails per parent user. 5351 * This is applicable for user types that are {@link UserTypeDetails#isProfile()}. 5352 * If there is no maximum, {@link UserTypeDetails#UNLIMITED_NUMBER_OF_USERS} is returned. 5353 */ getMaxUsersOfTypePerParent(UserTypeDetails userTypeDetails)5354 private static int getMaxUsersOfTypePerParent(UserTypeDetails userTypeDetails) { 5355 final int defaultMax = userTypeDetails.getMaxAllowedPerParent(); 5356 if (!Build.IS_DEBUGGABLE) { 5357 return defaultMax; 5358 } else { 5359 if (userTypeDetails.isManagedProfile()) { 5360 return SystemProperties.getInt("persist.sys.max_profiles", defaultMax); 5361 } 5362 } 5363 return defaultMax; 5364 } 5365 5366 @GuardedBy("mUsersLock") 5367 @VisibleForTesting getFreeProfileBadgeLU(int parentUserId, String userType)5368 int getFreeProfileBadgeLU(int parentUserId, String userType) { 5369 Set<Integer> usedBadges = new ArraySet<>(); 5370 final int userSize = mUsers.size(); 5371 for (int i = 0; i < userSize; i++) { 5372 UserInfo ui = mUsers.valueAt(i).info; 5373 // Check which badge indexes are already used by this profile group. 5374 if (ui.userType.equals(userType) 5375 && ui.profileGroupId == parentUserId 5376 && !mRemovingUserIds.get(ui.id)) { 5377 usedBadges.add(ui.profileBadge); 5378 } 5379 } 5380 int maxUsersOfType = getMaxUsersOfTypePerParent(userType); 5381 if (maxUsersOfType == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) { 5382 maxUsersOfType = Integer.MAX_VALUE; 5383 } 5384 for (int i = 0; i < maxUsersOfType; i++) { 5385 if (!usedBadges.contains(i)) { 5386 return i; 5387 } 5388 } 5389 return 0; 5390 } 5391 5392 /** 5393 * Checks if the given user has a managed profile associated with it. 5394 * @param userId The parent user 5395 * @return 5396 */ hasManagedProfile(@serIdInt int userId)5397 boolean hasManagedProfile(@UserIdInt int userId) { 5398 synchronized (mUsersLock) { 5399 UserInfo userInfo = getUserInfoLU(userId); 5400 final int userSize = mUsers.size(); 5401 for (int i = 0; i < userSize; i++) { 5402 UserInfo profile = mUsers.valueAt(i).info; 5403 if (userId != profile.id && isProfileOf(userInfo, profile)) { 5404 return true; 5405 } 5406 } 5407 return false; 5408 } 5409 } 5410 5411 /** 5412 * Checks if the calling package name matches with the calling UID, throw 5413 * {@link SecurityException} if not. 5414 */ verifyCallingPackage(String callingPackage, int callingUid)5415 private void verifyCallingPackage(String callingPackage, int callingUid) { 5416 int packageUid = mPm.getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid)); 5417 if (packageUid != callingUid) { 5418 throw new SecurityException("Specified package " + callingPackage 5419 + " does not match the calling uid " + callingUid); 5420 } 5421 } 5422 5423 /** Retrieves the internal package manager interface. */ getPackageManagerInternal()5424 private PackageManagerInternal getPackageManagerInternal() { 5425 // Don't need to synchonize; worst-case scenario LocalServices will be called twice. 5426 if (mPmInternal == null) { 5427 mPmInternal = LocalServices.getService(PackageManagerInternal.class); 5428 } 5429 return mPmInternal; 5430 } 5431 5432 /** Retrieve the internal cross profile apps interface. */ getCrossProfileAppsInternal()5433 private CrossProfileAppsInternal getCrossProfileAppsInternal() { 5434 if (mCrossProfileAppsInternal == null) { 5435 mCrossProfileAppsInternal = LocalServices.getService(CrossProfileAppsInternal.class); 5436 } 5437 return mCrossProfileAppsInternal; 5438 } 5439 5440 /** Returns the internal device policy manager interface. */ getDevicePolicyManagerInternal()5441 private DevicePolicyManagerInternal getDevicePolicyManagerInternal() { 5442 if (mDevicePolicyManagerInternal == null) { 5443 mDevicePolicyManagerInternal = 5444 LocalServices.getService(DevicePolicyManagerInternal.class); 5445 } 5446 return mDevicePolicyManagerInternal; 5447 } 5448 } 5449