UserManagerService.java revision af6ec296ec200726ac86ff53efc64e221ed6f2f6
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 and ephemeral 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 || ui.isEphemeral()) && 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 private void broadcastProfileAvailabilityChanges(UserHandle profileHandle, 518 UserHandle parentHandle, Bundle extras) { 519 // Send intent to profile 520 Intent intent = new Intent(Intent.ACTION_AVAILABILITY_CHANGED); 521 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 522 intent.putExtras(extras); 523 mContext.sendBroadcastAsUser(intent, profileHandle); 524 525 // Send intent to parent 526 if (parentHandle != null) { 527 intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); 528 intent.putExtra(Intent.EXTRA_USER, profileHandle); 529 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); 530 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 531 intent.putExtras(extras); 532 mContext.sendBroadcastAsUser(intent, parentHandle); 533 } 534 } 535 536 @Override 537 public void setQuietModeEnabled(int userHandle, boolean enableQuietMode) { 538 checkManageUsersPermission("silence profile"); 539 boolean changed = false; 540 UserInfo profile, parent; 541 synchronized (mPackagesLock) { 542 synchronized (mUsersLock) { 543 profile = getUserInfoLU(userHandle); 544 parent = getProfileParentLU(userHandle); 545 546 } 547 if (profile == null || !profile.isManagedProfile()) { 548 throw new IllegalArgumentException("User " + userHandle + " is not a profile"); 549 } 550 if (profile.isQuietModeEnabled() != enableQuietMode) { 551 profile.flags ^= UserInfo.FLAG_QUIET_MODE; 552 writeUserLP(profile); 553 changed = true; 554 } 555 } 556 if (changed) { 557 Bundle extras = new Bundle(); 558 extras.putBoolean(Intent.EXTRA_QUIET_MODE, enableQuietMode); 559 broadcastProfileAvailabilityChanges(profile.getUserHandle(), 560 parent != null ? parent.getUserHandle() : null, extras); 561 } 562 } 563 564 @Override 565 public boolean isQuietModeEnabled(int userHandle) { 566 synchronized (mPackagesLock) { 567 UserInfo info; 568 synchronized (mUsersLock) { 569 info = getUserInfoLU(userHandle); 570 } 571 if (info == null || !info.isManagedProfile()) { 572 throw new IllegalArgumentException("User " + userHandle + " is not a profile"); 573 } 574 return info.isQuietModeEnabled(); 575 } 576 } 577 578 @Override 579 public void setUserEnabled(int userId) { 580 checkManageUsersPermission("enable user"); 581 synchronized (mPackagesLock) { 582 UserInfo info; 583 synchronized (mUsersLock) { 584 info = getUserInfoLU(userId); 585 } 586 if (info != null && !info.isEnabled()) { 587 info.flags ^= UserInfo.FLAG_DISABLED; 588 writeUserLP(info); 589 } 590 } 591 } 592 593 @Override 594 public UserInfo getUserInfo(int userId) { 595 checkManageUsersPermission("query user"); 596 synchronized (mUsersLock) { 597 return getUserInfoLU(userId); 598 } 599 } 600 601 @Override 602 public boolean isRestricted() { 603 synchronized (mUsersLock) { 604 return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted(); 605 } 606 } 607 608 @Override 609 public boolean canHaveRestrictedProfile(int userId) { 610 checkManageUsersPermission("canHaveRestrictedProfile"); 611 synchronized (mUsersLock) { 612 final UserInfo userInfo = getUserInfoLU(userId); 613 if (userInfo == null || !userInfo.canHaveProfile()) { 614 return false; 615 } 616 if (!userInfo.isAdmin()) { 617 return false; 618 } 619 // restricted profile can be created if there is no DO set and the admin user has no PO; 620 return !mIsDeviceManaged && !mIsUserManaged.get(userId); 621 } 622 } 623 624 /* 625 * Should be locked on mUsers before calling this. 626 */ 627 private UserInfo getUserInfoLU(int userId) { 628 UserInfo ui = mUsers.get(userId); 629 // If it is partial and not in the process of being removed, return as unknown user. 630 if (ui != null && ui.partial && !mRemovingUserIds.get(userId)) { 631 Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); 632 return null; 633 } 634 return ui; 635 } 636 637 /** 638 * Obtains {@link #mUsersLock} and return UserInfo from mUsers. 639 * <p>No permissions checking or any addition checks are made</p> 640 */ 641 private UserInfo getUserInfoNoChecks(int userId) { 642 synchronized (mUsersLock) { 643 return mUsers.get(userId); 644 } 645 } 646 647 /** Called by PackageManagerService */ 648 public boolean exists(int userId) { 649 return getUserInfoNoChecks(userId) != null; 650 } 651 652 @Override 653 public void setUserName(int userId, String name) { 654 checkManageUsersPermission("rename users"); 655 boolean changed = false; 656 synchronized (mPackagesLock) { 657 UserInfo info = getUserInfoNoChecks(userId); 658 if (info == null || info.partial) { 659 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId); 660 return; 661 } 662 if (name != null && !name.equals(info.name)) { 663 info.name = name; 664 writeUserLP(info); 665 changed = true; 666 } 667 } 668 if (changed) { 669 sendUserInfoChangedBroadcast(userId); 670 } 671 } 672 673 @Override 674 public void setUserIcon(int userId, Bitmap bitmap) { 675 checkManageUsersPermission("update users"); 676 long ident = Binder.clearCallingIdentity(); 677 try { 678 synchronized (mPackagesLock) { 679 UserInfo info = getUserInfoNoChecks(userId); 680 if (info == null || info.partial) { 681 Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId); 682 return; 683 } 684 writeBitmapLP(info, bitmap); 685 writeUserLP(info); 686 } 687 sendUserInfoChangedBroadcast(userId); 688 } finally { 689 Binder.restoreCallingIdentity(ident); 690 } 691 } 692 693 private void sendUserInfoChangedBroadcast(int userId) { 694 Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED); 695 changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 696 changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 697 mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL); 698 } 699 700 @Override 701 public ParcelFileDescriptor getUserIcon(int userId) { 702 String iconPath; 703 synchronized (mPackagesLock) { 704 UserInfo info = getUserInfoNoChecks(userId); 705 if (info == null || info.partial) { 706 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + userId); 707 return null; 708 } 709 int callingGroupId = getUserInfoNoChecks(UserHandle.getCallingUserId()).profileGroupId; 710 if (callingGroupId == UserInfo.NO_PROFILE_GROUP_ID 711 || callingGroupId != info.profileGroupId) { 712 checkManageUsersPermission("get the icon of a user who is not related"); 713 } 714 if (info.iconPath == null) { 715 return null; 716 } 717 iconPath = info.iconPath; 718 } 719 720 try { 721 return ParcelFileDescriptor.open( 722 new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY); 723 } catch (FileNotFoundException e) { 724 Log.e(LOG_TAG, "Couldn't find icon file", e); 725 } 726 return null; 727 } 728 729 public void makeInitialized(int userId) { 730 checkManageUsersPermission("makeInitialized"); 731 boolean scheduleWriteUser = false; 732 UserInfo info; 733 synchronized (mUsersLock) { 734 info = mUsers.get(userId); 735 if (info == null || info.partial) { 736 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId); 737 return; 738 } 739 if ((info.flags & UserInfo.FLAG_INITIALIZED) == 0) { 740 info.flags |= UserInfo.FLAG_INITIALIZED; 741 scheduleWriteUser = true; 742 } 743 } 744 if (scheduleWriteUser) { 745 scheduleWriteUser(info); 746 } 747 } 748 749 /** 750 * If default guest restrictions haven't been initialized yet, add the basic 751 * restrictions. 752 */ 753 private void initDefaultGuestRestrictions() { 754 synchronized (mGuestRestrictions) { 755 if (mGuestRestrictions.isEmpty()) { 756 mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); 757 mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true); 758 mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); 759 } 760 } 761 } 762 763 @Override 764 public Bundle getDefaultGuestRestrictions() { 765 checkManageUsersPermission("getDefaultGuestRestrictions"); 766 synchronized (mGuestRestrictions) { 767 return new Bundle(mGuestRestrictions); 768 } 769 } 770 771 @Override 772 public void setDefaultGuestRestrictions(Bundle restrictions) { 773 checkManageUsersPermission("setDefaultGuestRestrictions"); 774 synchronized (mGuestRestrictions) { 775 mGuestRestrictions.clear(); 776 mGuestRestrictions.putAll(restrictions); 777 } 778 synchronized (mPackagesLock) { 779 writeUserListLP(); 780 } 781 } 782 783 /** 784 * See {@link UserManagerInternal#setDevicePolicyUserRestrictions(int, Bundle, Bundle)} 785 */ 786 void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle local, 787 @Nullable Bundle global) { 788 Preconditions.checkNotNull(local); 789 boolean globalChanged = false; 790 boolean localChanged; 791 synchronized (mRestrictionsLock) { 792 if (global != null) { 793 // Update global. 794 globalChanged = !UserRestrictionsUtils.areEqual( 795 mDevicePolicyGlobalUserRestrictions, global); 796 if (globalChanged) { 797 mDevicePolicyGlobalUserRestrictions = global; 798 } 799 } 800 { 801 // Update local. 802 final Bundle prev = mDevicePolicyLocalUserRestrictions.get(userId); 803 localChanged = !UserRestrictionsUtils.areEqual(prev, local); 804 if (localChanged) { 805 mDevicePolicyLocalUserRestrictions.put(userId, local); 806 } 807 } 808 } 809 if (DBG) { 810 Log.d(LOG_TAG, "setDevicePolicyUserRestrictions: userId=" + userId 811 + " global=" + global + (globalChanged ? " (changed)" : "") 812 + " local=" + local + (localChanged ? " (changed)" : "") 813 ); 814 } 815 // Don't call them within the mRestrictionsLock. 816 synchronized (mPackagesLock) { 817 if (globalChanged) { 818 writeUserListLP(); 819 } 820 if (localChanged) { 821 writeUserLP(getUserInfoNoChecks(userId)); 822 } 823 } 824 825 synchronized (mRestrictionsLock) { 826 if (globalChanged) { 827 applyUserRestrictionsForAllUsersLR(); 828 } else if (localChanged) { 829 applyUserRestrictionsLR(userId); 830 } 831 } 832 } 833 834 @GuardedBy("mRestrictionsLock") 835 private Bundle computeEffectiveUserRestrictionsLR(int userId) { 836 final Bundle baseRestrictions = 837 UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId)); 838 final Bundle global = mDevicePolicyGlobalUserRestrictions; 839 final Bundle local = mDevicePolicyLocalUserRestrictions.get(userId); 840 841 if (UserRestrictionsUtils.isEmpty(global) && UserRestrictionsUtils.isEmpty(local)) { 842 // Common case first. 843 return baseRestrictions; 844 } 845 final Bundle effective = UserRestrictionsUtils.clone(baseRestrictions); 846 UserRestrictionsUtils.merge(effective, global); 847 UserRestrictionsUtils.merge(effective, local); 848 849 return effective; 850 } 851 852 @GuardedBy("mRestrictionsLock") 853 private void invalidateEffectiveUserRestrictionsLR(int userId) { 854 if (DBG) { 855 Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId); 856 } 857 mCachedEffectiveUserRestrictions.remove(userId); 858 } 859 860 private Bundle getEffectiveUserRestrictions(int userId) { 861 synchronized (mRestrictionsLock) { 862 Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId); 863 if (restrictions == null) { 864 restrictions = computeEffectiveUserRestrictionsLR(userId); 865 mCachedEffectiveUserRestrictions.put(userId, restrictions); 866 } 867 return restrictions; 868 } 869 } 870 871 /** @return a specific user restriction that's in effect currently. */ 872 @Override 873 public boolean hasUserRestriction(String restrictionKey, int userId) { 874 Bundle restrictions = getEffectiveUserRestrictions(userId); 875 return restrictions != null && restrictions.getBoolean(restrictionKey); 876 } 877 878 /** 879 * @return UserRestrictions that are in effect currently. This always returns a new 880 * {@link Bundle}. 881 */ 882 @Override 883 public Bundle getUserRestrictions(int userId) { 884 return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId)); 885 } 886 887 @Override 888 public boolean hasBaseUserRestriction(String restrictionKey, int userId) { 889 checkManageUsersPermission("hasBaseUserRestriction"); 890 synchronized (mRestrictionsLock) { 891 Bundle bundle = mBaseUserRestrictions.get(userId); 892 return (bundle != null && bundle.getBoolean(restrictionKey, false)); 893 } 894 } 895 896 @Override 897 public void setUserRestriction(String key, boolean value, int userId) { 898 checkManageUsersPermission("setUserRestriction"); 899 synchronized (mRestrictionsLock) { 900 // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create 901 // a copy. 902 final Bundle newRestrictions = UserRestrictionsUtils.clone( 903 mBaseUserRestrictions.get(userId)); 904 newRestrictions.putBoolean(key, value); 905 906 updateUserRestrictionsInternalLR(newRestrictions, userId); 907 } 908 } 909 910 /** 911 * Optionally updating user restrictions, calculate the effective user restrictions and also 912 * propagate to other services and system settings. 913 * 914 * @param newRestrictions User restrictions to set. 915 * If null, will not update user restrictions and only does the propagation. 916 * @param userId target user ID. 917 */ 918 @GuardedBy("mRestrictionsLock") 919 private void updateUserRestrictionsInternalLR( 920 @Nullable Bundle newRestrictions, int userId) { 921 922 final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull( 923 mAppliedUserRestrictions.get(userId)); 924 925 // Update base restrictions. 926 if (newRestrictions != null) { 927 // If newRestrictions == the current one, it's probably a bug. 928 final Bundle prevBaseRestrictions = mBaseUserRestrictions.get(userId); 929 930 Preconditions.checkState(prevBaseRestrictions != newRestrictions); 931 Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId) 932 != newRestrictions); 933 934 if (!UserRestrictionsUtils.areEqual(prevBaseRestrictions, newRestrictions)) { 935 mBaseUserRestrictions.put(userId, newRestrictions); 936 scheduleWriteUser(getUserInfoNoChecks(userId)); 937 } 938 } 939 940 final Bundle effective = computeEffectiveUserRestrictionsLR(userId); 941 942 mCachedEffectiveUserRestrictions.put(userId, effective); 943 944 // Apply the new restrictions. 945 if (DBG) { 946 debug("Applying user restrictions: userId=" + userId 947 + " new=" + effective + " prev=" + prevAppliedRestrictions); 948 } 949 950 if (mAppOpsService != null) { // We skip it until system-ready. 951 final long token = Binder.clearCallingIdentity(); 952 try { 953 mAppOpsService.setUserRestrictions(effective, userId); 954 } catch (RemoteException e) { 955 Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions"); 956 } finally { 957 Binder.restoreCallingIdentity(token); 958 } 959 } 960 961 propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions); 962 963 mAppliedUserRestrictions.put(userId, new Bundle(effective)); 964 } 965 966 private void propagateUserRestrictionsLR(final int userId, 967 Bundle newRestrictions, Bundle prevRestrictions) { 968 // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock 969 // actually, but we still need some kind of synchronization otherwise we might end up 970 // calling listeners out-of-order, thus "LR". 971 972 if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) { 973 return; 974 } 975 976 final Bundle newRestrictionsFinal = new Bundle(newRestrictions); 977 final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions); 978 979 mHandler.post(new Runnable() { 980 @Override 981 public void run() { 982 UserRestrictionsUtils.applyUserRestrictions( 983 mContext, userId, newRestrictionsFinal, prevRestrictionsFinal); 984 985 final UserRestrictionsListener[] listeners; 986 synchronized (mUserRestrictionsListeners) { 987 listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()]; 988 mUserRestrictionsListeners.toArray(listeners); 989 } 990 for (int i = 0; i < listeners.length; i++) { 991 listeners[i].onUserRestrictionsChanged(userId, 992 newRestrictionsFinal, prevRestrictionsFinal); 993 } 994 } 995 }); 996 } 997 998 // Package private for the inner class. 999 void applyUserRestrictionsLR(int userId) { 1000 updateUserRestrictionsInternalLR(null, userId); 1001 } 1002 1003 @GuardedBy("mRestrictionsLock") 1004 // Package private for the inner class. 1005 void applyUserRestrictionsForAllUsersLR() { 1006 if (DBG) { 1007 debug("applyUserRestrictionsForAllUsersLR"); 1008 } 1009 // First, invalidate all cached values. 1010 mCachedEffectiveUserRestrictions.clear(); 1011 1012 // We don't want to call into ActivityManagerNative while taking a lock, so we'll call 1013 // it on a handler. 1014 final Runnable r = new Runnable() { 1015 @Override 1016 public void run() { 1017 // Then get the list of running users. 1018 final int[] runningUsers; 1019 try { 1020 runningUsers = ActivityManagerNative.getDefault().getRunningUserIds(); 1021 } catch (RemoteException e) { 1022 Log.w(LOG_TAG, "Unable to access ActivityManagerNative"); 1023 return; 1024 } 1025 // Then re-calculate the effective restrictions and apply, only for running users. 1026 // It's okay if a new user has started after the getRunningUserIds() call, 1027 // because we'll do the same thing (re-calculate the restrictions and apply) 1028 // when we start a user. 1029 synchronized (mRestrictionsLock) { 1030 for (int i = 0; i < runningUsers.length; i++) { 1031 applyUserRestrictionsLR(runningUsers[i]); 1032 } 1033 } 1034 } 1035 }; 1036 mHandler.post(r); 1037 } 1038 1039 /** 1040 * Check if we've hit the limit of how many users can be created. 1041 */ 1042 private boolean isUserLimitReached() { 1043 int count; 1044 synchronized (mUsersLock) { 1045 count = getAliveUsersExcludingGuestsCountLU(); 1046 } 1047 return count >= UserManager.getMaxSupportedUsers(); 1048 } 1049 1050 @Override 1051 public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) { 1052 checkManageUsersPermission("check if more managed profiles can be added."); 1053 if (ActivityManager.isLowRamDeviceStatic()) { 1054 return false; 1055 } 1056 if (!mContext.getPackageManager().hasSystemFeature( 1057 PackageManager.FEATURE_MANAGED_USERS)) { 1058 return false; 1059 } 1060 // Limit number of managed profiles that can be created 1061 final int managedProfilesCount = getProfiles(userId, true).size() - 1; 1062 final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0; 1063 if (managedProfilesCount - profilesRemovedCount >= MAX_MANAGED_PROFILES) { 1064 return false; 1065 } 1066 synchronized(mUsersLock) { 1067 UserInfo userInfo = getUserInfoLU(userId); 1068 if (!userInfo.canHaveProfile()) { 1069 return false; 1070 } 1071 int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU() 1072 - profilesRemovedCount; 1073 // We allow creating a managed profile in the special case where there is only one user. 1074 return usersCountAfterRemoving == 1 1075 || usersCountAfterRemoving < UserManager.getMaxSupportedUsers(); 1076 } 1077 } 1078 1079 private int getAliveUsersExcludingGuestsCountLU() { 1080 int aliveUserCount = 0; 1081 final int totalUserCount = mUsers.size(); 1082 // Skip over users being removed 1083 for (int i = 0; i < totalUserCount; i++) { 1084 UserInfo user = mUsers.valueAt(i); 1085 if (!mRemovingUserIds.get(user.id) 1086 && !user.isGuest() && !user.partial) { 1087 aliveUserCount++; 1088 } 1089 } 1090 return aliveUserCount; 1091 } 1092 1093 /** 1094 * Enforces that only the system UID or root's UID or apps that have the 1095 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and 1096 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL} 1097 * permissions can make certain calls to the UserManager. 1098 * 1099 * @param message used as message if SecurityException is thrown 1100 * @throws SecurityException if the caller does not have enough privilege. 1101 */ 1102 private static final void checkManageUserAndAcrossUsersFullPermission(String message) { 1103 final int uid = Binder.getCallingUid(); 1104 if (uid != Process.SYSTEM_UID && uid != 0 1105 && ActivityManager.checkComponentPermission( 1106 Manifest.permission.MANAGE_USERS, 1107 uid, -1, true) != PackageManager.PERMISSION_GRANTED 1108 && ActivityManager.checkComponentPermission( 1109 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1110 uid, -1, true) != PackageManager.PERMISSION_GRANTED) { 1111 throw new SecurityException( 1112 "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " 1113 + message); 1114 } 1115 } 1116 1117 /** 1118 * Enforces that only the system UID or root's UID or apps that have the 1119 * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} 1120 * permission can make certain calls to the UserManager. 1121 * 1122 * @param message used as message if SecurityException is thrown 1123 * @throws SecurityException if the caller is not system or root 1124 */ 1125 private static final void checkManageUsersPermission(String message) { 1126 final int uid = Binder.getCallingUid(); 1127 if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID 1128 && ActivityManager.checkComponentPermission( 1129 android.Manifest.permission.MANAGE_USERS, 1130 uid, -1, true) != PackageManager.PERMISSION_GRANTED) { 1131 throw new SecurityException("You need MANAGE_USERS permission to: " + message); 1132 } 1133 } 1134 1135 /** 1136 * Enforces that only the system UID or root's UID (on any user) can make certain calls to the 1137 * UserManager. 1138 * 1139 * @param message used as message if SecurityException is thrown 1140 * @throws SecurityException if the caller is not system or root 1141 */ 1142 private static void checkSystemOrRoot(String message) { 1143 final int uid = Binder.getCallingUid(); 1144 if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) { 1145 throw new SecurityException("Only system may: " + message); 1146 } 1147 } 1148 1149 private void writeBitmapLP(UserInfo info, Bitmap bitmap) { 1150 try { 1151 File dir = new File(mUsersDir, Integer.toString(info.id)); 1152 File file = new File(dir, USER_PHOTO_FILENAME); 1153 File tmp = new File(dir, USER_PHOTO_FILENAME_TMP); 1154 if (!dir.exists()) { 1155 dir.mkdir(); 1156 FileUtils.setPermissions( 1157 dir.getPath(), 1158 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1159 -1, -1); 1160 } 1161 FileOutputStream os; 1162 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp)) 1163 && tmp.renameTo(file)) { 1164 info.iconPath = file.getAbsolutePath(); 1165 } 1166 try { 1167 os.close(); 1168 } catch (IOException ioe) { 1169 // What the ... ! 1170 } 1171 tmp.delete(); 1172 } catch (FileNotFoundException e) { 1173 Slog.w(LOG_TAG, "Error setting photo for user ", e); 1174 } 1175 } 1176 1177 /** 1178 * Returns an array of user ids. This array is cached here for quick access, so do not modify or 1179 * cache it elsewhere. 1180 * @return the array of user ids. 1181 */ 1182 public int[] getUserIds() { 1183 synchronized (mUsersLock) { 1184 return mUserIds; 1185 } 1186 } 1187 1188 private void readUserListLP() { 1189 if (!mUserListFile.exists()) { 1190 fallbackToSingleUserLP(); 1191 return; 1192 } 1193 FileInputStream fis = null; 1194 AtomicFile userListFile = new AtomicFile(mUserListFile); 1195 try { 1196 fis = userListFile.openRead(); 1197 XmlPullParser parser = Xml.newPullParser(); 1198 parser.setInput(fis, StandardCharsets.UTF_8.name()); 1199 int type; 1200 while ((type = parser.next()) != XmlPullParser.START_TAG 1201 && type != XmlPullParser.END_DOCUMENT) { 1202 ; 1203 } 1204 1205 if (type != XmlPullParser.START_TAG) { 1206 Slog.e(LOG_TAG, "Unable to read user list"); 1207 fallbackToSingleUserLP(); 1208 return; 1209 } 1210 1211 mNextSerialNumber = -1; 1212 if (parser.getName().equals(TAG_USERS)) { 1213 String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO); 1214 if (lastSerialNumber != null) { 1215 mNextSerialNumber = Integer.parseInt(lastSerialNumber); 1216 } 1217 String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION); 1218 if (versionNumber != null) { 1219 mUserVersion = Integer.parseInt(versionNumber); 1220 } 1221 } 1222 1223 final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle(); 1224 1225 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 1226 if (type == XmlPullParser.START_TAG) { 1227 final String name = parser.getName(); 1228 if (name.equals(TAG_USER)) { 1229 String id = parser.getAttributeValue(null, ATTR_ID); 1230 Pair<UserInfo, String> userPair = readUserLP(Integer.parseInt(id)); 1231 1232 if (userPair != null) { 1233 UserInfo user = userPair.first; 1234 String account = userPair.second; 1235 synchronized (mUsersLock) { 1236 mUsers.put(user.id, user); 1237 mUserAccounts.put(user.id, account); 1238 if (mNextSerialNumber < 0 || mNextSerialNumber <= user.id) { 1239 mNextSerialNumber = user.id + 1; 1240 } 1241 } 1242 } 1243 } else if (name.equals(TAG_GUEST_RESTRICTIONS)) { 1244 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1245 && type != XmlPullParser.END_TAG) { 1246 if (type == XmlPullParser.START_TAG) { 1247 if (parser.getName().equals(TAG_RESTRICTIONS)) { 1248 synchronized (mGuestRestrictions) { 1249 UserRestrictionsUtils 1250 .readRestrictions(parser, mGuestRestrictions); 1251 } 1252 } else if (parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS) 1253 ) { 1254 UserRestrictionsUtils.readRestrictions(parser, 1255 newDevicePolicyGlobalUserRestrictions); 1256 } 1257 break; 1258 } 1259 } 1260 } 1261 } 1262 } 1263 synchronized (mRestrictionsLock) { 1264 mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions; 1265 } 1266 updateUserIds(); 1267 upgradeIfNecessaryLP(); 1268 } catch (IOException | XmlPullParserException e) { 1269 fallbackToSingleUserLP(); 1270 } finally { 1271 IoUtils.closeQuietly(fis); 1272 } 1273 } 1274 1275 /** 1276 * Upgrade steps between versions, either for fixing bugs or changing the data format. 1277 */ 1278 private void upgradeIfNecessaryLP() { 1279 final int originalVersion = mUserVersion; 1280 int userVersion = mUserVersion; 1281 if (userVersion < 1) { 1282 // Assign a proper name for the owner, if not initialized correctly before 1283 UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM); 1284 if ("Primary".equals(user.name)) { 1285 user.name = mContext.getResources().getString(com.android.internal.R.string.owner_name); 1286 scheduleWriteUser(user); 1287 } 1288 userVersion = 1; 1289 } 1290 1291 if (userVersion < 2) { 1292 // Owner should be marked as initialized 1293 UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM); 1294 if ((user.flags & UserInfo.FLAG_INITIALIZED) == 0) { 1295 user.flags |= UserInfo.FLAG_INITIALIZED; 1296 scheduleWriteUser(user); 1297 } 1298 userVersion = 2; 1299 } 1300 1301 1302 if (userVersion < 4) { 1303 userVersion = 4; 1304 } 1305 1306 if (userVersion < 5) { 1307 initDefaultGuestRestrictions(); 1308 userVersion = 5; 1309 } 1310 1311 if (userVersion < 6) { 1312 final boolean splitSystemUser = UserManager.isSplitSystemUser(); 1313 synchronized (mUsersLock) { 1314 for (int i = 0; i < mUsers.size(); i++) { 1315 UserInfo user = mUsers.valueAt(i); 1316 // In non-split mode, only user 0 can have restricted profiles 1317 if (!splitSystemUser && user.isRestricted() 1318 && (user.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID)) { 1319 user.restrictedProfileParentId = UserHandle.USER_SYSTEM; 1320 scheduleWriteUser(user); 1321 } 1322 } 1323 } 1324 userVersion = 6; 1325 } 1326 1327 if (userVersion < USER_VERSION) { 1328 Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to " 1329 + USER_VERSION); 1330 } else { 1331 mUserVersion = userVersion; 1332 1333 if (originalVersion < mUserVersion) { 1334 writeUserListLP(); 1335 } 1336 } 1337 } 1338 1339 private void fallbackToSingleUserLP() { 1340 int flags = UserInfo.FLAG_INITIALIZED; 1341 // In split system user mode, the admin and primary flags are assigned to the first human 1342 // user. 1343 if (!UserManager.isSplitSystemUser()) { 1344 flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY; 1345 } 1346 // Create the system user 1347 UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, 1348 mContext.getResources().getString(com.android.internal.R.string.owner_name), null, 1349 flags); 1350 synchronized (mUsersLock) { 1351 mUsers.put(system.id, system); 1352 } 1353 mNextSerialNumber = MIN_USER_ID; 1354 mUserVersion = USER_VERSION; 1355 1356 Bundle restrictions = new Bundle(); 1357 synchronized (mRestrictionsLock) { 1358 mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions); 1359 } 1360 1361 updateUserIds(); 1362 initDefaultGuestRestrictions(); 1363 1364 writeUserListLP(); 1365 writeUserLP(system); 1366 } 1367 1368 private void scheduleWriteUser(UserInfo userInfo) { 1369 if (DBG) { 1370 debug("scheduleWriteUser"); 1371 } 1372 // No need to wrap it within a lock -- worst case, we'll just post the same message 1373 // twice. 1374 if (!mHandler.hasMessages(WRITE_USER_MSG, userInfo)) { 1375 Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userInfo); 1376 mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); 1377 } 1378 } 1379 1380 /* 1381 * Writes the user file in this format: 1382 * 1383 * <user flags="20039023" id="0"> 1384 * <name>Primary</name> 1385 * </user> 1386 */ 1387 private void writeUserLP(UserInfo userInfo) { 1388 if (DBG) { 1389 debug("writeUserLP " + userInfo); 1390 } 1391 FileOutputStream fos = null; 1392 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userInfo.id + XML_SUFFIX)); 1393 try { 1394 fos = userFile.startWrite(); 1395 final BufferedOutputStream bos = new BufferedOutputStream(fos); 1396 1397 // XmlSerializer serializer = XmlUtils.serializerInstance(); 1398 final XmlSerializer serializer = new FastXmlSerializer(); 1399 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 1400 serializer.startDocument(null, true); 1401 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1402 1403 serializer.startTag(null, TAG_USER); 1404 serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); 1405 serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber)); 1406 serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); 1407 serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime)); 1408 serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME, 1409 Long.toString(userInfo.lastLoggedInTime)); 1410 if (userInfo.iconPath != null) { 1411 serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); 1412 } 1413 if (userInfo.partial) { 1414 serializer.attribute(null, ATTR_PARTIAL, "true"); 1415 } 1416 if (userInfo.guestToRemove) { 1417 serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true"); 1418 } 1419 if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 1420 serializer.attribute(null, ATTR_PROFILE_GROUP_ID, 1421 Integer.toString(userInfo.profileGroupId)); 1422 } 1423 if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) { 1424 serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID, 1425 Integer.toString(userInfo.restrictedProfileParentId)); 1426 } 1427 serializer.startTag(null, TAG_NAME); 1428 serializer.text(userInfo.name); 1429 serializer.endTag(null, TAG_NAME); 1430 synchronized (mRestrictionsLock) { 1431 UserRestrictionsUtils.writeRestrictions(serializer, 1432 mBaseUserRestrictions.get(userInfo.id), TAG_RESTRICTIONS); 1433 UserRestrictionsUtils.writeRestrictions(serializer, 1434 mDevicePolicyLocalUserRestrictions.get(userInfo.id), 1435 TAG_DEVICE_POLICY_RESTRICTIONS); 1436 } 1437 // Update the account field if it is set. 1438 String account; 1439 synchronized (mUsersLock) { 1440 account = mUserAccounts.get(userInfo.id); 1441 } 1442 if (account != null) { 1443 serializer.startTag(null, TAG_ACCOUNT); 1444 serializer.text(account); 1445 serializer.endTag(null, TAG_ACCOUNT); 1446 } 1447 1448 serializer.endTag(null, TAG_USER); 1449 1450 serializer.endDocument(); 1451 userFile.finishWrite(fos); 1452 } catch (Exception ioe) { 1453 Slog.e(LOG_TAG, "Error writing user info " + userInfo.id + "\n" + ioe); 1454 userFile.failWrite(fos); 1455 } 1456 } 1457 1458 /* 1459 * Writes the user list file in this format: 1460 * 1461 * <users nextSerialNumber="3"> 1462 * <user id="0"></user> 1463 * <user id="2"></user> 1464 * </users> 1465 */ 1466 private void writeUserListLP() { 1467 if (DBG) { 1468 debug("writeUserList"); 1469 } 1470 FileOutputStream fos = null; 1471 AtomicFile userListFile = new AtomicFile(mUserListFile); 1472 try { 1473 fos = userListFile.startWrite(); 1474 final BufferedOutputStream bos = new BufferedOutputStream(fos); 1475 1476 // XmlSerializer serializer = XmlUtils.serializerInstance(); 1477 final XmlSerializer serializer = new FastXmlSerializer(); 1478 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 1479 serializer.startDocument(null, true); 1480 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1481 1482 serializer.startTag(null, TAG_USERS); 1483 serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber)); 1484 serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); 1485 1486 serializer.startTag(null, TAG_GUEST_RESTRICTIONS); 1487 synchronized (mGuestRestrictions) { 1488 UserRestrictionsUtils 1489 .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS); 1490 } 1491 serializer.endTag(null, TAG_GUEST_RESTRICTIONS); 1492 synchronized (mRestrictionsLock) { 1493 UserRestrictionsUtils.writeRestrictions(serializer, 1494 mDevicePolicyGlobalUserRestrictions, TAG_DEVICE_POLICY_RESTRICTIONS); 1495 } 1496 int[] userIdsToWrite; 1497 synchronized (mUsersLock) { 1498 userIdsToWrite = new int[mUsers.size()]; 1499 for (int i = 0; i < userIdsToWrite.length; i++) { 1500 UserInfo user = mUsers.valueAt(i); 1501 userIdsToWrite[i] = user.id; 1502 } 1503 } 1504 for (int id : userIdsToWrite) { 1505 serializer.startTag(null, TAG_USER); 1506 serializer.attribute(null, ATTR_ID, Integer.toString(id)); 1507 serializer.endTag(null, TAG_USER); 1508 } 1509 1510 serializer.endTag(null, TAG_USERS); 1511 1512 serializer.endDocument(); 1513 userListFile.finishWrite(fos); 1514 } catch (Exception e) { 1515 userListFile.failWrite(fos); 1516 Slog.e(LOG_TAG, "Error writing user list"); 1517 } 1518 } 1519 1520 private Pair<UserInfo, String> readUserLP(int id) { 1521 int flags = 0; 1522 int serialNumber = id; 1523 String name = null; 1524 String account = null; 1525 String iconPath = null; 1526 long creationTime = 0L; 1527 long lastLoggedInTime = 0L; 1528 int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; 1529 int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID; 1530 boolean partial = false; 1531 boolean guestToRemove = false; 1532 Bundle baseRestrictions = new Bundle(); 1533 Bundle localRestrictions = new Bundle(); 1534 1535 FileInputStream fis = null; 1536 try { 1537 AtomicFile userFile = 1538 new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX)); 1539 fis = userFile.openRead(); 1540 XmlPullParser parser = Xml.newPullParser(); 1541 parser.setInput(fis, StandardCharsets.UTF_8.name()); 1542 int type; 1543 while ((type = parser.next()) != XmlPullParser.START_TAG 1544 && type != XmlPullParser.END_DOCUMENT) { 1545 ; 1546 } 1547 1548 if (type != XmlPullParser.START_TAG) { 1549 Slog.e(LOG_TAG, "Unable to read user " + id); 1550 return null; 1551 } 1552 1553 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) { 1554 int storedId = readIntAttribute(parser, ATTR_ID, -1); 1555 if (storedId != id) { 1556 Slog.e(LOG_TAG, "User id does not match the file name"); 1557 return null; 1558 } 1559 serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id); 1560 flags = readIntAttribute(parser, ATTR_FLAGS, 0); 1561 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); 1562 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0); 1563 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0); 1564 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID, 1565 UserInfo.NO_PROFILE_GROUP_ID); 1566 restrictedProfileParentId = readIntAttribute(parser, 1567 ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID); 1568 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); 1569 if ("true".equals(valueString)) { 1570 partial = true; 1571 } 1572 valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE); 1573 if ("true".equals(valueString)) { 1574 guestToRemove = true; 1575 } 1576 1577 int outerDepth = parser.getDepth(); 1578 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1579 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1580 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1581 continue; 1582 } 1583 String tag = parser.getName(); 1584 if (TAG_NAME.equals(tag)) { 1585 type = parser.next(); 1586 if (type == XmlPullParser.TEXT) { 1587 name = parser.getText(); 1588 } 1589 } else if (TAG_RESTRICTIONS.equals(tag)) { 1590 UserRestrictionsUtils.readRestrictions(parser, baseRestrictions); 1591 } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) { 1592 UserRestrictionsUtils.readRestrictions(parser, localRestrictions); 1593 } else if (TAG_ACCOUNT.equals(tag)) { 1594 type = parser.next(); 1595 if (type == XmlPullParser.TEXT) { 1596 account = parser.getText(); 1597 } 1598 } 1599 } 1600 } 1601 1602 UserInfo userInfo = new UserInfo(id, name, iconPath, flags); 1603 userInfo.serialNumber = serialNumber; 1604 userInfo.creationTime = creationTime; 1605 userInfo.lastLoggedInTime = lastLoggedInTime; 1606 userInfo.partial = partial; 1607 userInfo.guestToRemove = guestToRemove; 1608 userInfo.profileGroupId = profileGroupId; 1609 userInfo.restrictedProfileParentId = restrictedProfileParentId; 1610 synchronized (mRestrictionsLock) { 1611 mBaseUserRestrictions.put(id, baseRestrictions); 1612 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions); 1613 } 1614 return new Pair<>(userInfo, account); 1615 1616 } catch (IOException ioe) { 1617 } catch (XmlPullParserException pe) { 1618 } finally { 1619 if (fis != null) { 1620 try { 1621 fis.close(); 1622 } catch (IOException e) { 1623 } 1624 } 1625 } 1626 return null; 1627 } 1628 1629 private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) { 1630 String valueString = parser.getAttributeValue(null, attr); 1631 if (valueString == null) return defaultValue; 1632 try { 1633 return Integer.parseInt(valueString); 1634 } catch (NumberFormatException nfe) { 1635 return defaultValue; 1636 } 1637 } 1638 1639 private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) { 1640 String valueString = parser.getAttributeValue(null, attr); 1641 if (valueString == null) return defaultValue; 1642 try { 1643 return Long.parseLong(valueString); 1644 } catch (NumberFormatException nfe) { 1645 return defaultValue; 1646 } 1647 } 1648 1649 private boolean isPackageInstalled(String pkg, int userId) { 1650 final ApplicationInfo info = mPm.getApplicationInfo(pkg, 1651 PackageManager.GET_UNINSTALLED_PACKAGES, 1652 userId); 1653 if (info == null || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 1654 return false; 1655 } 1656 return true; 1657 } 1658 1659 /** 1660 * Removes all the restrictions files (res_<packagename>) for a given user. 1661 * Does not do any permissions checking. 1662 */ 1663 private void cleanAppRestrictions(int userId) { 1664 synchronized (mPackagesLock) { 1665 File dir = Environment.getUserSystemDirectory(userId); 1666 String[] files = dir.list(); 1667 if (files == null) return; 1668 for (String fileName : files) { 1669 if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) { 1670 File resFile = new File(dir, fileName); 1671 if (resFile.exists()) { 1672 resFile.delete(); 1673 } 1674 } 1675 } 1676 } 1677 } 1678 1679 /** 1680 * Removes the app restrictions file for a specific package and user id, if it exists. 1681 */ 1682 private void cleanAppRestrictionsForPackage(String pkg, int userId) { 1683 synchronized (mPackagesLock) { 1684 File dir = Environment.getUserSystemDirectory(userId); 1685 File resFile = new File(dir, packageToRestrictionsFileName(pkg)); 1686 if (resFile.exists()) { 1687 resFile.delete(); 1688 } 1689 } 1690 } 1691 1692 @Override 1693 public UserInfo createProfileForUser(String name, int flags, int userId) { 1694 checkManageUsersPermission("Only the system can create users"); 1695 return createUserInternal(name, flags, userId); 1696 } 1697 1698 @Override 1699 public UserInfo createUser(String name, int flags) { 1700 checkManageUsersPermission("Only the system can create users"); 1701 return createUserInternal(name, flags, UserHandle.USER_NULL); 1702 } 1703 1704 private UserInfo createUserInternal(String name, int flags, int parentId) { 1705 if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) { 1706 Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled."); 1707 return null; 1708 } 1709 if (ActivityManager.isLowRamDeviceStatic()) { 1710 return null; 1711 } 1712 final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0; 1713 final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0; 1714 final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0; 1715 final long ident = Binder.clearCallingIdentity(); 1716 UserInfo userInfo; 1717 final int userId; 1718 try { 1719 synchronized (mPackagesLock) { 1720 UserInfo parent = null; 1721 if (parentId != UserHandle.USER_NULL) { 1722 synchronized (mUsersLock) { 1723 parent = getUserInfoLU(parentId); 1724 } 1725 if (parent == null) return null; 1726 } 1727 if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) { 1728 Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId); 1729 return null; 1730 } 1731 if (!isGuest && !isManagedProfile && isUserLimitReached()) { 1732 // If we're not adding a guest user or a managed profile and the limit has 1733 // been reached, cannot add a user. 1734 return null; 1735 } 1736 // If we're adding a guest and there already exists one, bail. 1737 if (isGuest && findCurrentGuestUser() != null) { 1738 return null; 1739 } 1740 // In legacy mode, restricted profile's parent can only be the owner user 1741 if (isRestricted && !UserManager.isSplitSystemUser() 1742 && (parentId != UserHandle.USER_SYSTEM)) { 1743 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner"); 1744 return null; 1745 } 1746 if (isRestricted && UserManager.isSplitSystemUser()) { 1747 if (parent == null) { 1748 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be " 1749 + "specified"); 1750 return null; 1751 } 1752 if (!parent.canHaveProfile()) { 1753 Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be " 1754 + "created for the specified parent user id " + parentId); 1755 return null; 1756 } 1757 } 1758 // In split system user mode, we assign the first human user the primary flag. 1759 // And if there is no device owner, we also assign the admin flag to primary user. 1760 if (UserManager.isSplitSystemUser() 1761 && !isGuest && !isManagedProfile && getPrimaryUser() == null) { 1762 flags |= UserInfo.FLAG_PRIMARY; 1763 synchronized (mUsersLock) { 1764 if (!mIsDeviceManaged) { 1765 flags |= UserInfo.FLAG_ADMIN; 1766 } 1767 } 1768 } 1769 1770 if (parent != null && parent.isEphemeral()) { 1771 flags |= UserInfo.FLAG_EPHEMERAL; 1772 } 1773 userId = getNextAvailableId(); 1774 userInfo = new UserInfo(userId, name, null, flags); 1775 userInfo.serialNumber = mNextSerialNumber++; 1776 long now = System.currentTimeMillis(); 1777 userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0; 1778 userInfo.partial = true; 1779 Environment.getUserSystemDirectory(userInfo.id).mkdirs(); 1780 synchronized (mUsersLock) { 1781 mUsers.put(userId, userInfo); 1782 } 1783 writeUserListLP(); 1784 if (parent != null) { 1785 if (isManagedProfile) { 1786 if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { 1787 parent.profileGroupId = parent.id; 1788 writeUserLP(parent); 1789 } 1790 userInfo.profileGroupId = parent.profileGroupId; 1791 } else if (isRestricted) { 1792 if (parent.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) { 1793 parent.restrictedProfileParentId = parent.id; 1794 writeUserLP(parent); 1795 } 1796 userInfo.restrictedProfileParentId = parent.restrictedProfileParentId; 1797 } 1798 } 1799 } 1800 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1801 storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral()); 1802 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 1803 final String volumeUuid = vol.getFsUuid(); 1804 try { 1805 final File userDir = Environment.getDataUserDirectory(volumeUuid, userId); 1806 storage.prepareUserStorage( 1807 volumeUuid, userId, userInfo.serialNumber, userInfo.isEphemeral()); 1808 enforceSerialNumber(userDir, userInfo.serialNumber); 1809 } catch (IOException e) { 1810 Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e); 1811 } 1812 } 1813 mPm.createNewUser(userId); 1814 userInfo.partial = false; 1815 synchronized (mPackagesLock) { 1816 writeUserLP(userInfo); 1817 } 1818 updateUserIds(); 1819 Bundle restrictions = new Bundle(); 1820 if (isGuest) { 1821 synchronized (mGuestRestrictions) { 1822 restrictions.putAll(mGuestRestrictions); 1823 } 1824 } 1825 synchronized (mRestrictionsLock) { 1826 mBaseUserRestrictions.append(userId, restrictions); 1827 } 1828 mPm.newUserCreated(userId); 1829 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED); 1830 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 1831 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 1832 android.Manifest.permission.MANAGE_USERS); 1833 } finally { 1834 Binder.restoreCallingIdentity(ident); 1835 } 1836 return userInfo; 1837 } 1838 1839 /** 1840 * @hide 1841 */ 1842 public UserInfo createRestrictedProfile(String name, int parentUserId) { 1843 checkManageUsersPermission("setupRestrictedProfile"); 1844 final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId); 1845 if (user == null) { 1846 return null; 1847 } 1848 setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id); 1849 // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise 1850 // the putIntForUser() will fail. 1851 android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(), 1852 android.provider.Settings.Secure.LOCATION_MODE, 1853 android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id); 1854 setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id); 1855 return user; 1856 } 1857 1858 /** 1859 * Find the current guest user. If the Guest user is partial, 1860 * then do not include it in the results as it is about to die. 1861 */ 1862 private UserInfo findCurrentGuestUser() { 1863 synchronized (mUsersLock) { 1864 final int size = mUsers.size(); 1865 for (int i = 0; i < size; i++) { 1866 final UserInfo user = mUsers.valueAt(i); 1867 if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) { 1868 return user; 1869 } 1870 } 1871 } 1872 return null; 1873 } 1874 1875 /** 1876 * Mark this guest user for deletion to allow us to create another guest 1877 * and switch to that user before actually removing this guest. 1878 * @param userHandle the userid of the current guest 1879 * @return whether the user could be marked for deletion 1880 */ 1881 public boolean markGuestForDeletion(int userHandle) { 1882 checkManageUsersPermission("Only the system can remove users"); 1883 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 1884 UserManager.DISALLOW_REMOVE_USER, false)) { 1885 Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 1886 return false; 1887 } 1888 1889 long ident = Binder.clearCallingIdentity(); 1890 try { 1891 final UserInfo user; 1892 synchronized (mPackagesLock) { 1893 synchronized (mUsersLock) { 1894 user = mUsers.get(userHandle); 1895 if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) { 1896 return false; 1897 } 1898 } 1899 if (!user.isGuest()) { 1900 return false; 1901 } 1902 // We set this to a guest user that is to be removed. This is a temporary state 1903 // where we are allowed to add new Guest users, even if this one is still not 1904 // removed. This user will still show up in getUserInfo() calls. 1905 // If we don't get around to removing this Guest user, it will be purged on next 1906 // startup. 1907 user.guestToRemove = true; 1908 // Mark it as disabled, so that it isn't returned any more when 1909 // profiles are queried. 1910 user.flags |= UserInfo.FLAG_DISABLED; 1911 writeUserLP(user); 1912 } 1913 } finally { 1914 Binder.restoreCallingIdentity(ident); 1915 } 1916 return true; 1917 } 1918 1919 /** 1920 * Removes a user and all data directories created for that user. This method should be called 1921 * after the user's processes have been terminated. 1922 * @param userHandle the user's id 1923 */ 1924 public boolean removeUser(int userHandle) { 1925 checkManageUsersPermission("Only the system can remove users"); 1926 if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean( 1927 UserManager.DISALLOW_REMOVE_USER, false)) { 1928 Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled."); 1929 return false; 1930 } 1931 1932 long ident = Binder.clearCallingIdentity(); 1933 try { 1934 final UserInfo user; 1935 int currentUser = ActivityManager.getCurrentUser(); 1936 if (currentUser == userHandle) { 1937 Log.w(LOG_TAG, "Current user cannot be removed"); 1938 return false; 1939 } 1940 synchronized (mPackagesLock) { 1941 synchronized (mUsersLock) { 1942 user = mUsers.get(userHandle); 1943 if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) { 1944 return false; 1945 } 1946 1947 // We remember deleted user IDs to prevent them from being 1948 // reused during the current boot; they can still be reused 1949 // after a reboot. 1950 mRemovingUserIds.put(userHandle, true); 1951 } 1952 1953 try { 1954 mAppOpsService.removeUser(userHandle); 1955 } catch (RemoteException e) { 1956 Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e); 1957 } 1958 // Set this to a partially created user, so that the user will be purged 1959 // on next startup, in case the runtime stops now before stopping and 1960 // removing the user completely. 1961 user.partial = true; 1962 // Mark it as disabled, so that it isn't returned any more when 1963 // profiles are queried. 1964 user.flags |= UserInfo.FLAG_DISABLED; 1965 writeUserLP(user); 1966 } 1967 1968 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 1969 && user.isManagedProfile()) { 1970 // Send broadcast to notify system that the user removed was a 1971 // managed user. 1972 sendProfileRemovedBroadcast(user.profileGroupId, user.id); 1973 } 1974 1975 if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle); 1976 int res; 1977 try { 1978 res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true, 1979 new IStopUserCallback.Stub() { 1980 @Override 1981 public void userStopped(int userId) { 1982 finishRemoveUser(userId); 1983 } 1984 @Override 1985 public void userStopAborted(int userId) { 1986 } 1987 }); 1988 } catch (RemoteException e) { 1989 return false; 1990 } 1991 return res == ActivityManager.USER_OP_SUCCESS; 1992 } finally { 1993 Binder.restoreCallingIdentity(ident); 1994 } 1995 } 1996 1997 void finishRemoveUser(final int userHandle) { 1998 if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle); 1999 // Let other services shutdown any activity and clean up their state before completely 2000 // wiping the user's system directory and removing from the user list 2001 long ident = Binder.clearCallingIdentity(); 2002 try { 2003 Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED); 2004 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2005 mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL, 2006 android.Manifest.permission.MANAGE_USERS, 2007 2008 new BroadcastReceiver() { 2009 @Override 2010 public void onReceive(Context context, Intent intent) { 2011 if (DBG) { 2012 Slog.i(LOG_TAG, 2013 "USER_REMOVED broadcast sent, cleaning up user data " 2014 + userHandle); 2015 } 2016 new Thread() { 2017 public void run() { 2018 // Clean up any ActivityManager state 2019 LocalServices.getService(ActivityManagerInternal.class) 2020 .onUserRemoved(userHandle); 2021 removeUserState(userHandle); 2022 } 2023 }.start(); 2024 } 2025 }, 2026 2027 null, Activity.RESULT_OK, null, null); 2028 } finally { 2029 Binder.restoreCallingIdentity(ident); 2030 } 2031 } 2032 2033 private void removeUserState(final int userHandle) { 2034 mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle); 2035 // Cleanup package manager settings 2036 mPm.cleanUpUser(this, userHandle); 2037 2038 // Remove this user from the list 2039 synchronized (mUsersLock) { 2040 mUsers.remove(userHandle); 2041 mUserAccounts.delete(userHandle); 2042 mIsUserManaged.delete(userHandle); 2043 } 2044 synchronized (mRestrictionsLock) { 2045 mBaseUserRestrictions.remove(userHandle); 2046 mAppliedUserRestrictions.remove(userHandle); 2047 mCachedEffectiveUserRestrictions.remove(userHandle); 2048 mDevicePolicyLocalUserRestrictions.remove(userHandle); 2049 } 2050 // Remove user file 2051 AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX)); 2052 userFile.delete(); 2053 // Update the user list 2054 synchronized (mPackagesLock) { 2055 writeUserListLP(); 2056 } 2057 updateUserIds(); 2058 removeDirectoryRecursive(Environment.getUserSystemDirectory(userHandle)); 2059 } 2060 2061 private void removeDirectoryRecursive(File parent) { 2062 if (parent.isDirectory()) { 2063 String[] files = parent.list(); 2064 for (String filename : files) { 2065 File child = new File(parent, filename); 2066 removeDirectoryRecursive(child); 2067 } 2068 } 2069 parent.delete(); 2070 } 2071 2072 private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { 2073 Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); 2074 managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | 2075 Intent.FLAG_RECEIVER_FOREGROUND); 2076 managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); 2077 managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); 2078 mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null); 2079 } 2080 2081 @Override 2082 public Bundle getApplicationRestrictions(String packageName) { 2083 return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId()); 2084 } 2085 2086 @Override 2087 public Bundle getApplicationRestrictionsForUser(String packageName, int userId) { 2088 if (UserHandle.getCallingUserId() != userId 2089 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { 2090 checkSystemOrRoot("get application restrictions for other users/apps"); 2091 } 2092 synchronized (mPackagesLock) { 2093 // Read the restrictions from XML 2094 return readApplicationRestrictionsLP(packageName, userId); 2095 } 2096 } 2097 2098 @Override 2099 public void setApplicationRestrictions(String packageName, Bundle restrictions, 2100 int userId) { 2101 checkSystemOrRoot("set application restrictions"); 2102 synchronized (mPackagesLock) { 2103 if (restrictions == null || restrictions.isEmpty()) { 2104 cleanAppRestrictionsForPackage(packageName, userId); 2105 } else { 2106 // Write the restrictions to XML 2107 writeApplicationRestrictionsLP(packageName, restrictions, userId); 2108 } 2109 } 2110 2111 if (isPackageInstalled(packageName, userId)) { 2112 // Notify package of changes via an intent - only sent to explicitly registered receivers. 2113 Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); 2114 changeIntent.setPackage(packageName); 2115 changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2116 mContext.sendBroadcastAsUser(changeIntent, new UserHandle(userId)); 2117 } 2118 } 2119 2120 private void unhideAllInstalledAppsForUser(final int userHandle) { 2121 mHandler.post(new Runnable() { 2122 @Override 2123 public void run() { 2124 List<ApplicationInfo> apps = 2125 mPm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES, 2126 userHandle).getList(); 2127 final long ident = Binder.clearCallingIdentity(); 2128 try { 2129 for (ApplicationInfo appInfo : apps) { 2130 if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0 2131 && (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HIDDEN) 2132 != 0) { 2133 mPm.setApplicationHiddenSettingAsUser(appInfo.packageName, false, 2134 userHandle); 2135 } 2136 } 2137 } finally { 2138 Binder.restoreCallingIdentity(ident); 2139 } 2140 } 2141 }); 2142 } 2143 private int getUidForPackage(String packageName) { 2144 long ident = Binder.clearCallingIdentity(); 2145 try { 2146 return mContext.getPackageManager().getApplicationInfo(packageName, 2147 PackageManager.GET_UNINSTALLED_PACKAGES).uid; 2148 } catch (NameNotFoundException nnfe) { 2149 return -1; 2150 } finally { 2151 Binder.restoreCallingIdentity(ident); 2152 } 2153 } 2154 2155 private Bundle readApplicationRestrictionsLP(String packageName, int userId) { 2156 AtomicFile restrictionsFile = 2157 new AtomicFile(new File(Environment.getUserSystemDirectory(userId), 2158 packageToRestrictionsFileName(packageName))); 2159 return readApplicationRestrictionsLP(restrictionsFile); 2160 } 2161 2162 @VisibleForTesting 2163 static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) { 2164 final Bundle restrictions = new Bundle(); 2165 final ArrayList<String> values = new ArrayList<>(); 2166 if (!restrictionsFile.getBaseFile().exists()) { 2167 return restrictions; 2168 } 2169 2170 FileInputStream fis = null; 2171 try { 2172 fis = restrictionsFile.openRead(); 2173 XmlPullParser parser = Xml.newPullParser(); 2174 parser.setInput(fis, StandardCharsets.UTF_8.name()); 2175 XmlUtils.nextElement(parser); 2176 if (parser.getEventType() != XmlPullParser.START_TAG) { 2177 Slog.e(LOG_TAG, "Unable to read restrictions file " 2178 + restrictionsFile.getBaseFile()); 2179 return restrictions; 2180 } 2181 while (parser.next() != XmlPullParser.END_DOCUMENT) { 2182 readEntry(restrictions, values, parser); 2183 } 2184 } catch (IOException|XmlPullParserException e) { 2185 Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e); 2186 } finally { 2187 IoUtils.closeQuietly(fis); 2188 } 2189 return restrictions; 2190 } 2191 2192 private static void readEntry(Bundle restrictions, ArrayList<String> values, 2193 XmlPullParser parser) throws XmlPullParserException, IOException { 2194 int type = parser.getEventType(); 2195 if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) { 2196 String key = parser.getAttributeValue(null, ATTR_KEY); 2197 String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE); 2198 String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE); 2199 if (multiple != null) { 2200 values.clear(); 2201 int count = Integer.parseInt(multiple); 2202 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) { 2203 if (type == XmlPullParser.START_TAG 2204 && parser.getName().equals(TAG_VALUE)) { 2205 values.add(parser.nextText().trim()); 2206 count--; 2207 } 2208 } 2209 String [] valueStrings = new String[values.size()]; 2210 values.toArray(valueStrings); 2211 restrictions.putStringArray(key, valueStrings); 2212 } else if (ATTR_TYPE_BUNDLE.equals(valType)) { 2213 restrictions.putBundle(key, readBundleEntry(parser, values)); 2214 } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) { 2215 final int outerDepth = parser.getDepth(); 2216 ArrayList<Bundle> bundleList = new ArrayList<>(); 2217 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 2218 Bundle childBundle = readBundleEntry(parser, values); 2219 bundleList.add(childBundle); 2220 } 2221 restrictions.putParcelableArray(key, 2222 bundleList.toArray(new Bundle[bundleList.size()])); 2223 } else { 2224 String value = parser.nextText().trim(); 2225 if (ATTR_TYPE_BOOLEAN.equals(valType)) { 2226 restrictions.putBoolean(key, Boolean.parseBoolean(value)); 2227 } else if (ATTR_TYPE_INTEGER.equals(valType)) { 2228 restrictions.putInt(key, Integer.parseInt(value)); 2229 } else { 2230 restrictions.putString(key, value); 2231 } 2232 } 2233 } 2234 } 2235 2236 private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values) 2237 throws IOException, XmlPullParserException { 2238 Bundle childBundle = new Bundle(); 2239 final int outerDepth = parser.getDepth(); 2240 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 2241 readEntry(childBundle, values, parser); 2242 } 2243 return childBundle; 2244 } 2245 2246 private void writeApplicationRestrictionsLP(String packageName, 2247 Bundle restrictions, int userId) { 2248 AtomicFile restrictionsFile = new AtomicFile( 2249 new File(Environment.getUserSystemDirectory(userId), 2250 packageToRestrictionsFileName(packageName))); 2251 writeApplicationRestrictionsLP(restrictions, restrictionsFile); 2252 } 2253 2254 @VisibleForTesting 2255 static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) { 2256 FileOutputStream fos = null; 2257 try { 2258 fos = restrictionsFile.startWrite(); 2259 final BufferedOutputStream bos = new BufferedOutputStream(fos); 2260 2261 final XmlSerializer serializer = new FastXmlSerializer(); 2262 serializer.setOutput(bos, StandardCharsets.UTF_8.name()); 2263 serializer.startDocument(null, true); 2264 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 2265 2266 serializer.startTag(null, TAG_RESTRICTIONS); 2267 writeBundle(restrictions, serializer); 2268 serializer.endTag(null, TAG_RESTRICTIONS); 2269 2270 serializer.endDocument(); 2271 restrictionsFile.finishWrite(fos); 2272 } catch (Exception e) { 2273 restrictionsFile.failWrite(fos); 2274 Slog.e(LOG_TAG, "Error writing application restrictions list", e); 2275 } 2276 } 2277 2278 private static void writeBundle(Bundle restrictions, XmlSerializer serializer) 2279 throws IOException { 2280 for (String key : restrictions.keySet()) { 2281 Object value = restrictions.get(key); 2282 serializer.startTag(null, TAG_ENTRY); 2283 serializer.attribute(null, ATTR_KEY, key); 2284 2285 if (value instanceof Boolean) { 2286 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN); 2287 serializer.text(value.toString()); 2288 } else if (value instanceof Integer) { 2289 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER); 2290 serializer.text(value.toString()); 2291 } else if (value == null || value instanceof String) { 2292 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING); 2293 serializer.text(value != null ? (String) value : ""); 2294 } else if (value instanceof Bundle) { 2295 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 2296 writeBundle((Bundle) value, serializer); 2297 } else if (value instanceof Parcelable[]) { 2298 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY); 2299 Parcelable[] array = (Parcelable[]) value; 2300 for (Parcelable parcelable : array) { 2301 if (!(parcelable instanceof Bundle)) { 2302 throw new IllegalArgumentException("bundle-array can only hold Bundles"); 2303 } 2304 serializer.startTag(null, TAG_ENTRY); 2305 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE); 2306 writeBundle((Bundle) parcelable, serializer); 2307 serializer.endTag(null, TAG_ENTRY); 2308 } 2309 } else { 2310 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY); 2311 String[] values = (String[]) value; 2312 serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length)); 2313 for (String choice : values) { 2314 serializer.startTag(null, TAG_VALUE); 2315 serializer.text(choice != null ? choice : ""); 2316 serializer.endTag(null, TAG_VALUE); 2317 } 2318 } 2319 serializer.endTag(null, TAG_ENTRY); 2320 } 2321 } 2322 2323 @Override 2324 public int getUserSerialNumber(int userHandle) { 2325 synchronized (mUsersLock) { 2326 if (!exists(userHandle)) return -1; 2327 return getUserInfoLU(userHandle).serialNumber; 2328 } 2329 } 2330 2331 @Override 2332 public int getUserHandle(int userSerialNumber) { 2333 synchronized (mUsersLock) { 2334 for (int userId : mUserIds) { 2335 UserInfo info = getUserInfoLU(userId); 2336 if (info != null && info.serialNumber == userSerialNumber) return userId; 2337 } 2338 // Not found 2339 return -1; 2340 } 2341 } 2342 2343 @Override 2344 public long getUserCreationTime(int userHandle) { 2345 int callingUserId = UserHandle.getCallingUserId(); 2346 UserInfo userInfo = null; 2347 synchronized (mUsersLock) { 2348 if (callingUserId == userHandle) { 2349 userInfo = getUserInfoLU(userHandle); 2350 } else { 2351 UserInfo parent = getProfileParentLU(userHandle); 2352 if (parent != null && parent.id == callingUserId) { 2353 userInfo = getUserInfoLU(userHandle); 2354 } 2355 } 2356 } 2357 if (userInfo == null) { 2358 throw new SecurityException("userHandle can only be the calling user or a managed " 2359 + "profile associated with this user"); 2360 } 2361 return userInfo.creationTime; 2362 } 2363 2364 /** 2365 * Caches the list of user ids in an array, adjusting the array size when necessary. 2366 */ 2367 private void updateUserIds() { 2368 int num = 0; 2369 synchronized (mUsersLock) { 2370 final int userSize = mUsers.size(); 2371 for (int i = 0; i < userSize; i++) { 2372 if (!mUsers.valueAt(i).partial) { 2373 num++; 2374 } 2375 } 2376 final int[] newUsers = new int[num]; 2377 int n = 0; 2378 for (int i = 0; i < userSize; i++) { 2379 if (!mUsers.valueAt(i).partial) { 2380 newUsers[n++] = mUsers.keyAt(i); 2381 } 2382 } 2383 mUserIds = newUsers; 2384 } 2385 } 2386 2387 /** 2388 * Called right before a user starts. This will not be called for the system user. 2389 */ 2390 public void onBeforeStartUser(int userId) { 2391 synchronized (mRestrictionsLock) { 2392 applyUserRestrictionsLR(userId); 2393 } 2394 } 2395 2396 /** 2397 * Make a note of the last started time of a user and do some cleanup. 2398 * @param userId the user that was just foregrounded 2399 */ 2400 public void onUserForeground(int userId) { 2401 UserInfo user = getUserInfoNoChecks(userId); 2402 if (user == null || user.partial) { 2403 Slog.w(LOG_TAG, "userForeground: unknown user #" + userId); 2404 return; 2405 } 2406 long now = System.currentTimeMillis(); 2407 if (now > EPOCH_PLUS_30_YEARS) { 2408 user.lastLoggedInTime = now; 2409 scheduleWriteUser(user); 2410 } 2411 } 2412 2413 /** 2414 * Returns the next available user id, filling in any holes in the ids. 2415 * TODO: May not be a good idea to recycle ids, in case it results in confusion 2416 * for data and battery stats collection, or unexpected cross-talk. 2417 */ 2418 private int getNextAvailableId() { 2419 synchronized (mUsersLock) { 2420 int i = MIN_USER_ID; 2421 while (i < MAX_USER_ID) { 2422 if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) { 2423 return i; 2424 } 2425 i++; 2426 } 2427 } 2428 throw new IllegalStateException("No user id available!"); 2429 } 2430 2431 private String packageToRestrictionsFileName(String packageName) { 2432 return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX; 2433 } 2434 2435 /** 2436 * Enforce that serial number stored in user directory inode matches the 2437 * given expected value. Gracefully sets the serial number if currently 2438 * undefined. 2439 * 2440 * @throws IOException when problem extracting serial number, or serial 2441 * number is mismatched. 2442 */ 2443 public static void enforceSerialNumber(File file, int serialNumber) throws IOException { 2444 final int foundSerial = getSerialNumber(file); 2445 Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial); 2446 2447 if (foundSerial == -1) { 2448 Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid"); 2449 try { 2450 setSerialNumber(file, serialNumber); 2451 } catch (IOException e) { 2452 Slog.w(LOG_TAG, "Failed to set serial number on " + file, e); 2453 } 2454 2455 } else if (foundSerial != serialNumber) { 2456 throw new IOException("Found serial number " + foundSerial 2457 + " doesn't match expected " + serialNumber); 2458 } 2459 } 2460 2461 /** 2462 * Set serial number stored in user directory inode. 2463 * 2464 * @throws IOException if serial number was already set 2465 */ 2466 private static void setSerialNumber(File file, int serialNumber) 2467 throws IOException { 2468 try { 2469 final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8); 2470 Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE); 2471 } catch (ErrnoException e) { 2472 throw e.rethrowAsIOException(); 2473 } 2474 } 2475 2476 /** 2477 * Return serial number stored in user directory inode. 2478 * 2479 * @return parsed serial number, or -1 if not set 2480 */ 2481 private static int getSerialNumber(File file) throws IOException { 2482 try { 2483 final byte[] buf = new byte[256]; 2484 final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL, buf); 2485 final String serial = new String(buf, 0, len); 2486 try { 2487 return Integer.parseInt(serial); 2488 } catch (NumberFormatException e) { 2489 throw new IOException("Bad serial number: " + serial); 2490 } 2491 } catch (ErrnoException e) { 2492 if (e.errno == OsConstants.ENODATA) { 2493 return -1; 2494 } else { 2495 throw e.rethrowAsIOException(); 2496 } 2497 } 2498 } 2499 2500 @Override 2501 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2502 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 2503 (new Shell()).exec(this, in, out, err, args, resultReceiver); 2504 } 2505 2506 int onShellCommand(Shell shell, String cmd) { 2507 if (cmd == null) { 2508 return shell.handleDefaultCommands(cmd); 2509 } 2510 2511 final PrintWriter pw = shell.getOutPrintWriter(); 2512 try { 2513 switch(cmd) { 2514 case "list": 2515 return runList(pw); 2516 } 2517 } catch (RemoteException e) { 2518 pw.println("Remote exception: " + e); 2519 } 2520 return -1; 2521 } 2522 2523 private int runList(PrintWriter pw) throws RemoteException { 2524 final IActivityManager am = ActivityManagerNative.getDefault(); 2525 final List<UserInfo> users = getUsers(false); 2526 if (users == null) { 2527 pw.println("Error: couldn't get users"); 2528 return 1; 2529 } else { 2530 pw.println("Users:"); 2531 for (int i = 0; i < users.size(); i++) { 2532 String running = am.isUserRunning(users.get(i).id, 0) ? " running" : ""; 2533 pw.println("\t" + users.get(i).toString() + running); 2534 } 2535 return 0; 2536 } 2537 } 2538 2539 @Override 2540 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2541 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2542 != PackageManager.PERMISSION_GRANTED) { 2543 pw.println("Permission Denial: can't dump UserManager from from pid=" 2544 + Binder.getCallingPid() 2545 + ", uid=" + Binder.getCallingUid() 2546 + " without permission " 2547 + android.Manifest.permission.DUMP); 2548 return; 2549 } 2550 2551 long now = System.currentTimeMillis(); 2552 StringBuilder sb = new StringBuilder(); 2553 synchronized (mPackagesLock) { 2554 synchronized (mUsersLock) { 2555 pw.println("Users:"); 2556 for (int i = 0; i < mUsers.size(); i++) { 2557 UserInfo user = mUsers.valueAt(i); 2558 if (user == null) { 2559 continue; 2560 } 2561 final int userId = user.id; 2562 pw.print(" "); pw.print(user); 2563 pw.print(" serialNo="); pw.print(user.serialNumber); 2564 if (mRemovingUserIds.get(userId)) { 2565 pw.print(" <removing> "); 2566 } 2567 if (user.partial) { 2568 pw.print(" <partial>"); 2569 } 2570 pw.println(); 2571 pw.print(" Created: "); 2572 if (user.creationTime == 0) { 2573 pw.println("<unknown>"); 2574 } else { 2575 sb.setLength(0); 2576 TimeUtils.formatDuration(now - user.creationTime, sb); 2577 sb.append(" ago"); 2578 pw.println(sb); 2579 } 2580 pw.print(" Last logged in: "); 2581 if (user.lastLoggedInTime == 0) { 2582 pw.println("<unknown>"); 2583 } else { 2584 sb.setLength(0); 2585 TimeUtils.formatDuration(now - user.lastLoggedInTime, sb); 2586 sb.append(" ago"); 2587 pw.println(sb); 2588 } 2589 pw.print(" Has profile owner: "); 2590 pw.println(mIsUserManaged.get(userId)); 2591 pw.println(" Restrictions:"); 2592 synchronized (mRestrictionsLock) { 2593 UserRestrictionsUtils.dumpRestrictions( 2594 pw, " ", mBaseUserRestrictions.get(user.id)); 2595 pw.println(" Device policy local restrictions:"); 2596 UserRestrictionsUtils.dumpRestrictions( 2597 pw, " ", mDevicePolicyLocalUserRestrictions.get(user.id)); 2598 pw.println(" Effective restrictions:"); 2599 UserRestrictionsUtils.dumpRestrictions( 2600 pw, " ", mCachedEffectiveUserRestrictions.get(user.id)); 2601 } 2602 pw.println(); 2603 String accountName = mUserAccounts.get(userId); 2604 if (accountName != null) { 2605 pw.print(" Account name: " + accountName); 2606 pw.println(); 2607 } 2608 } 2609 } 2610 pw.println(" Device policy global restrictions:"); 2611 synchronized (mRestrictionsLock) { 2612 UserRestrictionsUtils 2613 .dumpRestrictions(pw, " ", mDevicePolicyGlobalUserRestrictions); 2614 } 2615 pw.println(); 2616 pw.println(" Guest restrictions:"); 2617 synchronized (mGuestRestrictions) { 2618 UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions); 2619 } 2620 synchronized (mUsersLock) { 2621 pw.println(); 2622 pw.println(" Device managed: " + mIsDeviceManaged); 2623 } 2624 } 2625 } 2626 2627 final class MainHandler extends Handler { 2628 2629 @Override 2630 public void handleMessage(Message msg) { 2631 switch (msg.what) { 2632 case WRITE_USER_MSG: 2633 removeMessages(WRITE_USER_MSG, msg.obj); 2634 synchronized (mPackagesLock) { 2635 int userId = ((UserInfo) msg.obj).id; 2636 UserInfo userInfo = getUserInfoNoChecks(userId); 2637 if (userInfo != null) { 2638 writeUserLP(userInfo); 2639 } 2640 } 2641 } 2642 } 2643 } 2644 2645 /** 2646 * @param userId 2647 * @return whether the user has been initialized yet 2648 */ 2649 boolean isInitialized(int userId) { 2650 return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0; 2651 } 2652 2653 private class LocalService extends UserManagerInternal { 2654 @Override 2655 public void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle localRestrictions, 2656 @Nullable Bundle globalRestrictions) { 2657 UserManagerService.this.setDevicePolicyUserRestrictions(userId, localRestrictions, 2658 globalRestrictions); 2659 } 2660 2661 @Override 2662 public Bundle getBaseUserRestrictions(int userId) { 2663 synchronized (mRestrictionsLock) { 2664 return mBaseUserRestrictions.get(userId); 2665 } 2666 } 2667 2668 @Override 2669 public void setBaseUserRestrictionsByDpmsForMigration( 2670 int userId, Bundle baseRestrictions) { 2671 synchronized (mRestrictionsLock) { 2672 mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions)); 2673 invalidateEffectiveUserRestrictionsLR(userId); 2674 } 2675 2676 final UserInfo userInfo = getUserInfoNoChecks(userId); 2677 synchronized (mPackagesLock) { 2678 if (userInfo != null) { 2679 writeUserLP(userInfo); 2680 } else { 2681 Slog.w(LOG_TAG, "UserInfo not found for " + userId); 2682 } 2683 } 2684 } 2685 2686 @Override 2687 public boolean getUserRestriction(int userId, String key) { 2688 return getUserRestrictions(userId).getBoolean(key); 2689 } 2690 2691 @Override 2692 public void addUserRestrictionsListener(UserRestrictionsListener listener) { 2693 synchronized (mUserRestrictionsListeners) { 2694 mUserRestrictionsListeners.add(listener); 2695 } 2696 } 2697 2698 @Override 2699 public void removeUserRestrictionsListener(UserRestrictionsListener listener) { 2700 synchronized (mUserRestrictionsListeners) { 2701 mUserRestrictionsListeners.remove(listener); 2702 } 2703 } 2704 2705 @Override 2706 public void setDeviceManaged(boolean isManaged) { 2707 synchronized (mUsersLock) { 2708 mIsDeviceManaged = isManaged; 2709 } 2710 } 2711 2712 @Override 2713 public void setUserManaged(int userId, boolean isManaged) { 2714 synchronized (mUsersLock) { 2715 mIsUserManaged.put(userId, isManaged); 2716 } 2717 } 2718 } 2719 2720 private class Shell extends ShellCommand { 2721 @Override 2722 public int onCommand(String cmd) { 2723 return onShellCommand(this, cmd); 2724 } 2725 2726 @Override 2727 public void onHelp() { 2728 final PrintWriter pw = getOutPrintWriter(); 2729 pw.println("User manager (user) commands:"); 2730 pw.println(" help"); 2731 pw.println(" Print this help text."); 2732 pw.println(""); 2733 pw.println(" list"); 2734 pw.println(" Prints all users on the system."); 2735 } 2736 } 2737 2738 private static void debug(String message) { 2739 Log.d(LOG_TAG, message + 2740 (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, " ") : "")); 2741 } 2742} 2743