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