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