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