1 /* 2 * Copyright (C) 2019 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 17 package com.android.server.pm; 18 19 import android.annotation.ColorRes; 20 import android.annotation.DrawableRes; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.StringRes; 24 import android.content.pm.UserInfo; 25 import android.content.pm.UserInfo.UserInfoFlag; 26 import android.content.pm.UserProperties; 27 import android.content.res.Resources; 28 import android.os.Bundle; 29 import android.os.UserManager; 30 31 import com.android.internal.util.Preconditions; 32 import com.android.server.BundleUtils; 33 34 import java.io.PrintWriter; 35 import java.util.ArrayList; 36 import java.util.Collections; 37 import java.util.List; 38 39 /** 40 * Contains the details about a multiuser "user type", such as a 41 * {@link UserManager#USER_TYPE_PROFILE_MANAGED}. 42 * 43 * Tests are located in UserManagerServiceUserTypeTest.java. 44 * @hide 45 */ 46 public final class UserTypeDetails { 47 48 /** Indicates that there is no limit to the number of users allowed. */ 49 public static final int UNLIMITED_NUMBER_OF_USERS = -1; 50 51 /** Name of the user type, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}. */ 52 private final @NonNull String mName; 53 54 /** Whether users of this type can be created. */ 55 private final boolean mEnabled; 56 57 // TODO(b/142482943): Currently unused and not set. Hook this up. 58 private final int mLabel; 59 60 /** 61 * Maximum number of this user type allowed on the device. 62 * Use {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit. 63 */ 64 private final int mMaxAllowed; 65 66 /** 67 * Maximum number of this user type allowed per parent (for user types, like profiles, that 68 * have parents). 69 * Use {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit. 70 */ 71 // TODO(b/142482943): Should this also apply to restricted profiles? 72 private final int mMaxAllowedPerParent; 73 74 // TODO(b/143784345): Update doc when we clean up UserInfo. 75 /** The {@link UserInfo.UserInfoFlag} representing the base type of this user. */ 76 private final @UserInfoFlag int mBaseType; 77 78 // TODO(b/143784345): Update doc/name when we clean up UserInfo. 79 /** The {@link UserInfoFlag}s to apply by default to newly created users of this type. */ 80 private final @UserInfoFlag int mDefaultUserInfoPropertyFlags; 81 82 /** 83 * List of User Restrictions to apply by default to newly created users of this type. 84 * <p>Does not apply to SYSTEM users (since they are not formally created); for them use 85 * {@link com.android.internal.R.array#config_defaultFirstUserRestrictions} instead. 86 * The Bundle is of the form used by {@link UserRestrictionsUtils}. 87 */ 88 private final @Nullable Bundle mDefaultRestrictions; 89 90 /** 91 * List of {@link android.provider.Settings.System} to apply by default to newly created users 92 * of this type. 93 */ 94 private final @Nullable Bundle mDefaultSystemSettings; 95 96 /** 97 * List of {@link android.provider.Settings.Secure} to apply by default to newly created users 98 * of this type. 99 */ 100 private final @Nullable Bundle mDefaultSecureSettings; 101 102 /** 103 * List of {@link DefaultCrossProfileIntentFilter} to allow by default for newly created 104 * profiles. 105 */ 106 private final @Nullable List<DefaultCrossProfileIntentFilter> mDefaultCrossProfileIntentFilters; 107 108 109 // Fields for profiles only, controlling the nature of their badges. 110 // All badge information should be set if {@link #hasBadge()} is true. 111 112 /** Resource ID of the badge put on icons. */ 113 private @DrawableRes final int mIconBadge; 114 /** Resource ID of the badge. Should be set if mIconBadge is set. */ 115 private @DrawableRes final int mBadgePlain; 116 /** Resource ID of the badge without a background. Should be set if mIconBadge is set. */ 117 private @DrawableRes final int mBadgeNoBackground; 118 119 /** 120 * Resource ID ({@link StringRes}) of the of the labels to describe badged apps; should be the 121 * same format as com.android.internal.R.color.profile_badge_1. These are used for accessibility 122 * services. 123 * 124 * <p>This is an array because, in general, there may be multiple users of the same user type. 125 * In this case, the user is indexed according to its {@link UserInfo#profileBadge}. 126 * 127 * <p>Must be set if mIconBadge is set. 128 */ 129 private final @Nullable int[] mBadgeLabels; 130 131 /** 132 * Resource ID ({@link ColorRes}) of the colors badge put on icons. 133 * (The value is a resource ID referring to the color; it is not the color value itself). 134 * 135 * <p>This is an array because, in general, there may be multiple users of the same user type. 136 * In this case, the user is indexed according to its {@link UserInfo#profileBadge}. 137 * 138 * <p>Must be set if mIconBadge is set. 139 */ 140 private final @Nullable int[] mBadgeColors; 141 142 /** 143 * Resource ID ({@link ColorRes}) of the colors badge put on icons when in dark theme. 144 * (The value is a resource ID referring to the color; it is not the color value itself). 145 * 146 * <p>This is an array because, in general, there may be multiple users of the same user type. 147 * In this case, the user is indexed according to its {@link UserInfo#profileBadge}. 148 * 149 * <p>Must be set if mIconBadge is set. 150 */ 151 private final @Nullable int[] mDarkThemeBadgeColors; 152 153 /** 154 * The default {@link UserProperties} for the user type. 155 * <p> The uninitialized value of each property is implied by {@link UserProperties.Builder}. 156 */ 157 private final @NonNull UserProperties mDefaultUserProperties; 158 UserTypeDetails(@onNull String name, boolean enabled, int maxAllowed, @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label, int maxAllowedPerParent, int iconBadge, int badgePlain, int badgeNoBackground, @Nullable int[] badgeLabels, @Nullable int[] badgeColors, @Nullable int[] darkThemeBadgeColors, @Nullable Bundle defaultRestrictions, @Nullable Bundle defaultSystemSettings, @Nullable Bundle defaultSecureSettings, @Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters, @NonNull UserProperties defaultUserProperties)159 private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed, 160 @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label, 161 int maxAllowedPerParent, 162 int iconBadge, int badgePlain, int badgeNoBackground, 163 @Nullable int[] badgeLabels, @Nullable int[] badgeColors, 164 @Nullable int[] darkThemeBadgeColors, 165 @Nullable Bundle defaultRestrictions, 166 @Nullable Bundle defaultSystemSettings, 167 @Nullable Bundle defaultSecureSettings, 168 @Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters, 169 @NonNull UserProperties defaultUserProperties) { 170 this.mName = name; 171 this.mEnabled = enabled; 172 this.mMaxAllowed = maxAllowed; 173 this.mMaxAllowedPerParent = maxAllowedPerParent; 174 this.mBaseType = baseType; 175 this.mDefaultUserInfoPropertyFlags = defaultUserInfoPropertyFlags; 176 this.mDefaultRestrictions = defaultRestrictions; 177 this.mDefaultSystemSettings = defaultSystemSettings; 178 this.mDefaultSecureSettings = defaultSecureSettings; 179 this.mDefaultCrossProfileIntentFilters = defaultCrossProfileIntentFilters; 180 181 this.mIconBadge = iconBadge; 182 this.mBadgePlain = badgePlain; 183 this.mBadgeNoBackground = badgeNoBackground; 184 this.mLabel = label; 185 this.mBadgeLabels = badgeLabels; 186 this.mBadgeColors = badgeColors; 187 this.mDarkThemeBadgeColors = darkThemeBadgeColors; 188 this.mDefaultUserProperties = defaultUserProperties; 189 } 190 191 /** 192 * Returns the name of the user type, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}. 193 */ getName()194 public String getName() { 195 return mName; 196 } 197 198 /** 199 * Returns whether this user type is enabled. 200 * If it is not enabled, all future attempts to create users of this type will be rejected. 201 */ isEnabled()202 public boolean isEnabled() { 203 return mEnabled; 204 } 205 206 /** 207 * Returns the maximum number of this user type allowed on the device. 208 * <p>Returns {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit. 209 */ getMaxAllowed()210 public int getMaxAllowed() { 211 return mMaxAllowed; 212 } 213 214 /** 215 * Returns the maximum number of this user type allowed per parent (for user types, like 216 * profiles, that have parents). 217 * Under certain circumstances (such as after a change-user-type) the max value can actually 218 * be exceeded: this is allowed in order to keep the device in a usable state. 219 * An error is logged in {@link UserManagerService#upgradeProfileToTypeLU} 220 * <p>Returns {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit. 221 */ getMaxAllowedPerParent()222 public int getMaxAllowedPerParent() { 223 return mMaxAllowedPerParent; 224 } 225 226 // TODO(b/143784345): Update comment when UserInfo is reorganized. 227 /** The {@link UserInfoFlag}s to apply by default to newly created users of this type. */ getDefaultUserInfoFlags()228 public int getDefaultUserInfoFlags() { 229 return mDefaultUserInfoPropertyFlags | mBaseType; 230 } 231 232 // TODO(b/142482943) Hook this up; it is currently unused. getLabel()233 public int getLabel() { 234 return mLabel; 235 } 236 237 /** Returns whether users of this user type should be badged. */ hasBadge()238 public boolean hasBadge() { 239 return mIconBadge != Resources.ID_NULL; 240 } 241 242 /** Resource ID of the badge to put on icons. */ getIconBadge()243 public @DrawableRes int getIconBadge() { 244 return mIconBadge; 245 } 246 247 /** Resource ID of the badge. Used for {@link UserManager#getUserBadgeResId(int)}. */ getBadgePlain()248 public @DrawableRes int getBadgePlain() { 249 return mBadgePlain; 250 } 251 252 /** Resource ID of the badge without a background. */ getBadgeNoBackground()253 public @DrawableRes int getBadgeNoBackground() { 254 return mBadgeNoBackground; 255 } 256 257 /** 258 * Returns the Resource ID of the badgeIndexth badge label, where the badgeIndex is expected 259 * to be the {@link UserInfo#profileBadge} of the user. 260 * If badgeIndex exceeds the number of labels, returns the label for the highest index. 261 */ getBadgeLabel(int badgeIndex)262 public @StringRes int getBadgeLabel(int badgeIndex) { 263 if (mBadgeLabels == null || mBadgeLabels.length == 0 || badgeIndex < 0) { 264 return Resources.ID_NULL; 265 } 266 return mBadgeLabels[Math.min(badgeIndex, mBadgeLabels.length - 1)]; 267 } 268 269 /** 270 * Returns the Resource ID of the badgeIndexth badge color, where the badgeIndex is expected 271 * to be the {@link UserInfo#profileBadge} of the user. 272 * If badgeIndex exceeds the number of colors, returns the color for the highest index. 273 */ getBadgeColor(int badgeIndex)274 public @ColorRes int getBadgeColor(int badgeIndex) { 275 if (mBadgeColors == null || mBadgeColors.length == 0 || badgeIndex < 0) { 276 return Resources.ID_NULL; 277 } 278 return mBadgeColors[Math.min(badgeIndex, mBadgeColors.length - 1)]; 279 } 280 281 /** 282 * Returns the Resource ID of the badgeIndexth dark theme badge color, where the badgeIndex is 283 * expected to be the {@link UserInfo#profileBadge} of the user. 284 * If dark theme badge colors haven't been set, use the light theme badge color. 285 * If badgeIndex exceeds the number of colors, returns the color for the highest index. 286 */ getDarkThemeBadgeColor(int badgeIndex)287 public @ColorRes int getDarkThemeBadgeColor(int badgeIndex) { 288 if (mDarkThemeBadgeColors == null || mDarkThemeBadgeColors.length == 0 || badgeIndex < 0) { 289 return getBadgeColor(badgeIndex); 290 } 291 return mDarkThemeBadgeColors[Math.min(badgeIndex, mDarkThemeBadgeColors.length - 1)]; 292 } 293 294 295 /** 296 * Returns the reference to the default {@link UserProperties} for this type of user. 297 * This is not a copy. Do NOT modify this object. 298 */ getDefaultUserPropertiesReference()299 public @NonNull UserProperties getDefaultUserPropertiesReference() { 300 return mDefaultUserProperties; 301 } 302 isProfile()303 public boolean isProfile() { 304 return (mBaseType & UserInfo.FLAG_PROFILE) != 0; 305 } 306 isFull()307 public boolean isFull() { 308 return (mBaseType & UserInfo.FLAG_FULL) != 0; 309 } 310 isSystem()311 public boolean isSystem() { 312 return (mBaseType & UserInfo.FLAG_SYSTEM) != 0; 313 } 314 315 /** Returns a {@link Bundle} representing the default user restrictions. */ getDefaultRestrictions()316 @NonNull Bundle getDefaultRestrictions() { 317 return BundleUtils.clone(mDefaultRestrictions); 318 } 319 320 /** Adds the default user restrictions to the given bundle of restrictions. */ addDefaultRestrictionsTo(@onNull Bundle currentRestrictions)321 public void addDefaultRestrictionsTo(@NonNull Bundle currentRestrictions) { 322 UserRestrictionsUtils.merge(currentRestrictions, mDefaultRestrictions); 323 } 324 325 /** Returns a {@link Bundle} representing the default system settings. */ getDefaultSystemSettings()326 @NonNull Bundle getDefaultSystemSettings() { 327 return BundleUtils.clone(mDefaultSystemSettings); 328 } 329 330 /** Returns a {@link Bundle} representing the default secure settings. */ getDefaultSecureSettings()331 @NonNull Bundle getDefaultSecureSettings() { 332 return BundleUtils.clone(mDefaultSecureSettings); 333 } 334 335 /** Returns a list of default cross profile intent filters. */ getDefaultCrossProfileIntentFilters()336 @NonNull List<DefaultCrossProfileIntentFilter> getDefaultCrossProfileIntentFilters() { 337 return mDefaultCrossProfileIntentFilters != null 338 ? new ArrayList<>(mDefaultCrossProfileIntentFilters) 339 : Collections.emptyList(); 340 } 341 342 /** Dumps details of the UserTypeDetails. Do not parse this. */ dump(PrintWriter pw, String prefix)343 public void dump(PrintWriter pw, String prefix) { 344 pw.print(prefix); pw.print("mName: "); pw.println(mName); 345 pw.print(prefix); pw.print("mBaseType: "); pw.println(UserInfo.flagsToString(mBaseType)); 346 pw.print(prefix); pw.print("mEnabled: "); pw.println(mEnabled); 347 pw.print(prefix); pw.print("mMaxAllowed: "); pw.println(mMaxAllowed); 348 pw.print(prefix); pw.print("mMaxAllowedPerParent: "); pw.println(mMaxAllowedPerParent); 349 pw.print(prefix); pw.print("mDefaultUserInfoFlags: "); 350 pw.println(UserInfo.flagsToString(mDefaultUserInfoPropertyFlags)); 351 pw.print(prefix); pw.print("mLabel: "); pw.println(mLabel); 352 mDefaultUserProperties.println(pw, prefix); 353 354 final String restrictionsPrefix = prefix + " "; 355 if (isSystem()) { 356 pw.print(prefix); pw.println("config_defaultFirstUserRestrictions: "); 357 try { 358 final Bundle restrictions = new Bundle(); 359 final String[] defaultFirstUserRestrictions = Resources.getSystem().getStringArray( 360 com.android.internal.R.array.config_defaultFirstUserRestrictions); 361 for (String userRestriction : defaultFirstUserRestrictions) { 362 if (UserRestrictionsUtils.isValidRestriction(userRestriction)) { 363 restrictions.putBoolean(userRestriction, true); 364 } 365 } 366 UserRestrictionsUtils.dumpRestrictions(pw, restrictionsPrefix, restrictions); 367 } catch (Resources.NotFoundException e) { 368 pw.print(restrictionsPrefix); pw.println("none - resource not found"); 369 } 370 } else { 371 pw.print(prefix); pw.println("mDefaultRestrictions: "); 372 UserRestrictionsUtils.dumpRestrictions(pw, restrictionsPrefix, mDefaultRestrictions); 373 } 374 375 pw.print(prefix); pw.print("mIconBadge: "); pw.println(mIconBadge); 376 pw.print(prefix); pw.print("mBadgePlain: "); pw.println(mBadgePlain); 377 pw.print(prefix); pw.print("mBadgeNoBackground: "); pw.println(mBadgeNoBackground); 378 pw.print(prefix); pw.print("mBadgeLabels.length: "); 379 pw.println(mBadgeLabels != null ? mBadgeLabels.length : "0(null)"); 380 pw.print(prefix); pw.print("mBadgeColors.length: "); 381 pw.println(mBadgeColors != null ? mBadgeColors.length : "0(null)"); 382 pw.print(prefix); pw.print("mDarkThemeBadgeColors.length: "); 383 pw.println(mDarkThemeBadgeColors != null ? mDarkThemeBadgeColors.length : "0(null)"); 384 } 385 386 /** Builder for a {@link UserTypeDetails}; see that class for documentation. */ 387 public static final class Builder { 388 // UserTypeDetails properties and their default values. 389 private String mName; // This MUST be explicitly set. 390 private int mBaseType; // This MUST be explicitly set. 391 private int mMaxAllowed = UNLIMITED_NUMBER_OF_USERS; 392 private int mMaxAllowedPerParent = UNLIMITED_NUMBER_OF_USERS; 393 private int mDefaultUserInfoPropertyFlags = 0; 394 private @Nullable Bundle mDefaultRestrictions = null; 395 private @Nullable Bundle mDefaultSystemSettings = null; 396 private @Nullable Bundle mDefaultSecureSettings = null; 397 private @Nullable List<DefaultCrossProfileIntentFilter> mDefaultCrossProfileIntentFilters = 398 null; 399 private int mEnabled = 1; 400 private int mLabel = Resources.ID_NULL; 401 private @Nullable int[] mBadgeLabels = null; 402 private @Nullable int[] mBadgeColors = null; 403 private @Nullable int[] mDarkThemeBadgeColors = null; 404 private @DrawableRes int mIconBadge = Resources.ID_NULL; 405 private @DrawableRes int mBadgePlain = Resources.ID_NULL; 406 private @DrawableRes int mBadgeNoBackground = Resources.ID_NULL; 407 // Default UserProperties cannot be null but for efficiency we don't initialize it now. 408 // If it isn't set explicitly, {@link UserProperties.Builder#build()} will be used. 409 private @Nullable UserProperties mDefaultUserProperties = null; 410 setName(String name)411 public Builder setName(String name) { 412 mName = name; 413 return this; 414 } 415 setEnabled(int enabled)416 public Builder setEnabled(int enabled) { 417 mEnabled = enabled; 418 return this; 419 } 420 setMaxAllowed(int maxAllowed)421 public Builder setMaxAllowed(int maxAllowed) { 422 mMaxAllowed = maxAllowed; 423 return this; 424 } 425 setMaxAllowedPerParent(int maxAllowedPerParent)426 public Builder setMaxAllowedPerParent(int maxAllowedPerParent) { 427 mMaxAllowedPerParent = maxAllowedPerParent; 428 return this; 429 } 430 setBaseType(@serInfoFlag int baseType)431 public Builder setBaseType(@UserInfoFlag int baseType) { 432 mBaseType = baseType; 433 return this; 434 } 435 setDefaultUserInfoPropertyFlags(@serInfoFlag int flags)436 public Builder setDefaultUserInfoPropertyFlags(@UserInfoFlag int flags) { 437 mDefaultUserInfoPropertyFlags = flags; 438 return this; 439 } 440 setBadgeLabels(@tringRes int ... badgeLabels)441 public Builder setBadgeLabels(@StringRes int ... badgeLabels) { 442 mBadgeLabels = badgeLabels; 443 return this; 444 } 445 setBadgeColors(@olorRes int ... badgeColors)446 public Builder setBadgeColors(@ColorRes int ... badgeColors) { 447 mBadgeColors = badgeColors; 448 return this; 449 } 450 451 /** 452 * The badge colors when the badge is on a dark background. 453 */ setDarkThemeBadgeColors(@olorRes int ... darkThemeBadgeColors)454 public Builder setDarkThemeBadgeColors(@ColorRes int ... darkThemeBadgeColors) { 455 mDarkThemeBadgeColors = darkThemeBadgeColors; 456 return this; 457 } 458 setIconBadge(@rawableRes int badgeIcon)459 public Builder setIconBadge(@DrawableRes int badgeIcon) { 460 mIconBadge = badgeIcon; 461 return this; 462 } 463 setBadgePlain(@rawableRes int badgePlain)464 public Builder setBadgePlain(@DrawableRes int badgePlain) { 465 mBadgePlain = badgePlain; 466 return this; 467 } 468 setBadgeNoBackground(@rawableRes int badgeNoBackground)469 public Builder setBadgeNoBackground(@DrawableRes int badgeNoBackground) { 470 mBadgeNoBackground = badgeNoBackground; 471 return this; 472 } 473 setLabel(int label)474 public Builder setLabel(int label) { 475 mLabel = label; 476 return this; 477 } 478 setDefaultRestrictions(@ullable Bundle restrictions)479 public Builder setDefaultRestrictions(@Nullable Bundle restrictions) { 480 mDefaultRestrictions = restrictions; 481 return this; 482 } 483 setDefaultSystemSettings(@ullable Bundle settings)484 public Builder setDefaultSystemSettings(@Nullable Bundle settings) { 485 mDefaultSystemSettings = settings; 486 return this; 487 } 488 setDefaultSecureSettings(@ullable Bundle settings)489 public Builder setDefaultSecureSettings(@Nullable Bundle settings) { 490 mDefaultSecureSettings = settings; 491 return this; 492 } 493 setDefaultCrossProfileIntentFilters( @ullable List<DefaultCrossProfileIntentFilter> intentFilters)494 public Builder setDefaultCrossProfileIntentFilters( 495 @Nullable List<DefaultCrossProfileIntentFilter> intentFilters) { 496 mDefaultCrossProfileIntentFilters = intentFilters; 497 return this; 498 } 499 500 /** 501 * Sets (replacing if necessary) the default UserProperties object for this user type. 502 * Takes a builder, rather than a built object, to efficiently ensure that a fresh copy of 503 * properties is stored (since it later might be modified by UserProperties#updateFromXml). 504 */ setDefaultUserProperties(UserProperties.Builder userPropertiesBuilder)505 public Builder setDefaultUserProperties(UserProperties.Builder userPropertiesBuilder) { 506 mDefaultUserProperties = userPropertiesBuilder.build(); 507 return this; 508 } 509 getDefaultUserProperties()510 public @NonNull UserProperties getDefaultUserProperties() { 511 if (mDefaultUserProperties == null) { 512 mDefaultUserProperties = new UserProperties.Builder().build(); 513 } 514 return mDefaultUserProperties; 515 } 516 getBaseType()517 @UserInfoFlag int getBaseType() { 518 return mBaseType; 519 } 520 createUserTypeDetails()521 public UserTypeDetails createUserTypeDetails() { 522 Preconditions.checkArgument(mName != null, 523 "Cannot create a UserTypeDetails with no name."); 524 Preconditions.checkArgument(hasValidBaseType(), 525 "UserTypeDetails " + mName + " has invalid baseType: " + mBaseType); 526 Preconditions.checkArgument(hasValidPropertyFlags(), 527 "UserTypeDetails " + mName + " has invalid flags: " 528 + Integer.toHexString(mDefaultUserInfoPropertyFlags)); 529 checkSystemAndMainUserPreconditions(); 530 if (hasBadge()) { 531 Preconditions.checkArgument(mBadgeLabels != null && mBadgeLabels.length != 0, 532 "UserTypeDetails " + mName + " has badge but no badgeLabels."); 533 Preconditions.checkArgument(mBadgeColors != null && mBadgeColors.length != 0, 534 "UserTypeDetails " + mName + " has badge but no badgeColors."); 535 } 536 if (!isProfile()) { 537 Preconditions.checkArgument(mDefaultCrossProfileIntentFilters == null 538 || mDefaultCrossProfileIntentFilters.isEmpty(), 539 "UserTypeDetails %s has a non empty " 540 + "defaultCrossProfileIntentFilters", mName); 541 } 542 return new UserTypeDetails( 543 mName, 544 mEnabled != 0, 545 mMaxAllowed, 546 mBaseType, 547 mDefaultUserInfoPropertyFlags, 548 mLabel, 549 mMaxAllowedPerParent, 550 mIconBadge, 551 mBadgePlain, 552 mBadgeNoBackground, 553 mBadgeLabels, 554 mBadgeColors, 555 mDarkThemeBadgeColors == null ? mBadgeColors : mDarkThemeBadgeColors, 556 mDefaultRestrictions, 557 mDefaultSystemSettings, 558 mDefaultSecureSettings, 559 mDefaultCrossProfileIntentFilters, 560 getDefaultUserProperties()); 561 } 562 hasBadge()563 private boolean hasBadge() { 564 return mIconBadge != Resources.ID_NULL; 565 } 566 isProfile()567 private boolean isProfile() { 568 return (mBaseType & UserInfo.FLAG_PROFILE) != 0; 569 } 570 571 // TODO(b/143784345): Refactor this when we clean up UserInfo. hasValidBaseType()572 private boolean hasValidBaseType() { 573 return mBaseType == UserInfo.FLAG_FULL 574 || mBaseType == UserInfo.FLAG_PROFILE 575 || mBaseType == UserInfo.FLAG_SYSTEM 576 || mBaseType == (UserInfo.FLAG_FULL | UserInfo.FLAG_SYSTEM); 577 } 578 579 // TODO(b/143784345): Refactor this when we clean up UserInfo. hasValidPropertyFlags()580 private boolean hasValidPropertyFlags() { 581 final int forbiddenMask = 582 UserInfo.FLAG_INITIALIZED | 583 UserInfo.FLAG_QUIET_MODE | 584 UserInfo.FLAG_FULL | 585 UserInfo.FLAG_SYSTEM | 586 UserInfo.FLAG_PROFILE; 587 return (mDefaultUserInfoPropertyFlags & forbiddenMask) == 0; 588 } 589 checkSystemAndMainUserPreconditions()590 private void checkSystemAndMainUserPreconditions() { 591 // Primary must be synonymous with System. 592 Preconditions.checkArgument( 593 ((mBaseType & UserInfo.FLAG_SYSTEM) != 0) == 594 ((mDefaultUserInfoPropertyFlags & UserInfo.FLAG_PRIMARY) != 0), 595 "UserTypeDetails " + mName + " cannot be SYSTEM xor PRIMARY."); 596 // At most one MainUser is ever allowed at a time. 597 Preconditions.checkArgument( 598 ((mDefaultUserInfoPropertyFlags & UserInfo.FLAG_MAIN) == 0) || mMaxAllowed == 1, 599 "UserTypeDetails " + mName + " must not sanction more than one MainUser."); 600 } 601 } 602 603 /** 604 * Returns whether the user type is a managed profile 605 * (i.e. {@link UserManager#USER_TYPE_PROFILE_MANAGED}). 606 */ isManagedProfile()607 public boolean isManagedProfile() { 608 return UserManager.isUserTypeManagedProfile(mName); 609 } 610 } 611