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