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