UserManagerService.java revision 7f98aa4aa93497692f200c553d2d6fff402e3de2
1 2/* 3 * Copyright (C) 2011 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.server.pm; 19 20import android.Manifest; 21import android.annotation.NonNull; 22import android.annotation.Nullable; 23import android.annotation.UserIdInt; 24import android.app.Activity; 25import android.app.ActivityManager; 26import android.app.ActivityManagerInternal; 27import android.app.ActivityManagerNative; 28import android.app.IActivityManager; 29import android.app.IStopUserCallback; 30import android.content.BroadcastReceiver; 31import android.content.Context; 32import android.content.Intent; 33import android.content.IntentFilter; 34import android.content.pm.PackageManager; 35import android.content.pm.PackageManager.NameNotFoundException; 36import android.content.pm.UserInfo; 37import android.content.res.Resources; 38import android.graphics.Bitmap; 39import android.os.Binder; 40import android.os.Build; 41import android.os.Bundle; 42import android.os.Debug; 43import android.os.Environment; 44import android.os.FileUtils; 45import android.os.Handler; 46import android.os.IBinder; 47import android.os.IUserManager; 48import android.os.Message; 49import android.os.ParcelFileDescriptor; 50import android.os.Parcelable; 51import android.os.PersistableBundle; 52import android.os.Process; 53import android.os.RemoteException; 54import android.os.ResultReceiver; 55import android.os.SELinux; 56import android.os.ServiceManager; 57import android.os.ShellCommand; 58import android.os.UserHandle; 59import android.os.UserManager; 60import android.os.UserManagerInternal; 61import android.os.UserManagerInternal.UserRestrictionsListener; 62import android.os.storage.StorageManager; 63import android.os.storage.VolumeInfo; 64import android.system.ErrnoException; 65import android.system.Os; 66import android.system.OsConstants; 67import android.util.AtomicFile; 68import android.util.IntArray; 69import android.util.Log; 70import android.util.Slog; 71import android.util.SparseArray; 72import android.util.SparseBooleanArray; 73import android.util.TimeUtils; 74import android.util.Xml; 75 76import com.android.internal.annotations.GuardedBy; 77import com.android.internal.annotations.VisibleForTesting; 78import com.android.internal.app.IAppOpsService; 79import com.android.internal.logging.MetricsLogger; 80import com.android.internal.util.FastXmlSerializer; 81import com.android.internal.util.Preconditions; 82import com.android.internal.util.XmlUtils; 83import com.android.internal.widget.LockPatternUtils; 84import com.android.server.LocalServices; 85 86import libcore.io.IoUtils; 87import libcore.util.Objects; 88 89import org.xmlpull.v1.XmlPullParser; 90import org.xmlpull.v1.XmlPullParserException; 91import org.xmlpull.v1.XmlSerializer; 92 93import java.io.BufferedOutputStream; 94import java.io.File; 95import java.io.FileDescriptor; 96import java.io.FileInputStream; 97import java.io.FileNotFoundException; 98import java.io.FileOutputStream; 99import java.io.IOException; 100import java.io.PrintWriter; 101import java.nio.charset.StandardCharsets; 102import java.util.ArrayList; 103import java.util.List; 104 105/** 106 * Service for {@link UserManager}. 107 * 108 * Method naming convention: 109 * <ul> 110 * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock. 111 * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock. 112 * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock. 113 * </ul> 114 */ 115public class UserManagerService extends IUserManager.Stub { 116 private static final String LOG_TAG = "UserManagerService"; 117 static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE 118 private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE 119 120 private static final String TAG_NAME = "name"; 121 private static final String TAG_ACCOUNT = "account"; 122 private static final String ATTR_FLAGS = "flags"; 123 private static final String ATTR_ICON_PATH = "icon"; 124 private static final String ATTR_ID = "id"; 125 private static final String ATTR_CREATION_TIME = "created"; 126 private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn"; 127 private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint"; 128 private static final String ATTR_SERIAL_NO = "serialNumber"; 129 private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; 130 private static final String ATTR_PARTIAL = "partial"; 131 private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove"; 132 private static final String ATTR_USER_VERSION = "version"; 133 private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId"; 134 private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId"; 135 private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName"; 136 private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType"; 137 private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions"; 138 private static final String TAG_USERS = "users"; 139 private static final String TAG_USER = "user"; 140 private static final String TAG_RESTRICTIONS = "restrictions"; 141 private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions"; 142 private static final String TAG_ENTRY = "entry"; 143 private static final String TAG_VALUE = "value"; 144 private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; 145 private static final String ATTR_KEY = "key"; 146 private static final String ATTR_VALUE_TYPE = "type"; 147 private static final String ATTR_MULTIPLE = "m"; 148 149 private static final String ATTR_TYPE_STRING_ARRAY = "sa"; 150 private static final String ATTR_TYPE_STRING = "s"; 151 private static final String ATTR_TYPE_BOOLEAN = "b"; 152 private static final String ATTR_TYPE_INTEGER = "i"; 153 private static final String ATTR_TYPE_BUNDLE = "B"; 154 private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA"; 155 156 private static final String USER_INFO_DIR = "system" + File.separator + "users"; 157 private static final String USER_LIST_FILENAME = "userlist.xml"; 158 private static final String USER_PHOTO_FILENAME = "photo.png"; 159 private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp"; 160 161 private static final String RESTRICTIONS_FILE_PREFIX = "res_"; 162 private static final String XML_SUFFIX = ".xml"; 163 164 private static final int MIN_USER_ID = 10; 165 // We need to keep process uid within Integer.MAX_VALUE. 166 private static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE; 167 168 private static final int USER_VERSION = 6; 169 170 private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms 171 172 // Maximum number of managed profiles permitted per user is 1. This cannot be increased 173 // without first making sure that the rest of the framework is prepared for it. 174 private static final int MAX_MANAGED_PROFILES = 1; 175 176 static final int WRITE_USER_MSG = 1; 177 static final int WRITE_USER_DELAY = 2*1000; // 2 seconds 178 179 private static final String XATTR_SERIAL = "user.serial"; 180 181 // Tron counters 182 private static final String TRON_GUEST_CREATED = "users_guest_created"; 183 private static final String TRON_USER_CREATED = "users_user_created"; 184 185 private final Context mContext; 186 private final PackageManagerService mPm; 187 private final Object mPackagesLock; 188 // Short-term lock for internal state, when interaction/sync with PM is not required 189 private final Object mUsersLock = new Object(); 190 private final Object mRestrictionsLock = new Object(); 191 192 private final Handler mHandler; 193 194 private final File mUsersDir; 195 private final File mUserListFile; 196 197 private static final IBinder mUserRestriconToken = new Binder(); 198 199 /** 200 * User-related information that is used for persisting to flash. Only UserInfo is 201 * directly exposed to other system apps. 202 */ 203 private static class UserData { 204 // Basic user information and properties 205 UserInfo info; 206 // Account name used when there is a strong association between a user and an account 207 String account; 208 // Account information for seeding into a newly created user. This could also be 209 // used for login validation for an existing user, for updating their credentials. 210 // In the latter case, data may not need to be persisted as it is only valid for the 211 // current login session. 212 String seedAccountName; 213 String seedAccountType; 214 PersistableBundle seedAccountOptions; 215 // Whether to perist the seed account information to be available after a boot 216 boolean persistSeedData; 217 218 void clearSeedAccountData() { 219 seedAccountName = null; 220 seedAccountType = null; 221 seedAccountOptions = null; 222 persistSeedData = false; 223 } 224 } 225 226 @GuardedBy("mUsersLock") 227 private final SparseArray<UserData> mUsers = new SparseArray<>(); 228 229 /** 230 * User restrictions set via UserManager. This doesn't include restrictions set by 231 * device owner / profile owners. 232 * 233 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 234 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 235 * maybe shared between {@link #mBaseUserRestrictions} and 236 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 237 * (Otherwise we won't be able to detect what restrictions have changed in 238 * {@link #updateUserRestrictionsInternalLR}. 239 */ 240 @GuardedBy("mRestrictionsLock") 241 private final SparseArray<Bundle> mBaseUserRestrictions = new SparseArray<>(); 242 243 /** 244 * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined 245 * with device / profile owner restrictions. We'll initialize it lazily; use 246 * {@link #getEffectiveUserRestrictions} to access it. 247 * 248 * DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user, 249 * a new {@link Bundle} should always be created and set. This is because a {@link Bundle} 250 * maybe shared between {@link #mBaseUserRestrictions} and 251 * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately. 252 * (Otherwise we won't be able to detect what restrictions have changed in 253 * {@link #updateUserRestrictionsInternalLR}. 254 */ 255 @GuardedBy("mRestrictionsLock") 256 private final SparseArray<Bundle> mCachedEffectiveUserRestrictions = new SparseArray<>(); 257 258 /** 259 * User restrictions that have already been applied in 260 * {@link #updateUserRestrictionsInternalLR(Bundle, int)}. We use it to detect restrictions 261 * that have changed since the last 262 * {@link #updateUserRestrictionsInternalLR(Bundle, int)} call. 263 */ 264 @GuardedBy("mRestrictionsLock") 265 private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>(); 266 267 /** 268 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 269 * that should be applied to all users, including guests. 270 */ 271 @GuardedBy("mRestrictionsLock") 272 private Bundle mDevicePolicyGlobalUserRestrictions; 273 274 /** 275 * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService} 276 * for each user. 277 */ 278 @GuardedBy("mRestrictionsLock") 279 private final SparseArray<Bundle> mDevicePolicyLocalUserRestrictions = new SparseArray<>(); 280 281 @GuardedBy("mGuestRestrictions") 282 private final Bundle mGuestRestrictions = new Bundle(); 283 284 /** 285 * Set of user IDs being actively removed. Removed IDs linger in this set 286 * for several seconds to work around a VFS caching issue. 287 */ 288 @GuardedBy("mUsersLock") 289 private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray(); 290 291 @GuardedBy("mUsersLock") 292 private int[] mUserIds; 293 @GuardedBy("mPackagesLock") 294 private int mNextSerialNumber; 295 private int mUserVersion = 0; 296 297 private IAppOpsService mAppOpsService; 298 299 private final LocalService mLocalService; 300 301 @GuardedBy("mUsersLock") 302 private boolean mIsDeviceManaged; 303 304 @GuardedBy("mUsersLock") 305 private final SparseBooleanArray mIsUserManaged = new SparseBooleanArray(); 306 307 @GuardedBy("mUserRestrictionsListeners") 308 private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners = 309 new ArrayList<>(); 310 311 private final LockPatternUtils mLockPatternUtils; 312 313 /** 314 * Whether all users should be created ephemeral. 315 */ 316 @GuardedBy("mUsersLock") 317 private boolean mForceEphemeralUsers; 318 319 private static UserManagerService sInstance; 320 321 public static UserManagerService getInstance() { 322 synchronized (UserManagerService.class) { 323 return sInstance; 324 } 325 } 326 327 @VisibleForTesting 328 UserManagerService(File dataDir) { 329 this(null, null, new Object(), dataDir); 330 } 331 332 /** 333 * Called by package manager to create the service. This is closely 334 * associated with the package manager, and the given lock is the 335 * package manager's own lock. 336 */ 337 UserManagerService(Context context, PackageManagerService pm, Object packagesLock) { 338 this(context, pm, packagesLock, Environment.getDataDirectory()); 339 } 340 341 private UserManagerService(Context context, PackageManagerService pm, 342 Object packagesLock, File dataDir) { 343 mContext = context; 344 mPm = pm; 345 mPackagesLock = packagesLock; 346 mHandler = new MainHandler(); 347 synchronized (mPackagesLock) { 348 mUsersDir = new File(dataDir, USER_INFO_DIR); 349 mUsersDir.mkdirs(); 350 // Make zeroth user directory, for services to migrate their files to that location 351 File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM)); 352 userZeroDir.mkdirs(); 353 FileUtils.setPermissions(mUsersDir.toString(), 354 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, 355 -1, -1); 356 mUserListFile = new File(mUsersDir, USER_LIST_FILENAME); 357 initDefaultGuestRestrictions(); 358 readUserListLP(); 359 sInstance = this; 360 } 361 mLocalService = new LocalService(); 362 LocalServices.addService(UserManagerInternal.class, mLocalService); 363 mLockPatternUtils = new LockPatternUtils(mContext); 364 } 365 366 void systemReady() { 367 // Prune out any partially created, partially removed and ephemeral users. 368 ArrayList<UserInfo> partials = new ArrayList<>(); 369 synchronized (mUsersLock) { 370 final int userSize = mUsers.size(); 371 for (int i = 0; i < userSize; i++) { 372 UserInfo ui = mUsers.valueAt(i).info; 373 if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) { 374 partials.add(ui); 375 } 376 } 377 } 378 final int partialsSize = partials.size(); 379 for (int i = 0; i < partialsSize; i++) { 380 UserInfo ui = partials.get(i); 381 Slog.w(LOG_TAG, "Removing partially created user " + ui.id 382 + " (name=" + ui.name + ")"); 383 removeUserState(ui.id); 384 } 385 386 mAppOpsService = IAppOpsService.Stub.asInterface( 387 ServiceManager.getService(Context.APP_OPS_SERVICE)); 388 389 synchronized (mRestrictionsLock) { 390 applyUserRestrictionsLR(UserHandle.USER_SYSTEM); 391 } 392 393 UserInfo currentGuestUser = findCurrentGuestUser(); 394 if (currentGuestUser != null && !hasUserRestriction( 395 UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) { 396 // If a guest user currently exists, apply the DISALLOW_CONFIG_WIFI option 397 // to it, in case this guest was created in a previous version where this 398 // user restriction was not a default guest restriction. 399 setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id); 400 } 401 } 402 403 @Override 404 public String getUserAccount(int userId) { 405 checkManageUserAndAcrossUsersFullPermission("get user account"); 406 synchronized (mUsersLock) { 407 return mUsers.get(userId).account; 408 } 409 } 410 411 @Override 412 public void setUserAccount(int userId, String accountName) { 413 checkManageUserAndAcrossUsersFullPermission("set user account"); 414 UserData userToUpdate = null; 415 synchronized (mPackagesLock) { 416 synchronized (mUsersLock) { 417 final UserData userData = mUsers.get(userId); 418 if (userData == null) { 419 Slog.e(LOG_TAG, "User not found for setting user account: u" + userId); 420 return; 421 } 422 String currentAccount = userData.account; 423 if (!Objects.equal(currentAccount, accountName)) { 424 userData.account = accountName; 425 userToUpdate = userData; 426 } 427 } 428 429 if (userToUpdate != null) { 430 writeUserLP(userToUpdate); 431 } 432 } 433 } 434 435 @Override 436 public UserInfo getPrimaryUser() { 437 checkManageUsersPermission("query users"); 438 synchronized (mUsersLock) { 439 final int userSize = mUsers.size(); 440 for (int i = 0; i < userSize; i++) { 441 UserInfo ui = mUsers.valueAt(i).info; 442 if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) { 443 return ui; 444 } 445 } 446 } 447 return null; 448 } 449 450 @Override 451 public @NonNull List<UserInfo> getUsers(boolean excludeDying) { 452 checkManageUsersPermission("query users"); 453 synchronized (mUsersLock) { 454 ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size()); 455 final int userSize = mUsers.size(); 456 for (int i = 0; i < userSize; i++) { 457 UserInfo ui = mUsers.valueAt(i).info; 458 if (ui.partial) { 459 continue; 460 } 461 if (!excludeDying || !mRemovingUserIds.get(ui.id)) { 462 users.add(userWithName(ui)); 463 } 464 } 465 return users; 466 } 467 } 468 469 @Override 470 public List<UserInfo> getProfiles(int userId, boolean enabledOnly) { 471 boolean returnFullInfo = true; 472 if (userId != UserHandle.getCallingUserId()) { 473 checkManageUsersPermission("getting profiles related to user " + userId); 474 } else { 475 returnFullInfo = hasManageUsersPermission(); 476 } 477 final long ident = Binder.clearCallingIdentity(); 478 try { 479 synchronized (mUsersLock) { 480 return getProfilesLU(userId, enabledOnly, returnFullInfo); 481 } 482 } finally { 483 Binder.restoreCallingIdentity(ident); 484 } 485 } 486 487 @Override 488 public int[] getProfileIds(int userId, boolean enabledOnly) { 489 if (userId != UserHandle.getCallingUserId()) { 490 checkManageUsersPermission("getting profiles related to user " + userId); 491 } 492 final long ident = Binder.clearCallingIdentity(); 493 try { 494 synchronized (mUsersLock) { 495 return getProfileIdsLU(userId, enabledOnly).toArray(); 496 } 497 } finally { 498 Binder.restoreCallingIdentity(ident); 499 } 500 } 501 502 /** Assume permissions already checked and caller's identity cleared */ 503 private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) { 504 IntArray profileIds = getProfileIdsLU(userId, enabledOnly); 505 ArrayList<UserInfo> users = new ArrayList<>(profileIds.size()); 506 for (int i = 0; i < profileIds.size(); i++) { 507 int profileId = profileIds.get(i); 508 UserInfo userInfo = mUsers.get(profileId).info; 509 // If full info is not required - clear PII data to prevent 3P apps from reading it 510 if (!fullInfo) { 511 userInfo = new UserInfo(userInfo); 512 userInfo.name = null; 513 userInfo.iconPath = null; 514 } else { 515 userInfo = userWithName(userInfo); 516 } 517 users.add(userInfo); 518 } 519 return users; 520 } 521 522 /** 523 * Assume permissions already checked and caller's identity cleared 524 */ 525 private IntArray getProfileIdsLU(int userId, boolean enabledOnly) { 526 UserInfo user = getUserInfoLU(userId); 527 IntArray result = new IntArray(mUsers.size()); 528 if (user == null) { 529 // Probably a dying user 530 return result; 531 } 532 final int userSize = mUsers.size(); 533 for (int i = 0; i < userSize; i++) { 534 UserInfo profile = mUsers.valueAt(i).info; 535 if (!isProfileOf(user, profile)) { 536 continue; 537 } 538 if (enabledOnly && !profile.isEnabled()) { 539 continue; 540 } 541 if (mRemovingUserIds.get(profile.id)) { 542 continue; 543 } 544 if (profile.partial) { 545 continue; 546 } 547 result.add(profile.id); 548 } 549 return result; 550 } 551 552 @Override 553 public int getCredentialOwnerProfile(int userHandle) { 554 checkManageUsersPermission("get the credential owner"); 555 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) { 556 synchronized (mUsersLock) { 557 UserInfo profileParent = getProfileParentLU(userHandle); 558 if (profileParent != null) { 559 return profileParent.id; 560 } 561 } 562 } 563 564 return userHandle; 565 } 566 567 @Override 568 public boolean isSameProfileGroup(int userId, int otherUserId) { 569 if (userId == otherUserId) return true; 570 checkManageUsersPermission("check if in the same profile group"); 571 synchronized (mPackagesLock) { 572 return isSameProfileGroupLP(userId, otherUserId); 573 } 574 } 575 576 private boolean isSameProfileGroupLP(int userId, int otherUserId) { 577 synchronized (mUsersLock) { 578 UserInfo userInfo = getUserInfoLU(userId); 579 if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 580 return false; 581 } 582 UserInfo otherUserInfo = getUserInfoLU(otherUserId); 583 if (otherUserInfo == null 584 || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 585 return false; 586 } 587 return userInfo.profileGroupId == otherUserInfo.profileGroupId; 588 } 589 } 590 591 @Override 592 public UserInfo getProfileParent(int userHandle) { 593 checkManageUsersPermission("get the profile parent"); 594 synchronized (mUsersLock) { 595 return getProfileParentLU(userHandle); 596 } 597 } 598 599 private UserInfo getProfileParentLU(int userHandle) { 600 UserInfo profile = getUserInfoLU(userHandle); 601 if (profile == null) { 602 return null; 603 } 604 int parentUserId = profile.profileGroupId; 605 if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) { 606 return null; 607 } else { 608 return getUserInfoLU(parentUserId); 609 } 610 } 611 612 private static boolean isProfileOf(UserInfo user, UserInfo profile) { 613 return user.id == profile.id || 614 (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 615 && user.profileGroupId == profile.profileGroupId); 616 } 617 618 private void broadcastProfileAvailabilityChanges(UserHandle profileHandle, 619 UserHandle parentHandle, boolean inQuietMode) { 620 Intent intent = new Intent(); 621 if (inQuietMode) { 622 intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); 623 } else { 624 intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); 625 } 626 intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); 627 intent.putExtra(Intent.EXTRA_USER, profileHandle); 628 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); 629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 630 mContext.sendBroadcastAsUser(intent, parentHandle); 631 632 //TODO: remove once Launcher3 is updated. 633 Intent oldIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); 634 oldIntent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); 635 oldIntent.putExtra(Intent.EXTRA_USER, profileHandle); 636 oldIntent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); 637 oldIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 638 mContext.sendBroadcastAsUser(oldIntent, parentHandle); 639 640 } 641 642 @Override 643 public void setQuietModeEnabled(int userHandle, boolean enableQuietMode) { 644 checkManageUsersPermission("silence profile"); 645 boolean changed = false; 646 UserInfo profile, parent; 647 synchronized (mPackagesLock) { 648 synchronized (mUsersLock) { 649 profile = getUserInfoLU(userHandle); 650 parent = getProfileParentLU(userHandle); 651 652 } 653 if (profile == null || !profile.isManagedProfile()) { 654 throw new IllegalArgumentException("User " + userHandle + " is not a profile"); 655 } 656 if (profile.isQuietModeEnabled() != enableQuietMode) { 657 profile.flags ^= UserInfo.FLAG_QUIET_MODE; 658 writeUserLP(getUserDataLU(profile.id)); 659 changed = true; 660 } 661 } 662 if (changed) { 663 long identity = Binder.clearCallingIdentity(); 664 try { 665 if (enableQuietMode) { 666 ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null); 667 } else { 668 ActivityManagerNative.getDefault().startUserInBackground(userHandle); 669 } 670 } catch (RemoteException e) { 671 Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e); 672 } finally { 673 Binder.restoreCallingIdentity(identity); 674 } 675 676 broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(), 677 enableQuietMode); 678 } 679 } 680 681 @Override 682 public boolean isQuietModeEnabled(int userHandle) { 683 synchronized (mPackagesLock) { 684 UserInfo info; 685 synchronized (mUsersLock) { 686 info = getUserInfoLU(userHandle); 687 } 688 if (info == null || !info.isManagedProfile()) { 689 return false; 690 } 691 return info.isQuietModeEnabled(); 692 } 693 } 694 695 @Override 696 public void setUserEnabled(int userId) { 697 checkManageUsersPermission("enable user"); 698 synchronized (mPackagesLock) { 699 UserInfo info; 700 synchronized (mUsersLock) { 701 info = getUserInfoLU(userId); 702 } 703 if (info != null && !info.isEnabled()) { 704 info.flags ^= UserInfo.FLAG_DISABLED; 705 writeUserLP(getUserDataLU(info.id)); 706 } 707 } 708 } 709 710 @Override 711 public UserInfo getUserInfo(int userId) { 712 checkManageUsersPermission("query user"); 713 synchronized (mUsersLock) { 714 return userWithName(getUserInfoLU(userId)); 715 } 716 } 717 718 /** 719 * Returns a UserInfo object with the name filled in, for Owner, or the original 720 * if the name is already set. 721 */ 722 private UserInfo userWithName(UserInfo orig) { 723 if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) { 724 UserInfo withName = new UserInfo(orig); 725 withName.name = getOwnerName(); 726 return withName; 727 } else { 728 return orig; 729 } 730 } 731 732 @Override 733 public boolean isManagedProfile(int userId) { 734 int callingUserId = UserHandle.getCallingUserId(); 735 if (callingUserId != userId && !hasManageUsersPermission()) { 736 synchronized (mPackagesLock) { 737 if (!isSameProfileGroupLP(callingUserId, userId)) { 738 throw new SecurityException( 739 "You need MANAGE_USERS permission to: check if specified user a " + 740 "managed profile outside your profile group"); 741 } 742 } 743 } 744 synchronized (mUsersLock) { 745 UserInfo userInfo = getUserInfoLU(userId); 746 return userInfo != null && userInfo.isManagedProfile(); 747 } 748 } 749 750 @Override 751 public boolean isRestricted() { 752 synchronized (mUsersLock) { 753 return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted(); 754 } 755 } 756 757 @Override 758 public boolean canHaveRestrictedProfile(int userId) { 759 checkManageUsersPermission("canHaveRestrictedProfile"); 760 synchronized (mUsersLock) { 761 final UserInfo userInfo = getUserInfoLU(userId); 762 if (userInfo == null || !userInfo.canHaveProfile()) { 763 return false; 764 } 765 if (!userInfo.isAdmin()) { 766 return false; 767 } 768 // restricted profile can be created if there is no DO set and the admin user has no PO; 769 return !mIsDeviceManaged && !mIsUserManaged.get(userId); 770 } 771 } 772 773 /* 774 * Should be locked on mUsers before calling this. 775 */ 776 private UserInfo getUserInfoLU(int userId) { 777 final UserData userData = mUsers.get(userId); 778 // If it is partial and not in the process of being removed, return as unknown user. 779 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 780 Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); 781 return null; 782 } 783 return userData != null ? userData.info : null; 784 } 785 786 private UserData getUserDataLU(int userId) { 787 final UserData userData = mUsers.get(userId); 788 // If it is partial and not in the process of being removed, return as unknown user. 789 if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) { 790 return null; 791 } 792 return userData; 793 } 794 795 /** 796 * Obtains {@link #mUsersLock} and return UserInfo from mUsers. 797 * <p>No permissions checking or any addition checks are made</p> 798 */ 799 private UserInfo getUserInfoNoChecks(int userId) { 800 synchronized (mUsersLock) { 801 final UserData userData = mUsers.get(userId); 802 return userData != null ? userData.info : null; 803 } 804 } 805 806 /** 807 * Obtains {@link #mUsersLock} and return UserData from mUsers. 808 * <p>No permissions checking or any addition checks are made</p> 809 */ 810 private UserData getUserDataNoChecks(int userId) { 811 synchronized (mUsersLock) { 812 return mUsers.get(userId); 813 } 814 } 815 816 /** Called by PackageManagerService */ 817 public boolean exists(int userId) { 818 return getUserInfoNoChecks(userId) != null; 819 } 820 821 @Override 822 public void setUserName(int userId, String name) { 823 checkManageUsersPermission("rename users"); 824 boolean changed = false; 825 synchronized (mPackagesLock) { 826 UserData userData = getUserDataNoChecks(userId); 827 if (userData == null || userData.info.partial) { 828 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId); 829 return; 830 } 831 if (name != null && !name.equals(userData.info.name)) { 832 userData.info.name = name; 833 writeUserLP(userData); 834 changed = true; 835 } 836 } 837 if (changed) { 838 sendUserInfoChangedBroadcast(userId); 839 } 840 } 841 842 @Override 843 public void setUserIcon(int userId, Bitmap bitmap) { 844 checkManageUsersPermission("update users"); 845 if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) { 846 Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled."); 847 return; 848 } 849 mLocalService.setUserIcon(userId, bitmap); 850 } 851 852 853 854 private void sendUserInfoChangedBroadcast(int userId) { 855 Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED); 856 changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 857 changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 858 mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL); 859 } 860 861 @Override 862 public ParcelFileDescriptor getUserIcon(int targetUserId) { 863 String iconPath; 864 synchronized (mPackagesLock) { 865 UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId); 866 if (targetUserInfo == null || targetUserInfo.partial) { 867 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId); 868 return null; 869 } 870 871 final int callingUserId = UserHandle.getCallingUserId(); 872 final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId; 873 final int targetGroupId = targetUserInfo.profileGroupId; 874 final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID 875 && callingGroupId == targetGroupId); 876 if ((callingUserId != targetUserId) && !sameGroup) { 877 checkManageUsersPermission("get the icon of a user who is not related"); 878 } 879 880 if (targetUserInfo.iconPath == null) { 881 return null; 882 } 883 iconPath = targetUserInfo.iconPath; 884 } 885 886 try { 887 return ParcelFileDescriptor.open( 888 new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY); 889 } catch (FileNotFoundException e) { 890 Log.e(LOG_TAG, "Couldn't find icon file", e); 891 } 892 return null; 893 } 894 895 public void makeInitialized(int userId) { 896 checkManageUsersPermission("makeInitialized"); 897 boolean scheduleWriteUser = false; 898 UserData userData; 899 synchronized (mUsersLock) { 900 userData = mUsers.get(userId); 901 if (userData == null || userData.info.partial) { 902 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId); 903 return; 904 } 905 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 906 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 907 scheduleWriteUser = true; 908 } 909 } 910 if (scheduleWriteUser) { 911 scheduleWriteUser(userData); 912 } 913 } 914 915 /** 916 * If default guest restrictions haven't been initialized yet, add the basic 917 * restrictions. 918 */ 919 private void initDefaultGuestRestrictions() { 920 synchronized (mGuestRestrictions) { 921 if (mGuestRestrictions.isEmpty()) { 922 mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true); 923 mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); 924 mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true); 925 mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); 926 } 927 } 928 } 929 930 @Override 931 public Bundle getDefaultGuestRestrictions() { 932 checkManageUsersPermission("getDefaultGuestRestrictions"); 933 synchronized (mGuestRestrictions) { 934 return new Bundle(mGuestRestrictions); 935 } 936 } 937 938 @Override 939 public void setDefaultGuestRestrictions(Bundle restrictions) { 940 checkManageUsersPermission("setDefaultGuestRestrictions"); 941 synchronized (mGuestRestrictions) { 942 mGuestRestrictions.clear(); 943 mGuestRestrictions.putAll(restrictions); 944 } 945 synchronized (mPackagesLock) { 946 writeUserListLP(); 947 } 948 } 949 950 /** 951 * See {@link UserManagerInternal#setDevicePolicyUserRestrictions(int, Bundle, Bundle)} 952 */ 953 void setDevicePolicyUserRestrictionsInner(int userId, @NonNull Bundle local, 954 @Nullable Bundle global) { 955 Preconditions.checkNotNull(local); 956 boolean globalChanged = false; 957 boolean localChanged; 958 synchronized (mRestrictionsLock) { 959 if (global != null) { 960 // Update global. 961 globalChanged = !UserRestrictionsUtils.areEqual( 962 mDevicePolicyGlobalUserRestrictions, global); 963 if (globalChanged) { 964 mDevicePolicyGlobalUserRestrictions = global; 965 } 966 } 967 { 968 // Update local. 969 final Bundle prev = mDevicePolicyLocalUserRestrictions.get(userId); 970 localChanged = !UserRestrictionsUtils.areEqual(prev, local); 971 if (localChanged) { 972 mDevicePolicyLocalUserRestrictions.put(userId, local); 973 } 974 } 975 } 976 if (DBG) { 977 Log.d(LOG_TAG, "setDevicePolicyUserRestrictions: userId=" + userId 978 + " global=" + global + (globalChanged ? " (changed)" : "") 979 + " local=" + local + (localChanged ? " (changed)" : "") 980 ); 981 } 982 // Don't call them within the mRestrictionsLock. 983 synchronized (mPackagesLock) { 984 if (localChanged) { 985 writeUserLP(getUserDataNoChecks(userId)); 986 } 987 if (globalChanged) { 988 writeUserListLP(); 989 } 990 } 991 992 synchronized (mRestrictionsLock) { 993 if (globalChanged) { 994 applyUserRestrictionsForAllUsersLR(); 995 } else if (localChanged) { 996 applyUserRestrictionsLR(userId); 997 } 998 } 999 } 1000 1001 @GuardedBy("mRestrictionsLock") 1002 private Bundle computeEffectiveUserRestrictionsLR(int userId) { 1003 final Bundle baseRestrictions = 1004 UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId)); 1005 final Bundle global = mDevicePolicyGlobalUserRestrictions; 1006 final Bundle local = mDevicePolicyLocalUserRestrictions.get(userId); 1007 1008 if (UserRestrictionsUtils.isEmpty(global) && UserRestrictionsUtils.isEmpty(local)) { 1009 // Common case first. 1010 return baseRestrictions; 1011 } 1012 final Bundle effective = UserRestrictionsUtils.clone(baseRestrictions); 1013 UserRestrictionsUtils.merge(effective, global); 1014 UserRestrictionsUtils.merge(effective, local); 1015 1016 return effective; 1017 } 1018 1019 @GuardedBy("mRestrictionsLock") 1020 private void invalidateEffectiveUserRestrictionsLR(int userId) { 1021 if (DBG) { 1022 Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId); 1023 } 1024 mCachedEffectiveUserRestrictions.remove(userId); 1025 } 1026 1027 private Bundle getEffectiveUserRestrictions(int userId) { 1028 synchronized (mRestrictionsLock) { 1029 Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId); 1030 if (restrictions == null) { 1031 restrictions = computeEffectiveUserRestrictionsLR(userId); 1032 mCachedEffectiveUserRestrictions.put(userId, restrictions); 1033 } 1034 return restrictions; 1035 } 1036 } 1037 1038 /** @return a specific user restriction that's in effect currently. */ 1039 @Override 1040 public boolean hasUserRestriction(String restrictionKey, int userId) { 1041 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1042 return false; 1043 } 1044 Bundle restrictions = getEffectiveUserRestrictions(userId); 1045 return restrictions != null && restrictions.getBoolean(restrictionKey); 1046 } 1047 1048 /** 1049 * @return UserRestrictions that are in effect currently. This always returns a new 1050 * {@link Bundle}. 1051 */ 1052 @Override 1053 public Bundle getUserRestrictions(int userId) { 1054 return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId)); 1055 } 1056 1057 @Override 1058 public boolean hasBaseUserRestriction(String restrictionKey, int userId) { 1059 checkManageUsersPermission("hasBaseUserRestriction"); 1060 if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) { 1061 return false; 1062 } 1063 synchronized (mRestrictionsLock) { 1064 Bundle bundle = mBaseUserRestrictions.get(userId); 1065 return (bundle != null && bundle.getBoolean(restrictionKey, false)); 1066 } 1067 } 1068 1069 @Override 1070 public void setUserRestriction(String key, boolean value, int userId) { 1071 checkManageUsersPermission("setUserRestriction"); 1072 if (!UserRestrictionsUtils.isValidRestriction(key)) { 1073 return; 1074 } 1075 synchronized (mRestrictionsLock) { 1076 // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create 1077 // a copy. 1078 final Bundle newRestrictions = UserRestrictionsUtils.clone( 1079 mBaseUserRestrictions.get(userId)); 1080 newRestrictions.putBoolean(key, value); 1081 1082 updateUserRestrictionsInternalLR(newRestrictions, userId); 1083 } 1084 } 1085 1086 /** 1087 * Optionally updating user restrictions, calculate the effective user restrictions and also 1088 * propagate to other services and system settings. 1089 * 1090 * @param newRestrictions User restrictions to set. 1091 * If null, will not update user restrictions and only does the propagation. 1092 * @param userId target user ID. 1093 */ 1094 @GuardedBy("mRestrictionsLock") 1095 private void updateUserRestrictionsInternalLR( 1096 @Nullable Bundle newRestrictions, int userId) { 1097 1098 final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull( 1099 mAppliedUserRestrictions.get(userId)); 1100 1101 // Update base restrictions. 1102 if (newRestrictions != null) { 1103 // If newRestrictions == the current one, it's probably a bug. 1104 final Bundle prevBaseRestrictions = mBaseUserRestrictions.get(userId); 1105 1106 Preconditions.checkState(prevBaseRestrictions != newRestrictions); 1107 Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId) 1108 != newRestrictions); 1109 1110 if (!UserRestrictionsUtils.areEqual(prevBaseRestrictions, newRestrictions)) { 1111 mBaseUserRestrictions.put(userId, newRestrictions); 1112 scheduleWriteUser(getUserDataNoChecks(userId)); 1113 } 1114 } 1115 1116 final Bundle effective = computeEffectiveUserRestrictionsLR(userId); 1117 1118 mCachedEffectiveUserRestrictions.put(userId, effective); 1119 1120 // Apply the new restrictions. 1121 if (DBG) { 1122 debug("Applying user restrictions: userId=" + userId 1123 + " new=" + effective + " prev=" + prevAppliedRestrictions); 1124 } 1125 1126 if (mAppOpsService != null) { // We skip it until system-ready. 1127 final long token = Binder.clearCallingIdentity(); 1128 try { 1129 mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId); 1130 } catch (RemoteException e) { 1131 Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions"); 1132 } finally { 1133 Binder.restoreCallingIdentity(token); 1134 } 1135 } 1136 1137 propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions); 1138 1139 mAppliedUserRestrictions.put(userId, new Bundle(effective)); 1140 } 1141 1142 private void propagateUserRestrictionsLR(final int userId, 1143 Bundle newRestrictions, Bundle prevRestrictions) { 1144 // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock 1145 // actually, but we still need some kind of synchronization otherwise we might end up 1146 // calling listeners out-of-order, thus "LR". 1147 1148 if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) { 1149 return; 1150 } 1151 1152 final Bundle newRestrictionsFinal = new Bundle(newRestrictions); 1153 final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions); 1154 1155 mHandler.post(new Runnable() { 1156 @Override 1157 public void run() { 1158 UserRestrictionsUtils.applyUserRestrictions( 1159 mContext, userId, newRestrictionsFinal, prevRestrictionsFinal); 1160 1161 final UserRestrictionsListener[] listeners; 1162 synchronized (mUserRestrictionsListeners) { 1163 listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()]; 1164 mUserRestrictionsListeners.toArray(listeners); 1165 } 1166 for (int i = 0; i < listeners.length; i++) { 1167 listeners[i].onUserRestrictionsChanged(userId, 1168 newRestrictionsFinal, prevRestrictionsFinal); 1169 } 1170 } 1171 }); 1172 } 1173 1174 // Package private for the inner class. 1175 void applyUserRestrictionsLR(int userId) { 1176 updateUserRestrictionsInternalLR(null, userId); 1177 } 1178 1179 @GuardedBy("mRestrictionsLock") 1180 // Package private for the inner class. 1181 void applyUserRestrictionsForAllUsersLR() { 1182 if (DBG) { 1183 debug("applyUserRestrictionsForAllUsersLR"); 1184 } 1185 // First, invalidate all cached values. 1186 mCachedEffectiveUserRestrictions.clear(); 1187 1188 // We don't want to call into ActivityManagerNative while taking a lock, so we'll call 1189 // it on a handler. 1190 final Runnable r = new Runnable() { 1191 @Override 1192 public void run() { 1193 // Then get the list of running users. 1194 final int[] runningUsers; 1195 try { 1196 runningUsers = ActivityManagerNative.getDefault().getRunningUserIds(); 1197 } catch (RemoteException e) { 1198 Log.w(LOG_TAG, "Unable to access ActivityManagerNative"); 1199 return; 1200 } 1201 // Then re-calculate the effective restrictions and apply, only for running users. 1202 // It's okay if a new user has started after the getRunningUserIds() call, 1203 // because we'll do the same thing (re-calculate the restrictions and apply) 1204 // when we start a user. 1205 synchronized (mRestrictionsLock) { 1206 for (int i = 0; i < runningUsers.length; i++) { 1207 applyUserRestrictionsLR(runningUsers[i]); 1208 } 1209 } 1210 } 1211 }; 1212 mHandler.post(r); 1213 } 1214 1215 /** 1216 * Check if we've hit the limit of how many users can be created. 1217 */ 1218 private boolean isUserLimitReached() { 1219 int count; 1220 synchronized (mUsersLock) { 1221 count = getAliveUsersExcludingGuestsCountLU(); 1222 } 1223 return count >= UserManager.getMaxSupportedUsers(); 1224 } 1225 1226 @Override 1227 public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) { 1228 checkManageUsersPermission("check if more managed profiles can be added."); 1229 if (ActivityManager.isLowRamDeviceStatic()) { 1230 return false; 1231 } 1232 if (!mContext.getPackageManager().hasSystemFeature( 1233 PackageManager.FEATURE_MANAGED_USERS)) { 1234 return false; 1235 } 1236 // Limit number of managed profiles that can be created 1237 final int managedProfilesCount = getProfiles(userId, true).size() - 1; 1238 final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0; 1239 if (managedProfilesCount - profilesRemovedCount >= MAX_MANAGED_PROFILES) { 1240 return false; 1241 } 1242 synchronized(mUsersLock) { 1243 UserInfo userInfo = getUserInfoLU(userId); 1244 if (!userInfo.canHaveProfile()) { 1245 return false; 1246 } 1247 int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU() 1248 - profilesRemovedCount; 1249 // We allow creating a managed profile in the special case where there is only one user. 1250 return usersCountAfterRemoving == 1 1251 || usersCountAfterRemoving < UserManager.getMaxSupportedUsers(); 1252 } 1253 } 1254 1255 private int getAliveUsersExcludingGuestsCountLU() { 1256 int aliveUserCount = 0; 1257 final int totalUserCount = mUsers.size(); 1258 // Skip over users being removed 1259 for (int i = 0; i < totalUserCount; i++) { 1260 UserInfo user = mUsers.valueAt(i).info; 1261 if (!mRemovingUserIds.get(user.id) 1262 && !user.isGuest() && !user.partial) { 1263 aliveUserCount++; 1264 } 1265 } 1266 return aliveUserCount; 1267 } 1268 1269 /** 1270 * Enforces that only the system UID or root's UID or apps that have the 1271 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and 1272 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL} 1273 * permissions can make certain calls to the UserManager. 1274 * 1275 * @param message used as message if SecurityException is thrown 1276 * @throws SecurityException if the caller does not have enough privilege. 1277 */ 1278 private static final void checkManageUserAndAcrossUsersFullPermission(String message) { 1279 final int uid = Binder.getCallingUid(); 1280 if (uid != Process.SYSTEM_UID && uid != 0 1281 && ActivityManager.checkComponentPermission( 1282 Manifest.permission.MANAGE_USERS, 1283 uid, -1, true) != PackageManager.PERMISSION_GRANTED 1284 && ActivityManager.checkComponentPermission( 1285 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1286 uid, -1, true) != PackageManager.PERMISSION_GRANTED) { 1287 throw new SecurityException( 1288 "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " 1289 + message); 1290 } 1291 } 1292 1293 /** 1294 * Enforces that only the system UID or root's UID or apps that have the 1295 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} 1296 * permission can make certain calls to the UserManager. 1297 * 1298 * @param message used as message if SecurityException is thrown 1299 * @throws SecurityException if the caller is not system or root 1300 * @see #hasManageUsersPermission() 1301 */ 1302 private static final void checkManageUsersPermission(String message) { 1303 if (!hasManageUsersPermission()) { 1304 throw new SecurityException("You need MANAGE_USERS permission to: " + message); 1305 } 1306 } 1307 1308 /** 1309 * @return whether the calling UID is system UID or root's UID or the calling app has the 1310 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}. 1311 */ 1312 private static final boolean hasManageUsersPermission() { 1313 final int callingUid = Binder.getCallingUid(); 1314 return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) 1315 || callingUid == Process.ROOT_UID 1316 || ActivityManager.checkComponentPermission( 1317 android.Manifest.permission.MANAGE_USERS, 1318 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED; 1319 } 1320 1321 /** 1322 * Enforces that only the system UID or root's UID (on any user) can make certain calls to the 1323 * UserManager. 1324 * 1325 * @param message used as message if SecurityException is thrown 1326 * @throws SecurityException if the caller is not system or root 1327 */ 1328 private static void checkSystemOrRoot(String message) { 1329 final int uid = Binder.getCallingUid(); 1330 if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) { 1331 throw new SecurityException("Only system may: " + message); 1332 } 1333 } 1334 1335 private void writeBitmapLP(UserInfo info, Bitmap bitmap) { 1336 try { 1337 File dir = new File(mUsersDir, Integer.toString(info.id)); 1338 File file = new File(dir, USER_PHOTO_FILENAME); 1339 File tmp = new File(dir, USER_PHOTO_FILENAME_TMP); 1340 if (!dir.exists()) { 1341 dir.mkdir(); 1342 FileUtils.setPermissions( 1343 dir.getPath(), 1344 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1345 -1, -1); 1346 } 1347 FileOutputStream os; 1348 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp)) 1349 && tmp.renameTo(file) && SELinux.restorecon(file)) { 1350 info.iconPath = file.getAbsolutePath(); 1351 } 1352 try { 1353 os.close(); 1354 } catch (IOException ioe) { 1355 // What the ... ! 1356 } 1357 tmp.delete(); 1358 } catch (FileNotFoundException e) { 1359 Slog.w(LOG_TAG, "Error setting photo for user ", e); 1360 } 1361 } 1362 1363 /** 1364 * Returns an array of user ids. This array is cached here for quick access, so do not modify or 1365 * cache it elsewhere. 1366 * @return the array of user ids. 1367 */ 1368 public int[] getUserIds() { 1369 synchronized (mUsersLock) { 1370 return mUserIds; 1371 } 1372 } 1373 1374 private void readUserListLP() { 1375 if (!mUserListFile.exists()) { 1376 fallbackToSingleUserLP(); 1377 return; 1378 } 1379 FileInputStream fis = null; 1380 AtomicFile userListFile = new AtomicFile(mUserListFile); 1381 try { 1382 fis = userListFile.openRead(); 1383 XmlPullParser parser = Xml.newPullParser(); 1384 parser.setInput(fis, StandardCharsets.UTF_8.name()); 1385 int type; 1386 while ((type = parser.next()) != XmlPullParser.START_TAG 1387 && type != XmlPullParser.END_DOCUMENT) { 1388 // Skip 1389 } 1390 1391 if (type != XmlPullParser.START_TAG) { 1392 Slog.e(LOG_TAG, "Unable to read user list"); 1393 fallbackToSingleUserLP(); 1394 return; 1395 } 1396 1397 mNextSerialNumber = -1; 1398 if (parser.getName().equals(TAG_USERS)) { 1399 String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO); 1400 if (lastSerialNumber != null) { 1401 mNextSerialNumber = Integer.parseInt(lastSerialNumber); 1402 } 1403 String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION); 1404 if (versionNumber != null) { 1405 mUserVersion = Integer.parseInt(versionNumber); 1406 } 1407 } 1408 1409 final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle(); 1410 1411 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 1412 if (type == XmlPullParser.START_TAG) { 1413 final String name = parser.getName(); 1414 if (name.equals(TAG_USER)) { 1415 String id = parser.getAttributeValue(null, ATTR_ID); 1416 1417 UserData userData = readUserLP(Integer.parseInt(id)); 1418 1419 if (userData != null) { 1420 synchronized (mUsersLock) { 1421 mUsers.put(userData.info.id, userData); 1422 if (mNextSerialNumber < 0 1423 || mNextSerialNumber <= userData.info.id) { 1424 mNextSerialNumber = userData.info.id + 1; 1425 } 1426 } 1427 } 1428 } else if (name.equals(TAG_GUEST_RESTRICTIONS)) { 1429 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1430 && type != XmlPullParser.END_TAG) { 1431 if (type == XmlPullParser.START_TAG) { 1432 if (parser.getName().equals(TAG_RESTRICTIONS)) { 1433 synchronized (mGuestRestrictions) { 1434 UserRestrictionsUtils 1435 .readRestrictions(parser, mGuestRestrictions); 1436 } 1437 } else if (parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS) 1438 ) { 1439 UserRestrictionsUtils.readRestrictions(parser, 1440 newDevicePolicyGlobalUserRestrictions); 1441 } 1442 break; 1443 } 1444 } 1445 } 1446 } 1447 } 1448 synchronized (mRestrictionsLock) { 1449 mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions; 1450 } 1451 updateUserIds(); 1452 upgradeIfNecessaryLP(); 1453 } catch (IOException | XmlPullParserException e) { 1454 fallbackToSingleUserLP(); 1455 } finally { 1456 IoUtils.closeQuietly(fis); 1457 } 1458 } 1459 1460 /** 1461 * Upgrade steps between versions, either for fixing bugs or changing the data format. 1462 */ 1463 private void upgradeIfNecessaryLP() { 1464 final int originalVersion = mUserVersion; 1465 int userVersion = mUserVersion; 1466 if (userVersion < 1) { 1467 // Assign a proper name for the owner, if not initialized correctly before 1468 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 1469 if ("Primary".equals(userData.info.name)) { 1470 userData.info.name = 1471 mContext.getResources().getString(com.android.internal.R.string.owner_name); 1472 scheduleWriteUser(userData); 1473 } 1474 userVersion = 1; 1475 } 1476 1477 if (userVersion < 2) { 1478 // Owner should be marked as initialized 1479 UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); 1480 if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 1481 userData.info.flags |= UserInfo.FLAG_INITIALIZED; 1482 scheduleWriteUser(userData); 1483 } 1484 userVersion = 2; 1485 } 1486 1487 1488 if (userVersion < 4) { 1489 userVersion = 4; 1490 } 1491 1492 if (userVersion < 5) { 1493 initDefaultGuestRestrictions(); 1494 userVersion = 5; 1495 } 1496 1497 if (userVersion < 6) { 1498 final boolean splitSystemUser = UserManager.isSplitSystemUser(); 1499 synchronized (mUsersLock) { 1500 for (int i = 0; i < mUsers.size(); i++) { 1501 UserData userData = mUsers.valueAt(i); 1502 // In non-split mode, only user 0 can have restricted profiles 1503 if (!splitSystemUser && userData.info.isRestricted() 1504 && (userData.info.restrictedProfileParentId 1505 == UserInfo.NO_PROFILE_GROUP_ID)) { 1506 userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM; 1507 scheduleWriteUser(userData); 1508 } 1509 } 1510 } 1511 userVersion = 6; 1512 } 1513 1514 if (userVersion < USER_VERSION) { 1515 Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to " 1516 + USER_VERSION); 1517 } else { 1518 mUserVersion = userVersion; 1519 1520 if (originalVersion < mUserVersion) { 1521 writeUserListLP(); 1522 } 1523 } 1524 } 1525 1526 private void fallbackToSingleUserLP() { 1527 int flags = UserInfo.FLAG_INITIALIZED; 1528 // In split system user mode, the admin and primary flags are assigned to the first human 1529 // user. 1530 if (!UserManager.isSplitSystemUser()) { 1531 flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY; 1532 } 1533 // Create the system user 1534 UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags); 1535 UserData userData = new UserData(); 1536 userData.info = system; 1537 synchronized (mUsersLock) { 1538 mUsers.put(system.id, userData); 1539 } 1540 mNextSerialNumber = MIN_USER_ID; 1541 mUserVersion = USER_VERSION; 1542 1543 Bundle restrictions = new Bundle(); 1544 synchronized (mRestrictionsLock) { 1545 mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions); 1546 } 1547 1548 updateUserIds(); 1549 initDefaultGuestRestrictions(); 1550 1551 writeUserLP(userData); 1552 writeUserListLP(); 1553 } 1554 1555 private String getOwnerName() { 1556 return mContext.getResources().getString(com.android.internal.R.string.owner_name); 1557 } 1558 1559 private void scheduleWriteUser(UserData UserData) { 1560 if (DBG) { 1561 debug("scheduleWriteUser"); 1562 } 1563 // No need to wrap it within a lock -- worst case, we'll just post the same message 1564 // twice. 1565 if (!mHandler.hasMessages(WRITE_USER_MSG, UserData)) { 1566 Message msg = mHandler.obtainMessage(WRITE_USER_MSG, UserData); 1567 mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); 1568 } 1569 } 1570 1571 /* 1572 * Writes the user file in this format: 1573 * 1574 * <user flags="20039023" id="0"> 1575 * <name>Primary</name> 1576 * </user> 1577 */ 1578 private void writeUserLP(UserData userData) { 1579 if (DBG) { 1580 debug("writeUserLP " + userData); 1581 } 1582 FileOutputStream fos = null; 1583 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX)); 1584 try { 1585 fos = userFile.startWrite(); 1586 final BufferedOutputStream bos = new BufferedOutputStream(fos); 1587 1588 // XmlSerializer serializer = XmlUtils.serializerInstance(); 1589 final XmlSerializer serializer = new FastXmlSerializer(); 1590 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 1591 serializer.startDocument(null, true); 1592 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1593 1594 final UserInfo userInfo = userData.info; 1595 serializer.startTag(null, TAG_USER); 1596 serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); 1597 serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber)); 1598 serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); 1599 serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime)); 1600 serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME, 1601 Long.toString(userInfo.lastLoggedInTime)); 1602 if (userInfo.lastLoggedInFingerprint != null) { 1603 serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT, 1604 userInfo.lastLoggedInFingerprint); 1605 } 1606 if (userInfo.iconPath != null) { 1607 serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); 1608 } 1609 if (userInfo.partial) { 1610 serializer.attribute(null, ATTR_PARTIAL, "true"); 1611 } 1612 if (userInfo.guestToRemove) { 1613 serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true"); 1614 } 1615 if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 1616 serializer.attribute(null, ATTR_PROFILE_GROUP_ID, 1617 Integer.toString(userInfo.profileGroupId)); 1618 } 1619 if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) { 1620 serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID, 1621 Integer.toString(userInfo.restrictedProfileParentId)); 1622 } 1623 // Write seed data 1624 if (userData.persistSeedData) { 1625 if (userData.seedAccountName != null) { 1626 serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName); 1627 } 1628 if (userData.seedAccountType != null) { 1629 serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType); 1630 } 1631 } 1632 if (userInfo.name != null) { 1633 serializer.startTag(null, TAG_NAME); 1634 serializer.text(userInfo.name); 1635 serializer.endTag(null, TAG_NAME); 1636 } 1637 synchronized (mRestrictionsLock) { 1638 UserRestrictionsUtils.writeRestrictions(serializer, 1639 mBaseUserRestrictions.get(userInfo.id), TAG_RESTRICTIONS); 1640 UserRestrictionsUtils.writeRestrictions(serializer, 1641 mDevicePolicyLocalUserRestrictions.get(userInfo.id), 1642 TAG_DEVICE_POLICY_RESTRICTIONS); 1643 } 1644 1645 if (userData.account != null) { 1646 serializer.startTag(null, TAG_ACCOUNT); 1647 serializer.text(userData.account); 1648 serializer.endTag(null, TAG_ACCOUNT); 1649 } 1650 1651 if (userData.persistSeedData && userData.seedAccountOptions != null) { 1652 serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS); 1653 userData.seedAccountOptions.saveToXml(serializer); 1654 serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS); 1655 } 1656 serializer.endTag(null, TAG_USER); 1657 1658 serializer.endDocument(); 1659 userFile.finishWrite(fos); 1660 } catch (Exception ioe) { 1661 Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe); 1662 userFile.failWrite(fos); 1663 } 1664 } 1665 1666 /* 1667 * Writes the user list file in this format: 1668 * 1669 * <users nextSerialNumber="3"> 1670 * <user id="0"></user> 1671 * <user id="2"></user> 1672 * </users> 1673 */ 1674 private void writeUserListLP() { 1675 if (DBG) { 1676 debug("writeUserList"); 1677 } 1678 FileOutputStream fos = null; 1679 AtomicFile userListFile = new AtomicFile(mUserListFile); 1680 try { 1681 fos = userListFile.startWrite(); 1682 final BufferedOutputStream bos = new BufferedOutputStream(fos); 1683 1684 // XmlSerializer serializer = XmlUtils.serializerInstance(); 1685 final XmlSerializer serializer = new FastXmlSerializer(); 1686 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 1687 serializer.startDocument(null, true); 1688 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1689 1690 serializer.startTag(null, TAG_USERS); 1691 serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber)); 1692 serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); 1693 1694 serializer.startTag(null, TAG_GUEST_RESTRICTIONS); 1695 synchronized (mGuestRestrictions) { 1696 UserRestrictionsUtils 1697 .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS); 1698 } 1699 serializer.endTag(null, TAG_GUEST_RESTRICTIONS); 1700 synchronized (mRestrictionsLock) { 1701 UserRestrictionsUtils.writeRestrictions(serializer, 1702 mDevicePolicyGlobalUserRestrictions, TAG_DEVICE_POLICY_RESTRICTIONS); 1703 } 1704 int[] userIdsToWrite; 1705 synchronized (mUsersLock) { 1706 userIdsToWrite = new int[mUsers.size()]; 1707 for (int i = 0; i < userIdsToWrite.length; i++) { 1708 UserInfo user = mUsers.valueAt(i).info; 1709 userIdsToWrite[i] = user.id; 1710 } 1711 } 1712 for (int id : userIdsToWrite) { 1713 serializer.startTag(null, TAG_USER); 1714 serializer.attribute(null, ATTR_ID, Integer.toString(id)); 1715 serializer.endTag(null, TAG_USER); 1716 } 1717 1718 serializer.endTag(null, TAG_USERS); 1719 1720 serializer.endDocument(); 1721 userListFile.finishWrite(fos); 1722 } catch (Exception e) { 1723 userListFile.failWrite(fos); 1724 Slog.e(LOG_TAG, "Error writing user list"); 1725 } 1726 } 1727 1728 private UserData readUserLP(int id) { 1729 int flags = 0; 1730 int serialNumber = id; 1731 String name = null; 1732 String account = null; 1733 String iconPath = null; 1734 long creationTime = 0L; 1735 long lastLoggedInTime = 0L; 1736 String lastLoggedInFingerprint = null; 1737 int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; 1738 int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID; 1739 boolean partial = false; 1740 boolean guestToRemove = false; 1741 boolean persistSeedData = false; 1742 String seedAccountName = null; 1743 String seedAccountType = null; 1744 PersistableBundle seedAccountOptions = null; 1745 Bundle baseRestrictions = new Bundle(); 1746 Bundle localRestrictions = new Bundle(); 1747 1748 FileInputStream fis = null; 1749 try { 1750 AtomicFile userFile = 1751 new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX)); 1752 fis = userFile.openRead(); 1753 XmlPullParser parser = Xml.newPullParser(); 1754 parser.setInput(fis, StandardCharsets.UTF_8.name()); 1755 int type; 1756 while ((type = parser.next()) != XmlPullParser.START_TAG 1757 && type != XmlPullParser.END_DOCUMENT) { 1758 // Skip 1759 } 1760 1761 if (type != XmlPullParser.START_TAG) { 1762 Slog.e(LOG_TAG, "Unable to read user " + id); 1763 return null; 1764 } 1765 1766 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) { 1767 int storedId = readIntAttribute(parser, ATTR_ID, -1); 1768 if (storedId != id) { 1769 Slog.e(LOG_TAG, "User id does not match the file name"); 1770 return null; 1771 } 1772 serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id); 1773 flags = readIntAttribute(parser, ATTR_FLAGS, 0); 1774 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); 1775 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0); 1776 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0); 1777 lastLoggedInFingerprint = parser.getAttributeValue(null, 1778 ATTR_LAST_LOGGED_IN_FINGERPRINT); 1779 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID, 1780 UserInfo.NO_PROFILE_GROUP_ID); 1781 restrictedProfileParentId = readIntAttribute(parser, 1782 ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID); 1783 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); 1784 if ("true".equals(valueString)) { 1785 partial = true; 1786 } 1787 valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE); 1788 if ("true".equals(valueString)) { 1789 guestToRemove = true; 1790 } 1791 1792 seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME); 1793 seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE); 1794 if (seedAccountName != null || seedAccountType != null) { 1795 persistSeedData = true; 1796 } 1797 1798 int outerDepth = parser.getDepth(); 1799 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1800 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1801 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1802 continue; 1803 } 1804 String tag = parser.getName(); 1805 if (TAG_NAME.equals(tag)) { 1806 type = parser.next(); 1807 if (type == XmlPullParser.TEXT) { 1808 name = parser.getText(); 1809 } 1810 } else if (TAG_RESTRICTIONS.equals(tag)) { 1811 UserRestrictionsUtils.readRestrictions(parser, baseRestrictions); 1812 } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) { 1813 UserRestrictionsUtils.readRestrictions(parser, localRestrictions); 1814 } else if (TAG_ACCOUNT.equals(tag)) { 1815 type = parser.next(); 1816 if (type == XmlPullParser.TEXT) { 1817 account = parser.getText(); 1818 } 1819 } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) { 1820 seedAccountOptions = PersistableBundle.restoreFromXml(parser); 1821 persistSeedData = true; 1822 } 1823 } 1824 } 1825 1826 // Create the UserInfo object that gets passed around 1827 UserInfo userInfo = new UserInfo(id, name, iconPath, flags); 1828 userInfo.serialNumber = serialNumber; 1829 userInfo.creationTime = creationTime; 1830 userInfo.lastLoggedInTime = lastLoggedInTime; 1831 userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint; 1832 userInfo.partial = partial; 1833 userInfo.guestToRemove = guestToRemove; 1834 userInfo.profileGroupId = profileGroupId; 1835 userInfo.restrictedProfileParentId = restrictedProfileParentId; 1836 1837 // Create the UserData object that's internal to this class 1838 UserData userData = new UserData(); 1839 userData.info = userInfo; 1840 userData.account = account; 1841 userData.seedAccountName = seedAccountName; 1842 userData.seedAccountType = seedAccountType; 1843 userData.persistSeedData = persistSeedData; 1844 userData.seedAccountOptions = seedAccountOptions; 1845 1846 synchronized (mRestrictionsLock) { 1847 mBaseUserRestrictions.put(id, baseRestrictions); 1848 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions); 1849 } 1850 return userData; 1851 } catch (IOException ioe) { 1852 } catch (XmlPullParserException pe) { 1853 } finally { 1854 if (fis != null) { 1855 try { 1856 fis.close(); 1857 } catch (IOException e) { 1858 } 1859 } 1860 } 1861 return null; 1862 } 1863 1864 private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) { 1865 String valueString = parser.getAttributeValue(null, attr); 1866 if (valueString == null) return defaultValue; 1867 try { 1868 return Integer.parseInt(valueString); 1869 } catch (NumberFormatException nfe) { 1870 return defaultValue; 1871 } 1872 } 1873 1874 private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) { 1875 String valueString = parser.getAttributeValue(null, attr); 1876 if (valueString == null) return defaultValue; 1877 try { 1878 return Long.parseLong(valueString); 1879 } catch (NumberFormatException nfe) { 1880 return defaultValue; 1881 } 1882 } 1883 1884 /** 1885 * Removes the app restrictions file for a specific package and user id, if it exists. 1886 */ 1887 private void cleanAppRestrictionsForPackage(String pkg, int userId) { 1888 synchronized (mPackagesLock) { 1889 File dir = Environment.getUserSystemDirectory(userId); 1890 File resFile = new File(dir, packageToRestrictionsFileName(pkg)); 1891 if (resFile.exists()) { 1892 resFile.delete(); 1893 } 1894 } 1895 } 1896 1897 @Override 1898 public UserInfo createProfileForUser(String name, int flags, int userId) { 1899 checkManageUsersPermission("Only the system can create users"); 1900 return createUserInternal(name, flags, userId); 1901 } 1902 1903 @Override 1904 public UserInfo createUser(String name, int flags) { 1905 checkManageUsersPermission("Only the system can create users"); 1906 return createUserInternal(name, flags, UserHandle.USER_NULL); 1907 } 1908 1909 private UserInfo createUserInternal(String name, int flags, int parentId) { 1910 if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) { 1911 Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled."); 1912 return null; 1913 } 1914 return createUserInternalUnchecked(name, flags, parentId); 1915 } 1916 1917 private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) { 1918 if (ActivityManager.isLowRamDeviceStatic()) { 1919 return null; 1920 } 1921 final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0; 1922 final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0; 1923 final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0; 1924 final long ident = Binder.clearCallingIdentity(); 1925 UserInfo userInfo; 1926 UserData userData; 1927 final int userId; 1928 try { 1929 synchronized (mPackagesLock) { 1930 UserData parent = null; 1931 if (parentId != UserHandle.USER_NULL) { 1932 synchronized (mUsersLock) { 1933 parent = getUserDataLU(parentId); 1934 } 1935 if (parent == null) return null; 1936 } 1937 if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) { 1938 Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId); 1939 return null; 1940 } 1941 if (!isGuest && !isManagedProfile && isUserLimitReached()) { 1942 // If we're not adding a guest user or a managed profile and the limit has 1943 // been reached, cannot add a user. 1944 return null; 1945 } 1946 // If we're adding a guest and there already exists one, bail. 1947 if (isGuest && findCurrentGuestUser() != null) { 1948 return null; 1949 } 1950 // In legacy mode, restricted profile's parent can only be the owner user 1951 if (isRestricted && !UserManager.isSplitSystemUser() 1952 && (parentId != UserHandle.USER_SYSTEM)) { 1953 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner"); 1954 return null; 1955 } 1956 if (isRestricted && UserManager.isSplitSystemUser()) { 1957 if (parent == null) { 1958 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be " 1959 + "specified"); 1960 return null; 1961 } 1962 if (!parent.info.canHaveProfile()) { 1963 Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be " 1964 + "created for the specified parent user id " + parentId); 1965 return null; 1966 } 1967 } 1968 if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0) { 1969 Log.e(LOG_TAG, 1970 "Ephemeral users are supported on split-system-user systems only."); 1971 return null; 1972 } 1973 // In split system user mode, we assign the first human user the primary flag. 1974 // And if there is no device owner, we also assign the admin flag to primary user. 1975 if (UserManager.isSplitSystemUser() 1976 && !isGuest && !isManagedProfile && getPrimaryUser() == null) { 1977 flags |= UserInfo.FLAG_PRIMARY; 1978 synchronized (mUsersLock) { 1979 if (!mIsDeviceManaged) { 1980 flags |= UserInfo.FLAG_ADMIN; 1981 } 1982 } 1983 } 1984 1985 userId = getNextAvailableId(); 1986 Environment.getUserSystemDirectory(userId).mkdirs(); 1987 boolean ephemeralGuests = Resources.getSystem() 1988 .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral); 1989 1990 synchronized (mUsersLock) { 1991 // Add ephemeral flag to guests/users if required. Also inherit it from parent. 1992 if ((isGuest && ephemeralGuests) || mForceEphemeralUsers 1993 || (parent != null && parent.info.isEphemeral())) { 1994 flags |= UserInfo.FLAG_EPHEMERAL; 1995 } 1996 1997 userInfo = new UserInfo(userId, name, null, flags); 1998 userInfo.serialNumber = mNextSerialNumber++; 1999 long now = System.currentTimeMillis(); 2000 userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0; 2001 userInfo.partial = true; 2002 userInfo.lastLoggedInFingerprint = Build.FINGERPRINT; 2003 userData = new UserData(); 2004 userData.info = userInfo; 2005 mUsers.put(userId, userData); 2006 } 2007 writeUserLP(userData); 2008 writeUserListLP(); 2009 if (parent != null) { 2010 if (isManagedProfile) { 2011 if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 2012 parent.info.profileGroupId = parent.info.id; 2013 writeUserLP(parent); 2014 } 2015 userInfo.profileGroupId = parent.info.profileGroupId; 2016 } else if (isRestricted) { 2017 if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) { 2018 parent.info.restrictedProfileParentId = parent.info.id; 2019 writeUserLP(parent); 2020 } 2021 userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId; 2022 } 2023 } 2024 } 2025 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2026 storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral()); 2027 prepareUserStorage(userId, userInfo.serialNumber, 2028 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 2029 mPm.createNewUser(userId); 2030 userInfo.partial = false; 2031 synchronized (mPackagesLock) { 2032 writeUserLP(userData); 2033 } 2034 updateUserIds(); 2035 Bundle restrictions = new Bundle(); 2036 if (isGuest) { 2037 synchronized (mGuestRestrictions) { 2038 restrictions.putAll(mGuestRestrictions); 2039 } 2040 } 2041 synchronized (mRestrictionsLock) { 2042 mBaseUserRestrictions.append(userId, restrictions); 2043 } 2044 mPm.newUserCreated(userId); 2045 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED); 2046 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 2047 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 2048 android.Manifest.permission.MANAGE_USERS); 2049 MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1); 2050 } finally { 2051 Binder.restoreCallingIdentity(ident); 2052 } 2053 return userInfo; 2054 } 2055 2056 /** 2057 * @hide 2058 */ 2059 @Override 2060 public UserInfo createRestrictedProfile(String name, int parentUserId) { 2061 checkManageUsersPermission("setupRestrictedProfile"); 2062 final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId); 2063 if (user == null) { 2064 return null; 2065 } 2066 long identity = Binder.clearCallingIdentity(); 2067 try { 2068 setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id); 2069 // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise 2070 // the putIntForUser() will fail. 2071 android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(), 2072 android.provider.Settings.Secure.LOCATION_MODE, 2073 android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id); 2074 setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id); 2075 } finally { 2076 Binder.restoreCallingIdentity(identity); 2077 } 2078 return user; 2079 } 2080 2081 /** 2082 * Find the current guest user. If the Guest user is partial, 2083 * then do not include it in the results as it is about to die. 2084 */ 2085 private UserInfo findCurrentGuestUser() { 2086 synchronized (mUsersLock) { 2087 final int size = mUsers.size(); 2088 for (int i = 0; i < size; i++) { 2089 final UserInfo user = mUsers.valueAt(i).info; 2090 if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) { 2091 return user; 2092 } 2093 } 2094 } 2095 return null; 2096 } 2097 2098 /** 2099 * Mark this guest user for deletion to allow us to create another guest 2100 * and switch to that user before actually removing this guest. 2101 * @param userHandle the userid of the current guest 2102 * @return whether the user could be marked for deletion 2103 */ 2104 @Override 2105 public boolean markGuestForDeletion(int userHandle) { 2106 checkManageUsersPermission("Only the system can remove users"); 2107 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 2108 UserManager.DISALLOW_REMOVE_USER, false)) { 2109 Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 2110 return false; 2111 } 2112 2113 long ident = Binder.clearCallingIdentity(); 2114 try { 2115 final UserData userData; 2116 synchronized (mPackagesLock) { 2117 synchronized (mUsersLock) { 2118 userData = mUsers.get(userHandle); 2119 if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) { 2120 return false; 2121 } 2122 } 2123 if (!userData.info.isGuest()) { 2124 return false; 2125 } 2126 // We set this to a guest user that is to be removed. This is a temporary state 2127 // where we are allowed to add new Guest users, even if this one is still not 2128 // removed. This user will still show up in getUserInfo() calls. 2129 // If we don't get around to removing this Guest user, it will be purged on next 2130 // startup. 2131 userData.info.guestToRemove = true; 2132 // Mark it as disabled, so that it isn't returned any more when 2133 // profiles are queried. 2134 userData.info.flags |= UserInfo.FLAG_DISABLED; 2135 writeUserLP(userData); 2136 } 2137 } finally { 2138 Binder.restoreCallingIdentity(ident); 2139 } 2140 return true; 2141 } 2142 2143 /** 2144 * Removes a user and all data directories created for that user. This method should be called 2145 * after the user's processes have been terminated. 2146 * @param userHandle the user's id 2147 */ 2148 @Override 2149 public boolean removeUser(int userHandle) { 2150 checkManageUsersPermission("Only the system can remove users"); 2151 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 2152 UserManager.DISALLOW_REMOVE_USER, false)) { 2153 Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 2154 return false; 2155 } 2156 2157 long ident = Binder.clearCallingIdentity(); 2158 try { 2159 final UserData userData; 2160 int currentUser = ActivityManager.getCurrentUser(); 2161 if (currentUser == userHandle) { 2162 Log.w(LOG_TAG, "Current user cannot be removed"); 2163 return false; 2164 } 2165 synchronized (mPackagesLock) { 2166 synchronized (mUsersLock) { 2167 userData = mUsers.get(userHandle); 2168 if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) { 2169 return false; 2170 } 2171 2172 // We remember deleted user IDs to prevent them from being 2173 // reused during the current boot; they can still be reused 2174 // after a reboot. 2175 mRemovingUserIds.put(userHandle, true); 2176 } 2177 2178 try { 2179 mAppOpsService.removeUser(userHandle); 2180 } catch (RemoteException e) { 2181 Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e); 2182 } 2183 // Set this to a partially created user, so that the user will be purged 2184 // on next startup, in case the runtime stops now before stopping and 2185 // removing the user completely. 2186 userData.info.partial = true; 2187 // Mark it as disabled, so that it isn't returned any more when 2188 // profiles are queried. 2189 userData.info.flags |= UserInfo.FLAG_DISABLED; 2190 writeUserLP(userData); 2191 } 2192 2193 if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 2194 && userData.info.isManagedProfile()) { 2195 // Send broadcast to notify system that the user removed was a 2196 // managed user. 2197 sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id); 2198 } 2199 2200 if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle); 2201 int res; 2202 try { 2203 res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true, 2204 new IStopUserCallback.Stub() { 2205 @Override 2206 public void userStopped(int userId) { 2207 finishRemoveUser(userId); 2208 } 2209 @Override 2210 public void userStopAborted(int userId) { 2211 } 2212 }); 2213 } catch (RemoteException e) { 2214 return false; 2215 } 2216 return res == ActivityManager.USER_OP_SUCCESS; 2217 } finally { 2218 Binder.restoreCallingIdentity(ident); 2219 } 2220 } 2221 2222 void finishRemoveUser(final int userHandle) { 2223 if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle); 2224 // Let other services shutdown any activity and clean up their state before completely 2225 // wiping the user's system directory and removing from the user list 2226 long ident = Binder.clearCallingIdentity(); 2227 try { 2228 Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED); 2229 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2230 mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL, 2231 android.Manifest.permission.MANAGE_USERS, 2232 2233 new BroadcastReceiver() { 2234 @Override 2235 public void onReceive(Context context, Intent intent) { 2236 if (DBG) { 2237 Slog.i(LOG_TAG, 2238 "USER_REMOVED broadcast sent, cleaning up user data " 2239 + userHandle); 2240 } 2241 new Thread() { 2242 @Override 2243 public void run() { 2244 // Clean up any ActivityManager state 2245 LocalServices.getService(ActivityManagerInternal.class) 2246 .onUserRemoved(userHandle); 2247 removeUserState(userHandle); 2248 } 2249 }.start(); 2250 } 2251 }, 2252 2253 null, Activity.RESULT_OK, null, null); 2254 } finally { 2255 Binder.restoreCallingIdentity(ident); 2256 } 2257 } 2258 2259 private void removeUserState(final int userHandle) { 2260 try { 2261 mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle); 2262 } catch (IllegalStateException e) { 2263 // This may be simply because the user was partially created. 2264 Slog.i(LOG_TAG, 2265 "Destroying key for user " + userHandle + " failed, continuing anyway", e); 2266 } 2267 // Cleanup package manager settings 2268 mPm.cleanUpUser(this, userHandle); 2269 2270 // Remove this user from the list 2271 synchronized (mUsersLock) { 2272 mUsers.remove(userHandle); 2273 mIsUserManaged.delete(userHandle); 2274 } 2275 synchronized (mRestrictionsLock) { 2276 mBaseUserRestrictions.remove(userHandle); 2277 mAppliedUserRestrictions.remove(userHandle); 2278 mCachedEffectiveUserRestrictions.remove(userHandle); 2279 mDevicePolicyLocalUserRestrictions.remove(userHandle); 2280 } 2281 // Update the user list 2282 synchronized (mPackagesLock) { 2283 writeUserListLP(); 2284 } 2285 // Remove user file 2286 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX)); 2287 userFile.delete(); 2288 updateUserIds(); 2289 File userDir = Environment.getUserSystemDirectory(userHandle); 2290 File renamedUserDir = Environment.getUserSystemDirectory(UserHandle.USER_NULL - userHandle); 2291 if (userDir.renameTo(renamedUserDir)) { 2292 removeDirectoryRecursive(renamedUserDir); 2293 } else { 2294 removeDirectoryRecursive(userDir); 2295 } 2296 } 2297 2298 private void removeDirectoryRecursive(File parent) { 2299 if (parent.isDirectory()) { 2300 String[] files = parent.list(); 2301 for (String filename : files) { 2302 File child = new File(parent, filename); 2303 removeDirectoryRecursive(child); 2304 } 2305 } 2306 parent.delete(); 2307 } 2308 2309 private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { 2310 Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); 2311 managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | 2312 Intent.FLAG_RECEIVER_FOREGROUND); 2313 managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); 2314 managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); 2315 mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null); 2316 } 2317 2318 @Override 2319 public Bundle getApplicationRestrictions(String packageName) { 2320 return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId()); 2321 } 2322 2323 @Override 2324 public Bundle getApplicationRestrictionsForUser(String packageName, int userId) { 2325 if (UserHandle.getCallingUserId() != userId 2326 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { 2327 checkSystemOrRoot("get application restrictions for other users/apps"); 2328 } 2329 synchronized (mPackagesLock) { 2330 // Read the restrictions from XML 2331 return readApplicationRestrictionsLP(packageName, userId); 2332 } 2333 } 2334 2335 @Override 2336 public void setApplicationRestrictions(String packageName, Bundle restrictions, 2337 int userId) { 2338 checkSystemOrRoot("set application restrictions"); 2339 synchronized (mPackagesLock) { 2340 if (restrictions == null || restrictions.isEmpty()) { 2341 cleanAppRestrictionsForPackage(packageName, userId); 2342 } else { 2343 restrictions.setDefusable(true); 2344 // Write the restrictions to XML 2345 writeApplicationRestrictionsLP(packageName, restrictions, userId); 2346 } 2347 } 2348 2349 // Notify package of changes via an intent - only sent to explicitly registered receivers. 2350 Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); 2351 changeIntent.setPackage(packageName); 2352 changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2353 mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId)); 2354 } 2355 2356 private int getUidForPackage(String packageName) { 2357 long ident = Binder.clearCallingIdentity(); 2358 try { 2359 return mContext.getPackageManager().getApplicationInfo(packageName, 2360 PackageManager.MATCH_UNINSTALLED_PACKAGES).uid; 2361 } catch (NameNotFoundException nnfe) { 2362 return -1; 2363 } finally { 2364 Binder.restoreCallingIdentity(ident); 2365 } 2366 } 2367 2368 private Bundle readApplicationRestrictionsLP(String packageName, int userId) { 2369 AtomicFile restrictionsFile = 2370 new AtomicFile(new File(Environment.getUserSystemDirectory(userId), 2371 packageToRestrictionsFileName(packageName))); 2372 return readApplicationRestrictionsLP(restrictionsFile); 2373 } 2374 2375 @VisibleForTesting 2376 static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) { 2377 final Bundle restrictions = new Bundle(); 2378 final ArrayList<String> values = new ArrayList<>(); 2379 if (!restrictionsFile.getBaseFile().exists()) { 2380 return restrictions; 2381 } 2382 2383 FileInputStream fis = null; 2384 try { 2385 fis = restrictionsFile.openRead(); 2386 XmlPullParser parser = Xml.newPullParser(); 2387 parser.setInput(fis, StandardCharsets.UTF_8.name()); 2388 XmlUtils.nextElement(parser); 2389 if (parser.getEventType() != XmlPullParser.START_TAG) { 2390 Slog.e(LOG_TAG, "Unable to read restrictions file " 2391 + restrictionsFile.getBaseFile()); 2392 return restrictions; 2393 } 2394 while (parser.next() != XmlPullParser.END_DOCUMENT) { 2395 readEntry(restrictions, values, parser); 2396 } 2397 } catch (IOException|XmlPullParserException e) { 2398 Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e); 2399 } finally { 2400 IoUtils.closeQuietly(fis); 2401 } 2402 return restrictions; 2403 } 2404 2405 private static void readEntry(Bundle restrictions, ArrayList<String> values, 2406 XmlPullParser parser) throws XmlPullParserException, IOException { 2407 int type = parser.getEventType(); 2408 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) { 2409 String key = parser.getAttributeValue(null, ATTR_KEY); 2410 String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE); 2411 String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE); 2412 if (multiple != null) { 2413 values.clear(); 2414 int count = Integer.parseInt(multiple); 2415 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) { 2416 if (type == XmlPullParser.START_TAG 2417 && parser.getName().equals(TAG_VALUE)) { 2418 values.add(parser.nextText().trim()); 2419 count--; 2420 } 2421 } 2422 String [] valueStrings = new String[values.size()]; 2423 values.toArray(valueStrings); 2424 restrictions.putStringArray(key, valueStrings); 2425 } else if (ATTR_TYPE_BUNDLE.equals(valType)) { 2426 restrictions.putBundle(key, readBundleEntry(parser, values)); 2427 } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) { 2428 final int outerDepth = parser.getDepth(); 2429 ArrayList<Bundle> bundleList = new ArrayList<>(); 2430 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 2431 Bundle childBundle = readBundleEntry(parser, values); 2432 bundleList.add(childBundle); 2433 } 2434 restrictions.putParcelableArray(key, 2435 bundleList.toArray(new Bundle[bundleList.size()])); 2436 } else { 2437 String value = parser.nextText().trim(); 2438 if (ATTR_TYPE_BOOLEAN.equals(valType)) { 2439 restrictions.putBoolean(key, Boolean.parseBoolean(value)); 2440 } else if (ATTR_TYPE_INTEGER.equals(valType)) { 2441 restrictions.putInt(key, Integer.parseInt(value)); 2442 } else { 2443 restrictions.putString(key, value); 2444 } 2445 } 2446 } 2447 } 2448 2449 private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values) 2450 throws IOException, XmlPullParserException { 2451 Bundle childBundle = new Bundle(); 2452 final int outerDepth = parser.getDepth(); 2453 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 2454 readEntry(childBundle, values, parser); 2455 } 2456 return childBundle; 2457 } 2458 2459 private void writeApplicationRestrictionsLP(String packageName, 2460 Bundle restrictions, int userId) { 2461 AtomicFile restrictionsFile = new AtomicFile( 2462 new File(Environment.getUserSystemDirectory(userId), 2463 packageToRestrictionsFileName(packageName))); 2464 writeApplicationRestrictionsLP(restrictions, restrictionsFile); 2465 } 2466 2467 @VisibleForTesting 2468 static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) { 2469 FileOutputStream fos = null; 2470 try { 2471 fos = restrictionsFile.startWrite(); 2472 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2473 2474 final XmlSerializer serializer = new FastXmlSerializer(); 2475 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 2476 serializer.startDocument(null, true); 2477 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2478 2479 serializer.startTag(null, TAG_RESTRICTIONS); 2480 writeBundle(restrictions, serializer); 2481 serializer.endTag(null, TAG_RESTRICTIONS); 2482 2483 serializer.endDocument(); 2484 restrictionsFile.finishWrite(fos); 2485 } catch (Exception e) { 2486 restrictionsFile.failWrite(fos); 2487 Slog.e(LOG_TAG, "Error writing application restrictions list", e); 2488 } 2489 } 2490 2491 private static void writeBundle(Bundle restrictions, XmlSerializer serializer) 2492 throws IOException { 2493 for (String key : restrictions.keySet()) { 2494 Object value = restrictions.get(key); 2495 serializer.startTag(null, TAG_ENTRY); 2496 serializer.attribute(null, ATTR_KEY, key); 2497 2498 if (value instanceof Boolean) { 2499 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN); 2500 serializer.text(value.toString()); 2501 } else if (value instanceof Integer) { 2502 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER); 2503 serializer.text(value.toString()); 2504 } else if (value == null || value instanceof String) { 2505 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING); 2506 serializer.text(value != null ? (String) value : ""); 2507 } else if (value instanceof Bundle) { 2508 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 2509 writeBundle((Bundle) value, serializer); 2510 } else if (value instanceof Parcelable[]) { 2511 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY); 2512 Parcelable[] array = (Parcelable[]) value; 2513 for (Parcelable parcelable : array) { 2514 if (!(parcelable instanceof Bundle)) { 2515 throw new IllegalArgumentException("bundle-array can only hold Bundles"); 2516 } 2517 serializer.startTag(null, TAG_ENTRY); 2518 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 2519 writeBundle((Bundle) parcelable, serializer); 2520 serializer.endTag(null, TAG_ENTRY); 2521 } 2522 } else { 2523 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY); 2524 String[] values = (String[]) value; 2525 serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length)); 2526 for (String choice : values) { 2527 serializer.startTag(null, TAG_VALUE); 2528 serializer.text(choice != null ? choice : ""); 2529 serializer.endTag(null, TAG_VALUE); 2530 } 2531 } 2532 serializer.endTag(null, TAG_ENTRY); 2533 } 2534 } 2535 2536 @Override 2537 public int getUserSerialNumber(int userHandle) { 2538 synchronized (mUsersLock) { 2539 if (!exists(userHandle)) return -1; 2540 return getUserInfoLU(userHandle).serialNumber; 2541 } 2542 } 2543 2544 @Override 2545 public int getUserHandle(int userSerialNumber) { 2546 synchronized (mUsersLock) { 2547 for (int userId : mUserIds) { 2548 UserInfo info = getUserInfoLU(userId); 2549 if (info != null && info.serialNumber == userSerialNumber) return userId; 2550 } 2551 // Not found 2552 return -1; 2553 } 2554 } 2555 2556 @Override 2557 public long getUserCreationTime(int userHandle) { 2558 int callingUserId = UserHandle.getCallingUserId(); 2559 UserInfo userInfo = null; 2560 synchronized (mUsersLock) { 2561 if (callingUserId == userHandle) { 2562 userInfo = getUserInfoLU(userHandle); 2563 } else { 2564 UserInfo parent = getProfileParentLU(userHandle); 2565 if (parent != null && parent.id == callingUserId) { 2566 userInfo = getUserInfoLU(userHandle); 2567 } 2568 } 2569 } 2570 if (userInfo == null) { 2571 throw new SecurityException("userHandle can only be the calling user or a managed " 2572 + "profile associated with this user"); 2573 } 2574 return userInfo.creationTime; 2575 } 2576 2577 /** 2578 * Caches the list of user ids in an array, adjusting the array size when necessary. 2579 */ 2580 private void updateUserIds() { 2581 int num = 0; 2582 synchronized (mUsersLock) { 2583 final int userSize = mUsers.size(); 2584 for (int i = 0; i < userSize; i++) { 2585 if (!mUsers.valueAt(i).info.partial) { 2586 num++; 2587 } 2588 } 2589 final int[] newUsers = new int[num]; 2590 int n = 0; 2591 for (int i = 0; i < userSize; i++) { 2592 if (!mUsers.valueAt(i).info.partial) { 2593 newUsers[n++] = mUsers.keyAt(i); 2594 } 2595 } 2596 mUserIds = newUsers; 2597 } 2598 } 2599 2600 /** 2601 * Prepare storage areas for given user on all mounted devices. 2602 */ 2603 private void prepareUserStorage(int userId, int userSerial, int flags) { 2604 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2605 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 2606 final String volumeUuid = vol.getFsUuid(); 2607 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 2608 } 2609 } 2610 2611 /** 2612 * Called right before a user is started. This gives us a chance to prepare 2613 * app storage and apply any user restrictions. 2614 */ 2615 public void onBeforeStartUser(int userId) { 2616 final int userSerial = getUserSerialNumber(userId); 2617 prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_DE); 2618 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE); 2619 2620 if (userId != UserHandle.USER_SYSTEM) { 2621 synchronized (mRestrictionsLock) { 2622 applyUserRestrictionsLR(userId); 2623 } 2624 } 2625 } 2626 2627 /** 2628 * Called right before a user is unlocked. This gives us a chance to prepare 2629 * app storage. 2630 */ 2631 public void onBeforeUnlockUser(@UserIdInt int userId) { 2632 final int userSerial = getUserSerialNumber(userId); 2633 prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_CE); 2634 mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE); 2635 } 2636 2637 /** 2638 * Make a note of the last started time of a user and do some cleanup. 2639 * @param userId the user that was just foregrounded 2640 */ 2641 public void onUserLoggedIn(@UserIdInt int userId) { 2642 UserData userData = getUserDataNoChecks(userId); 2643 if (userData == null || userData.info.partial) { 2644 Slog.w(LOG_TAG, "userForeground: unknown user #" + userId); 2645 return; 2646 } 2647 2648 final long now = System.currentTimeMillis(); 2649 if (now > EPOCH_PLUS_30_YEARS) { 2650 userData.info.lastLoggedInTime = now; 2651 } 2652 userData.info.lastLoggedInFingerprint = Build.FINGERPRINT; 2653 scheduleWriteUser(userData); 2654 } 2655 2656 /** 2657 * Returns the next available user id, filling in any holes in the ids. 2658 * TODO: May not be a good idea to recycle ids, in case it results in confusion 2659 * for data and battery stats collection, or unexpected cross-talk. 2660 */ 2661 private int getNextAvailableId() { 2662 synchronized (mUsersLock) { 2663 int i = MIN_USER_ID; 2664 while (i < MAX_USER_ID) { 2665 if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) { 2666 return i; 2667 } 2668 i++; 2669 } 2670 } 2671 throw new IllegalStateException("No user id available!"); 2672 } 2673 2674 private String packageToRestrictionsFileName(String packageName) { 2675 return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX; 2676 } 2677 2678 /** 2679 * Enforce that serial number stored in user directory inode matches the 2680 * given expected value. Gracefully sets the serial number if currently 2681 * undefined. 2682 * 2683 * @throws IOException when problem extracting serial number, or serial 2684 * number is mismatched. 2685 */ 2686 public static void enforceSerialNumber(File file, int serialNumber) throws IOException { 2687 final int foundSerial = getSerialNumber(file); 2688 Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial); 2689 2690 if (foundSerial == -1) { 2691 Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid"); 2692 try { 2693 setSerialNumber(file, serialNumber); 2694 } catch (IOException e) { 2695 Slog.w(LOG_TAG, "Failed to set serial number on " + file, e); 2696 } 2697 2698 } else if (foundSerial != serialNumber) { 2699 throw new IOException("Found serial number " + foundSerial 2700 + " doesn't match expected " + serialNumber); 2701 } 2702 } 2703 2704 /** 2705 * Set serial number stored in user directory inode. 2706 * 2707 * @throws IOException if serial number was already set 2708 */ 2709 private static void setSerialNumber(File file, int serialNumber) 2710 throws IOException { 2711 try { 2712 final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8); 2713 Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE); 2714 } catch (ErrnoException e) { 2715 throw e.rethrowAsIOException(); 2716 } 2717 } 2718 2719 /** 2720 * Return serial number stored in user directory inode. 2721 * 2722 * @return parsed serial number, or -1 if not set 2723 */ 2724 private static int getSerialNumber(File file) throws IOException { 2725 try { 2726 final byte[] buf = new byte[256]; 2727 final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL, buf); 2728 final String serial = new String(buf, 0, len); 2729 try { 2730 return Integer.parseInt(serial); 2731 } catch (NumberFormatException e) { 2732 throw new IOException("Bad serial number: " + serial); 2733 } 2734 } catch (ErrnoException e) { 2735 if (e.errno == OsConstants.ENODATA) { 2736 return -1; 2737 } else { 2738 throw e.rethrowAsIOException(); 2739 } 2740 } 2741 } 2742 2743 @Override 2744 public void setSeedAccountData(int userId, String accountName, String accountType, 2745 PersistableBundle accountOptions, boolean persist) { 2746 checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data"); 2747 synchronized (mPackagesLock) { 2748 final UserData userData; 2749 synchronized (mUsersLock) { 2750 userData = getUserDataLU(userId); 2751 if (userData == null) { 2752 Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); 2753 return; 2754 } 2755 userData.seedAccountName = accountName; 2756 userData.seedAccountType = accountType; 2757 userData.seedAccountOptions = accountOptions; 2758 userData.persistSeedData = persist; 2759 } 2760 if (persist) { 2761 writeUserLP(userData); 2762 } 2763 } 2764 } 2765 2766 @Override 2767 public String getSeedAccountName() throws RemoteException { 2768 checkManageUsersPermission("Cannot get seed account information"); 2769 synchronized (mUsersLock) { 2770 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 2771 return userData.seedAccountName; 2772 } 2773 } 2774 2775 @Override 2776 public String getSeedAccountType() throws RemoteException { 2777 checkManageUsersPermission("Cannot get seed account information"); 2778 synchronized (mUsersLock) { 2779 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 2780 return userData.seedAccountType; 2781 } 2782 } 2783 2784 @Override 2785 public PersistableBundle getSeedAccountOptions() throws RemoteException { 2786 checkManageUsersPermission("Cannot get seed account information"); 2787 synchronized (mUsersLock) { 2788 UserData userData = getUserDataLU(UserHandle.getCallingUserId()); 2789 return userData.seedAccountOptions; 2790 } 2791 } 2792 2793 @Override 2794 public void clearSeedAccountData() throws RemoteException { 2795 checkManageUsersPermission("Cannot clear seed account information"); 2796 synchronized (mPackagesLock) { 2797 UserData userData; 2798 synchronized (mUsersLock) { 2799 userData = getUserDataLU(UserHandle.getCallingUserId()); 2800 if (userData == null) return; 2801 userData.clearSeedAccountData(); 2802 } 2803 writeUserLP(userData); 2804 } 2805 } 2806 2807 @Override 2808 public boolean someUserHasSeedAccount(String accountName, String accountType) 2809 throws RemoteException { 2810 checkManageUsersPermission("Cannot check seed account information"); 2811 synchronized (mUsersLock) { 2812 final int userSize = mUsers.size(); 2813 for (int i = 0; i < userSize; i++) { 2814 final UserData data = mUsers.valueAt(i); 2815 if (data.info.isInitialized()) continue; 2816 if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) { 2817 continue; 2818 } 2819 if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) { 2820 continue; 2821 } 2822 return true; 2823 } 2824 } 2825 return false; 2826 } 2827 2828 @Override 2829 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2830 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 2831 (new Shell()).exec(this, in, out, err, args, resultReceiver); 2832 } 2833 2834 int onShellCommand(Shell shell, String cmd) { 2835 if (cmd == null) { 2836 return shell.handleDefaultCommands(cmd); 2837 } 2838 2839 final PrintWriter pw = shell.getOutPrintWriter(); 2840 try { 2841 switch(cmd) { 2842 case "list": 2843 return runList(pw); 2844 } 2845 } catch (RemoteException e) { 2846 pw.println("Remote exception: " + e); 2847 } 2848 return -1; 2849 } 2850 2851 private int runList(PrintWriter pw) throws RemoteException { 2852 final IActivityManager am = ActivityManagerNative.getDefault(); 2853 final List<UserInfo> users = getUsers(false); 2854 if (users == null) { 2855 pw.println("Error: couldn't get users"); 2856 return 1; 2857 } else { 2858 pw.println("Users:"); 2859 for (int i = 0; i < users.size(); i++) { 2860 String running = am.isUserRunning(users.get(i).id, 0) ? " running" : ""; 2861 pw.println("\t" + users.get(i).toString() + running); 2862 } 2863 return 0; 2864 } 2865 } 2866 2867 @Override 2868 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2869 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2870 != PackageManager.PERMISSION_GRANTED) { 2871 pw.println("Permission Denial: can't dump UserManager from from pid=" 2872 + Binder.getCallingPid() 2873 + ", uid=" + Binder.getCallingUid() 2874 + " without permission " 2875 + android.Manifest.permission.DUMP); 2876 return; 2877 } 2878 2879 long now = System.currentTimeMillis(); 2880 StringBuilder sb = new StringBuilder(); 2881 synchronized (mPackagesLock) { 2882 synchronized (mUsersLock) { 2883 pw.println("Users:"); 2884 for (int i = 0; i < mUsers.size(); i++) { 2885 UserData userData = mUsers.valueAt(i); 2886 if (userData == null) { 2887 continue; 2888 } 2889 UserInfo userInfo = userData.info; 2890 final int userId = userInfo.id; 2891 pw.print(" "); pw.print(userInfo); 2892 pw.print(" serialNo="); pw.print(userInfo.serialNumber); 2893 if (mRemovingUserIds.get(userId)) { 2894 pw.print(" <removing> "); 2895 } 2896 if (userInfo.partial) { 2897 pw.print(" <partial>"); 2898 } 2899 pw.println(); 2900 pw.print(" Created: "); 2901 if (userInfo.creationTime == 0) { 2902 pw.println("<unknown>"); 2903 } else { 2904 sb.setLength(0); 2905 TimeUtils.formatDuration(now - userInfo.creationTime, sb); 2906 sb.append(" ago"); 2907 pw.println(sb); 2908 } 2909 pw.print(" Last logged in: "); 2910 if (userInfo.lastLoggedInTime == 0) { 2911 pw.println("<unknown>"); 2912 } else { 2913 sb.setLength(0); 2914 TimeUtils.formatDuration(now - userInfo.lastLoggedInTime, sb); 2915 sb.append(" ago"); 2916 pw.println(sb); 2917 } 2918 pw.print(" Last logged in fingerprint: "); 2919 pw.println(userInfo.lastLoggedInFingerprint); 2920 pw.print(" Has profile owner: "); 2921 pw.println(mIsUserManaged.get(userId)); 2922 pw.println(" Restrictions:"); 2923 synchronized (mRestrictionsLock) { 2924 UserRestrictionsUtils.dumpRestrictions( 2925 pw, " ", mBaseUserRestrictions.get(userInfo.id)); 2926 pw.println(" Device policy local restrictions:"); 2927 UserRestrictionsUtils.dumpRestrictions( 2928 pw, " ", mDevicePolicyLocalUserRestrictions.get(userInfo.id)); 2929 pw.println(" Effective restrictions:"); 2930 UserRestrictionsUtils.dumpRestrictions( 2931 pw, " ", mCachedEffectiveUserRestrictions.get(userInfo.id)); 2932 } 2933 2934 if (userData.account != null) { 2935 pw.print(" Account name: " + userData.account); 2936 pw.println(); 2937 } 2938 2939 if (userData.seedAccountName != null) { 2940 pw.print(" Seed account name: " + userData.seedAccountName); 2941 pw.println(); 2942 if (userData.seedAccountType != null) { 2943 pw.print(" account type: " + userData.seedAccountType); 2944 pw.println(); 2945 } 2946 if (userData.seedAccountOptions != null) { 2947 pw.print(" account options exist"); 2948 pw.println(); 2949 } 2950 } 2951 } 2952 } 2953 pw.println(); 2954 pw.println(" Device policy global restrictions:"); 2955 synchronized (mRestrictionsLock) { 2956 UserRestrictionsUtils 2957 .dumpRestrictions(pw, " ", mDevicePolicyGlobalUserRestrictions); 2958 } 2959 pw.println(); 2960 pw.println(" Guest restrictions:"); 2961 synchronized (mGuestRestrictions) { 2962 UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions); 2963 } 2964 synchronized (mUsersLock) { 2965 pw.println(); 2966 pw.println(" Device managed: " + mIsDeviceManaged); 2967 } 2968 // Dump some capabilities 2969 pw.println(); 2970 pw.println(" Max users: " + UserManager.getMaxSupportedUsers()); 2971 pw.println(" Supports switchable users: " + UserManager.supportsMultipleUsers()); 2972 pw.println(" All guests ephemeral: " + Resources.getSystem().getBoolean( 2973 com.android.internal.R.bool.config_guestUserEphemeral)); 2974 } 2975 } 2976 2977 final class MainHandler extends Handler { 2978 2979 @Override 2980 public void handleMessage(Message msg) { 2981 switch (msg.what) { 2982 case WRITE_USER_MSG: 2983 removeMessages(WRITE_USER_MSG, msg.obj); 2984 synchronized (mPackagesLock) { 2985 int userId = ((UserData) msg.obj).info.id; 2986 UserData userData = getUserDataNoChecks(userId); 2987 if (userData != null) { 2988 writeUserLP(userData); 2989 } 2990 } 2991 } 2992 } 2993 } 2994 2995 /** 2996 * @param userId 2997 * @return whether the user has been initialized yet 2998 */ 2999 boolean isInitialized(int userId) { 3000 return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0; 3001 } 3002 3003 private class LocalService extends UserManagerInternal { 3004 @Override 3005 public void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle localRestrictions, 3006 @Nullable Bundle globalRestrictions) { 3007 UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, localRestrictions, 3008 globalRestrictions); 3009 } 3010 3011 @Override 3012 public Bundle getBaseUserRestrictions(int userId) { 3013 synchronized (mRestrictionsLock) { 3014 return mBaseUserRestrictions.get(userId); 3015 } 3016 } 3017 3018 @Override 3019 public void setBaseUserRestrictionsByDpmsForMigration( 3020 int userId, Bundle baseRestrictions) { 3021 synchronized (mRestrictionsLock) { 3022 mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions)); 3023 invalidateEffectiveUserRestrictionsLR(userId); 3024 } 3025 3026 final UserData userData = getUserDataNoChecks(userId); 3027 synchronized (mPackagesLock) { 3028 if (userData != null) { 3029 writeUserLP(userData); 3030 } else { 3031 Slog.w(LOG_TAG, "UserInfo not found for " + userId); 3032 } 3033 } 3034 } 3035 3036 @Override 3037 public boolean getUserRestriction(int userId, String key) { 3038 return getUserRestrictions(userId).getBoolean(key); 3039 } 3040 3041 @Override 3042 public void addUserRestrictionsListener(UserRestrictionsListener listener) { 3043 synchronized (mUserRestrictionsListeners) { 3044 mUserRestrictionsListeners.add(listener); 3045 } 3046 } 3047 3048 @Override 3049 public void removeUserRestrictionsListener(UserRestrictionsListener listener) { 3050 synchronized (mUserRestrictionsListeners) { 3051 mUserRestrictionsListeners.remove(listener); 3052 } 3053 } 3054 3055 @Override 3056 public void setDeviceManaged(boolean isManaged) { 3057 synchronized (mUsersLock) { 3058 mIsDeviceManaged = isManaged; 3059 } 3060 } 3061 3062 @Override 3063 public void setUserManaged(int userId, boolean isManaged) { 3064 synchronized (mUsersLock) { 3065 mIsUserManaged.put(userId, isManaged); 3066 } 3067 } 3068 3069 @Override 3070 public void setUserIcon(int userId, Bitmap bitmap) { 3071 long ident = Binder.clearCallingIdentity(); 3072 try { 3073 synchronized (mPackagesLock) { 3074 UserData userData = getUserDataNoChecks(userId); 3075 if (userData == null || userData.info.partial) { 3076 Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId); 3077 return; 3078 } 3079 writeBitmapLP(userData.info, bitmap); 3080 writeUserLP(userData); 3081 } 3082 sendUserInfoChangedBroadcast(userId); 3083 } finally { 3084 Binder.restoreCallingIdentity(ident); 3085 } 3086 } 3087 3088 @Override 3089 public void setForceEphemeralUsers(boolean forceEphemeralUsers) { 3090 synchronized (mUsersLock) { 3091 mForceEphemeralUsers = forceEphemeralUsers; 3092 } 3093 } 3094 3095 @Override 3096 public void removeAllUsers() { 3097 if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) { 3098 // Remove the non-system users straight away. 3099 removeNonSystemUsers(); 3100 } else { 3101 // Switch to the system user first and then remove the other users. 3102 BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() { 3103 @Override 3104 public void onReceive(Context context, Intent intent) { 3105 int userId = 3106 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 3107 if (userId != UserHandle.USER_SYSTEM) { 3108 return; 3109 } 3110 mContext.unregisterReceiver(this); 3111 removeNonSystemUsers(); 3112 } 3113 }; 3114 IntentFilter userSwitchedFilter = new IntentFilter(); 3115 userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED); 3116 mContext.registerReceiver( 3117 userSwitchedReceiver, userSwitchedFilter, null, mHandler); 3118 3119 // Switch to the system user. 3120 ActivityManager am = 3121 (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 3122 am.switchUser(UserHandle.USER_SYSTEM); 3123 } 3124 } 3125 3126 @Override 3127 public void onEphemeralUserStop(int userId) { 3128 synchronized (mUsersLock) { 3129 UserInfo userInfo = getUserInfoLU(userId); 3130 if (userInfo != null && userInfo.isEphemeral()) { 3131 // Do not allow switching back to the ephemeral user again as the user is going 3132 // to be deleted. 3133 userInfo.flags |= UserInfo.FLAG_DISABLED; 3134 if (userInfo.isGuest()) { 3135 // Indicate that the guest will be deleted after it stops. 3136 userInfo.guestToRemove = true; 3137 } 3138 } 3139 } 3140 } 3141 3142 @Override 3143 public UserInfo createUserEvenWhenDisallowed(String name, int flags) { 3144 UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL); 3145 // Keep this in sync with UserManager.createUser 3146 if (user != null && !user.isAdmin()) { 3147 setUserRestriction(UserManager.DISALLOW_SMS, true, user.id); 3148 setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id); 3149 } 3150 return user; 3151 } 3152 } 3153 3154 /* Remove all the users except of the system one. */ 3155 private void removeNonSystemUsers() { 3156 ArrayList<UserInfo> usersToRemove = new ArrayList<>(); 3157 synchronized (mUsersLock) { 3158 final int userSize = mUsers.size(); 3159 for (int i = 0; i < userSize; i++) { 3160 UserInfo ui = mUsers.valueAt(i).info; 3161 if (ui.id != UserHandle.USER_SYSTEM) { 3162 usersToRemove.add(ui); 3163 } 3164 } 3165 } 3166 for (UserInfo ui: usersToRemove) { 3167 removeUser(ui.id); 3168 } 3169 } 3170 3171 private class Shell extends ShellCommand { 3172 @Override 3173 public int onCommand(String cmd) { 3174 return onShellCommand(this, cmd); 3175 } 3176 3177 @Override 3178 public void onHelp() { 3179 final PrintWriter pw = getOutPrintWriter(); 3180 pw.println("User manager (user) commands:"); 3181 pw.println(" help"); 3182 pw.println(" Print this help text."); 3183 pw.println(""); 3184 pw.println(" list"); 3185 pw.println(" Prints all users on the system."); 3186 } 3187 } 3188 3189 private static void debug(String message) { 3190 Log.d(LOG_TAG, message + 3191 (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, " ") : "")); 3192 } 3193} 3194