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