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