diff --git a/core/java/android/content/pm/UserProperties.java b/core/java/android/content/pm/UserProperties.java index 645a1ac9d651f..80f3264116827 100644 --- a/core/java/android/content/pm/UserProperties.java +++ b/core/java/android/content/pm/UserProperties.java @@ -43,17 +43,20 @@ public final class UserProperties implements Parcelable { // Attribute strings for reading/writing properties to/from XML. private static final String ATTR_SHOW_IN_LAUNCHER = "showInLauncher"; private static final String ATTR_START_WITH_PARENT = "startWithParent"; + private static final String ATTR_SHOW_IN_SETTINGS = "showInSettings"; /** Index values of each property (to indicate whether they are present in this object). */ @IntDef(prefix = "INDEX_", value = { INDEX_SHOW_IN_LAUNCHER, INDEX_START_WITH_PARENT, + INDEX_SHOW_IN_SETTINGS, }) @Retention(RetentionPolicy.SOURCE) private @interface PropertyIndex { } private static final int INDEX_SHOW_IN_LAUNCHER = 0; private static final int INDEX_START_WITH_PARENT = 1; + private static final int INDEX_SHOW_IN_SETTINGS = 2; /** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */ private long mPropertiesPresent = 0; @@ -86,6 +89,37 @@ public final class UserProperties implements Parcelable { */ public static final int SHOW_IN_LAUNCHER_NO = 2; + /** + * Possible values for whether or how to show this user in the Settings app. + * @hide + */ + @IntDef(prefix = "SHOW_IN_SETTINGS_", value = { + SHOW_IN_SETTINGS_WITH_PARENT, + SHOW_IN_SETTINGS_SEPARATE, + SHOW_IN_SETTINGS_NO, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ShowInSettings { + } + /** + * Suggests that the Settings app should show this user's apps in the main tab. + * That is, either this user is a full user, so its apps should be presented accordingly, or, if + * this user is a profile, then its apps should be shown alongside its parent's apps. + * @hide + */ + public static final int SHOW_IN_SETTINGS_WITH_PARENT = 0; + /** + * Suggests that the Settings app should show this user's apps, but separately from the apps of + * this user's parent. + * @hide + */ + public static final int SHOW_IN_SETTINGS_SEPARATE = 1; + /** + * Suggests that the Settings app should not show this user. + * @hide + */ + public static final int SHOW_IN_SETTINGS_NO = 2; + /** * Reference to the default user properties for this user's user type. *
The caller must have {@link android.Manifest.permission#MANAGE_USERS} to query this + * property. + * + * @return whether, and how, a profile should be shown in the Settings. + * @hide + */ + public @ShowInSettings int getShowInSettings() { + if (isPresent(INDEX_SHOW_IN_SETTINGS)) return mShowInSettings; + if (mDefaultProperties != null) return mDefaultProperties.mShowInSettings; + throw new SecurityException("You don't have permission to query mShowInSettings"); + } + /** @hide */ + public void setShowInSettings(@ShowInSettings int val) { + this.mShowInSettings = val; + setPresent(INDEX_SHOW_IN_SETTINGS); + } + private @ShowInSettings int mShowInSettings; + /** * Returns whether a profile should be started when its parent starts (unless in quiet mode). * This only applies for users that have parents (i.e. for profiles). @@ -206,6 +268,7 @@ public final class UserProperties implements Parcelable { + "mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent) + ", mShowInLauncher=" + getShowInLauncher() + ", mStartWithParent=" + getStartWithParent() + + ", mShowInSettings=" + getShowInSettings() + "}"; } @@ -219,6 +282,7 @@ public final class UserProperties implements Parcelable { pw.println(prefix + " mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent)); pw.println(prefix + " mShowInLauncher=" + getShowInLauncher()); pw.println(prefix + " mStartWithParent=" + getStartWithParent()); + pw.println(prefix + " mShowInSettings=" + getShowInSettings()); } /** @@ -258,6 +322,8 @@ public final class UserProperties implements Parcelable { case ATTR_START_WITH_PARENT: setStartWithParent(parser.getAttributeBoolean(i)); break; + case ATTR_SHOW_IN_SETTINGS: + setShowInSettings(parser.getAttributeInt(i)); default: Slog.w(LOG_TAG, "Skipping unknown property " + attributeName); } @@ -281,6 +347,9 @@ public final class UserProperties implements Parcelable { if (isPresent(INDEX_START_WITH_PARENT)) { serializer.attributeBoolean(null, ATTR_START_WITH_PARENT, mStartWithParent); } + if (isPresent(INDEX_SHOW_IN_SETTINGS)) { + serializer.attributeInt(null, ATTR_SHOW_IN_SETTINGS, mShowInSettings); + } } // For use only with an object that has already had any permission-lacking fields stripped out. @@ -289,6 +358,7 @@ public final class UserProperties implements Parcelable { dest.writeLong(mPropertiesPresent); dest.writeInt(mShowInLauncher); dest.writeBoolean(mStartWithParent); + dest.writeInt(mShowInSettings); } /** @@ -301,6 +371,7 @@ public final class UserProperties implements Parcelable { mPropertiesPresent = source.readLong(); mShowInLauncher = source.readInt(); mStartWithParent = source.readBoolean(); + mShowInSettings = source.readInt(); } @Override @@ -327,6 +398,7 @@ public final class UserProperties implements Parcelable { // UserProperties fields and their default values. private @ShowInLauncher int mShowInLauncher = SHOW_IN_LAUNCHER_WITH_PARENT; private boolean mStartWithParent = false; + private @ShowInSettings int mShowInSettings = SHOW_IN_SETTINGS_WITH_PARENT; public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) { mShowInLauncher = showInLauncher; @@ -338,21 +410,30 @@ public final class UserProperties implements Parcelable { return this; } + /** Sets the value for {@link #mShowInSettings} */ + public Builder setShowInSettings(@ShowInSettings int showInSettings) { + mShowInSettings = showInSettings; + return this; + } + /** Builds a UserProperties object with *all* values populated. */ public UserProperties build() { return new UserProperties( mShowInLauncher, - mStartWithParent); + mStartWithParent, + mShowInSettings); } } // end Builder /** Creates a UserProperties with the given properties. Intended for building default values. */ private UserProperties( @ShowInLauncher int showInLauncher, - boolean startWithParent) { + boolean startWithParent, + @ShowInSettings int showInSettings) { mDefaultProperties = null; setShowInLauncher(showInLauncher); setStartWithParent(startWithParent); + setShowInSettings(showInSettings); } } diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java index b98d20eaa38e6..5b6196f829964 100644 --- a/services/core/java/com/android/server/pm/UserTypeFactory.java +++ b/services/core/java/com/android/server/pm/UserTypeFactory.java @@ -128,7 +128,8 @@ public final class UserTypeFactory { .setIsCredentialSharableWithParent(true) .setDefaultUserProperties(new UserProperties.Builder() .setStartWithParent(true) - .setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT)); + .setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT) + .setShowInSettings(UserProperties.SHOW_IN_SETTINGS_WITH_PARENT)); } /** @@ -163,7 +164,8 @@ public final class UserTypeFactory { .setIsCredentialSharableWithParent(true) .setDefaultUserProperties(new UserProperties.Builder() .setStartWithParent(true) - .setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_SEPARATE)); + .setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_SEPARATE) + .setShowInSettings(UserProperties.SHOW_IN_SETTINGS_SEPARATE)); } /** diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java index 8efcc41933e7c..8d2cffa93f411 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java @@ -59,9 +59,11 @@ public class UserManagerServiceUserPropertiesTest { final UserProperties defaultProps = new UserProperties.Builder() .setShowInLauncher(21) .setStartWithParent(false) + .setShowInSettings(45) .build(); final UserProperties actualProps = new UserProperties(defaultProps); actualProps.setShowInLauncher(14); + actualProps.setShowInSettings(32); // Write the properties to xml. final ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -99,10 +101,12 @@ public class UserManagerServiceUserPropertiesTest { final UserProperties defaultProps = new UserProperties.Builder() .setShowInLauncher(2145) .setStartWithParent(true) + .setShowInSettings(3452) .build(); final UserProperties orig = new UserProperties(defaultProps); orig.setShowInLauncher(2841); orig.setStartWithParent(false); + orig.setShowInSettings(1437); // Test every permission level. (Currently, it's linear so it's easy.) for (int permLevel = 0; permLevel < 4; permLevel++) { @@ -140,6 +144,9 @@ public class UserManagerServiceUserPropertiesTest { assertEqualGetterOrThrows(orig::getStartWithParent, copy::getStartWithParent, exposeAll); // Items requiring hasManagePermission - put them here using hasManagePermission. + assertEqualGetterOrThrows(orig::getShowInSettings, copy::getShowInSettings, + hasManagePermission); + // Items requiring hasQueryPermission - put them here using hasQueryPermission. // Items with no permission requirements. @@ -182,5 +189,6 @@ public class UserManagerServiceUserPropertiesTest { assertThat(expected.getPropertiesPresent()).isEqualTo(actual.getPropertiesPresent()); assertThat(expected.getShowInLauncher()).isEqualTo(actual.getShowInLauncher()); assertThat(expected.getStartWithParent()).isEqualTo(actual.getStartWithParent()); + assertThat(expected.getShowInSettings()).isEqualTo(actual.getShowInSettings()); } } diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index c1e778d1c9e7e..df2c5dd3cf65c 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -599,6 +599,7 @@ public final class UserManagerTest { // Check that this new user has the expected properties (relative to the defaults) // provided that the test caller has the necessary permissions. assertThat(userProps.getShowInLauncher()).isEqualTo(typeProps.getShowInLauncher()); + assertThat(userProps.getShowInSettings()).isEqualTo(typeProps.getShowInSettings()); assertThrows(SecurityException.class, userProps::getStartWithParent); }