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