/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Class holding the properties of a user that derive mostly from its user type. * * @hide */ @SystemApi public final class UserProperties implements Parcelable { private static final String LOG_TAG = UserProperties.class.getSimpleName(); // 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"; private static final String ATTR_SHOW_IN_QUIET_MODE = "showInQuietMode"; private static final String ATTR_SHOW_IN_SHARING_SURFACES = "showInSharingSurfaces"; private static final String ATTR_INHERIT_DEVICE_POLICY = "inheritDevicePolicy"; private static final String ATTR_USE_PARENTS_CONTACTS = "useParentsContacts"; private static final String ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA = "updateCrossProfileIntentFiltersOnOTA"; private static final String ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL = "crossProfileIntentFilterAccessControl"; private static final String ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY = "crossProfileIntentResolutionStrategy"; private static final String ATTR_MEDIA_SHARED_WITH_PARENT = "mediaSharedWithParent"; private static final String ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT = "credentialShareableWithParent"; private static final String ATTR_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE = "authAlwaysRequiredToDisableQuietMode"; private static final String ATTR_DELETE_APP_WITH_PARENT = "deleteAppWithParent"; private static final String ATTR_ALWAYS_VISIBLE = "alwaysVisible"; private static final String ATTR_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING = "allowStoppingUserWithDelayedLocking"; private static final String ATTR_CROSS_PROFILE_CONTENT_SHARING_STRATEGY = "crossProfileContentSharingStrategy"; private static final String ATTR_PROFILE_API_VISIBILITY = "profileApiVisibility"; private static final String ITEMS_RESTRICTED_ON_HOME_SCREEN = "itemsRestrictedOnHomeScreen"; /** 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, INDEX_INHERIT_DEVICE_POLICY, INDEX_USE_PARENTS_CONTACTS, INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA, INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL, INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY, INDEX_MEDIA_SHARED_WITH_PARENT, INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT, INDEX_DELETE_APP_WITH_PARENT, INDEX_ALWAYS_VISIBLE, INDEX_SHOW_IN_QUIET_MODE, INDEX_SHOW_IN_SHARING_SURFACES, INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE, INDEX_CROSS_PROFILE_CONTENT_SHARING_STRATEGY, INDEX_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING, INDEX_PROFILE_API_VISIBILITY, INDEX_ITEMS_RESTRICTED_ON_HOME_SCREEN }) @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; private static final int INDEX_INHERIT_DEVICE_POLICY = 3; private static final int INDEX_USE_PARENTS_CONTACTS = 4; private static final int INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA = 5; private static final int INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL = 6; private static final int INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY = 7; private static final int INDEX_MEDIA_SHARED_WITH_PARENT = 8; private static final int INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT = 9; private static final int INDEX_DELETE_APP_WITH_PARENT = 10; private static final int INDEX_ALWAYS_VISIBLE = 11; private static final int INDEX_SHOW_IN_QUIET_MODE = 12; private static final int INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE = 13; private static final int INDEX_SHOW_IN_SHARING_SURFACES = 14; private static final int INDEX_CROSS_PROFILE_CONTENT_SHARING_STRATEGY = 15; private static final int INDEX_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING = 16; private static final int INDEX_PROFILE_API_VISIBILITY = 17; private static final int INDEX_ITEMS_RESTRICTED_ON_HOME_SCREEN = 18; /** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */ private long mPropertiesPresent = 0; /** * Possible values for whether or how to show this user in the Launcher. * @hide */ @IntDef(prefix = "SHOW_IN_LAUNCHER_", value = { SHOW_IN_LAUNCHER_UNKNOWN, SHOW_IN_LAUNCHER_WITH_PARENT, SHOW_IN_LAUNCHER_SEPARATE, SHOW_IN_LAUNCHER_NO, }) @Retention(RetentionPolicy.SOURCE) public @interface ShowInLauncher { } /** * Indicates that the show in launcher value for this profile is unknown or unsupported. * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_LAUNCHER_UNKNOWN = -1; /** * Suggests that the launcher 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 */ @TestApi public static final int SHOW_IN_LAUNCHER_WITH_PARENT = 0; /** * Suggests that the launcher should show this user's apps, but separately from the apps of this * user's parent. * @hide */ @TestApi public static final int SHOW_IN_LAUNCHER_SEPARATE = 1; /** * Suggests that the launcher should not show this user. * @hide */ @TestApi 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_UNKNOWN, SHOW_IN_SETTINGS_WITH_PARENT, SHOW_IN_SETTINGS_SEPARATE, SHOW_IN_SETTINGS_NO, }) @Retention(RetentionPolicy.SOURCE) public @interface ShowInSettings { } /** * Indicates that the show in settings value for this profile is unknown or unsupported. * @hide */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_SETTINGS_UNKNOWN = -1; /** * 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; /** * Possible values for whether (and from whom) to inherit select user restrictions * or device policies. * * @hide */ @IntDef(prefix = "INHERIT_DEVICE_POLICY", value = { INHERIT_DEVICE_POLICY_NO, INHERIT_DEVICE_POLICY_FROM_PARENT, }) @Retention(RetentionPolicy.SOURCE) public @interface InheritDevicePolicy { } /** * Suggests that the given user profile should not inherit user restriction or device policy * from any other user. This is the default value for any new user type. * @hide */ public static final int INHERIT_DEVICE_POLICY_NO = 0; /** * Suggests that the given user profile should inherit select user restrictions or * device policies from its parent profile. * *

All the user restrictions and device policies would be not propagated to the profile * with this property value. The {@link com.android.server.devicepolicy.DevicePolicyEngine} * uses this property to determine and propagate only select ones to the given profile. * * @hide */ public static final int INHERIT_DEVICE_POLICY_FROM_PARENT = 1; /** * Reference to the default user properties for this user's user type. *

  • If non-null, then any absent property will use the default property from here instead. *
  • If null, then any absent property indicates that the caller lacks permission to see it, * so attempting to get that property will trigger a SecurityException. */ private final @Nullable UserProperties mDefaultProperties; /** * CrossProfileIntentFilterAccessControlLevel provides level of access for user to create/modify * {@link CrossProfileIntentFilter}. Each level have value assigned, the higher the value * implies higher restriction for creation/modification. * CrossProfileIntentFilterAccessControlLevel allows us to protect against malicious changes in * user's {@link CrossProfileIntentFilter}s, which might add/remove * {@link CrossProfileIntentFilter} leading to unprecedented results. * * @hide */ @IntDef(prefix = {"CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_"}, value = { CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL, CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM, CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY, }) @Retention(RetentionPolicy.SOURCE) public @interface CrossProfileIntentFilterAccessControlLevel { } /** * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL signifies that irrespective of user we would * allow access (addition/modification/removal) for CrossProfileIntentFilter. * This is the default access control level. * * @hide */ public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL = 0; /** * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM signifies that only system/root user would * be able to access (addition/modification/removal) CrossProfileIntentFilter. * * @hide */ public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM = 10; /** * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY signifies that only system/root * user would be able to add CrossProfileIntentFilter but not modify/remove. Once added, it * cannot be modified or removed. * * @hide */ public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY = 20; /** * Possible values for cross profile intent resolution strategy. * * @hide */ @IntDef(prefix = {"CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_"}, value = { CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT, CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING }) @Retention(RetentionPolicy.SOURCE) public @interface CrossProfileIntentResolutionStrategy { } /** * Signifies to use {@link DefaultCrossProfileResolver} strategy, which * check if it needs to skip the initiating profile, resolves intent in target profile. * {@link DefaultCrossProfileResolver} also filters the {@link ResolveInfo} after intent * resolution based on their domain approval level * * @hide */ public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT = 0; /** * Signifies that there is no need to filter {@link ResolveInfo} after cross profile intent * resolution across. This strategy is for profile acting transparent to end-user and resolves * all allowed intent without giving any profile priority. * * @hide */ public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING = 1; /** * Possible values for the profile visibility when in quiet mode. This affects the profile data * and apps surfacing in Settings, sharing surfaces, and file picker surfaces. It signifies * whether the profile data and apps will be shown or not. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "SHOW_IN_QUIET_MODE_", value = { SHOW_IN_QUIET_MODE_UNKNOWN, SHOW_IN_QUIET_MODE_PAUSED, SHOW_IN_QUIET_MODE_HIDDEN, SHOW_IN_QUIET_MODE_DEFAULT, } ) public @interface ShowInQuietMode { } /** * Indicates that the show in quiet mode value for this profile is unknown. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_QUIET_MODE_UNKNOWN = -1; /** * Indicates that the profile should still be visible in quiet mode but should be shown as * paused (e.g. by greying out its icons). */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_QUIET_MODE_PAUSED = 0; /** * Indicates that the profile should not be visible when the profile is in quiet mode. * For example, the profile should not be shown in tabbed views in Settings, files sharing * surfaces etc when in quiet mode. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_QUIET_MODE_HIDDEN = 1; /** * Indicates that quiet mode should not have any effect on the profile visibility. If the * profile is meant to be visible, it will remain visible and vice versa. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_QUIET_MODE_DEFAULT = 2; /** * Possible values for the profile apps visibility in sharing surfaces. This indicates the * profile data and apps should be shown in separate tabs or mixed with its parent user's data * and apps in sharing surfaces and file picker surfaces. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "SHOW_IN_SHARING_SURFACES_", value = { SHOW_IN_SHARING_SURFACES_UNKNOWN, SHOW_IN_SHARING_SURFACES_SEPARATE, SHOW_IN_SHARING_SURFACES_WITH_PARENT, SHOW_IN_SHARING_SURFACES_NO, } ) public @interface ShowInSharingSurfaces { } /** * Indicates that the show in launcher value for this profile is unknown or unsupported. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_SHARING_SURFACES_UNKNOWN = SHOW_IN_LAUNCHER_UNKNOWN; /** * Indicates that the profile data and apps should be shown in sharing surfaces intermixed with * parent user's data and apps. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_SHARING_SURFACES_WITH_PARENT = SHOW_IN_LAUNCHER_WITH_PARENT; /** * Indicates that the profile data and apps should be shown in sharing surfaces separate from * parent user's data and apps. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_SHARING_SURFACES_SEPARATE = SHOW_IN_LAUNCHER_SEPARATE; /** * Indicates that the profile data and apps should not be shown in sharing surfaces at all. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int SHOW_IN_SHARING_SURFACES_NO = SHOW_IN_LAUNCHER_NO; /** * Possible values for cross profile content sharing strategy for this profile. * * @hide */ @IntDef(prefix = {"CROSS_PROFILE_CONTENT_SHARING_"}, value = { CROSS_PROFILE_CONTENT_SHARING_UNKNOWN, CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION, CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT }) @Retention(RetentionPolicy.SOURCE) public @interface CrossProfileContentSharingStrategy { } /** * Signifies that cross-profile content sharing strategy, both to and from this profile, is * unknown/unsupported. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int CROSS_PROFILE_CONTENT_SHARING_UNKNOWN = -1; /** * Signifies that cross-profile content sharing strategy, both to and from this profile, should * not be delegated to any other user/profile. * For ex: * If this property is set for a profile, content sharing applications (such as Android * Sharesheet), should not delegate the decision to share content between that profile and * another profile to whether content sharing is allowed between any other profile/user related * to those profiles. They should instead decide, based upon whether content sharing is * specifically allowed between the two profiles in question. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION = 0; /** * Signifies that cross-profile content sharing strategy, both to and from this profile, should * be based upon the strategy used by the parent user of the profile. * For ex: * If this property is set for a profile A, content sharing applications (such as Android * Sharesheet), should share content between profile A and profile B, based upon whether content * sharing is allowed between the parent of profile A and profile B. * If it's also set for profile B, then decision should, in turn be made by considering content * sharing strategy between the parents of both profiles. */ @SuppressLint("UnflaggedApi") // b/306636213 public static final int CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT = 1; /** * Possible values for the profile visibility in public API surfaces. This indicates whether or * not the information linked to the profile (userId, package names) should not be returned in * API surfaces if a user is marked as hidden. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "PROFILE_API_VISIBILITY_", value = { PROFILE_API_VISIBILITY_UNKNOWN, PROFILE_API_VISIBILITY_VISIBLE, PROFILE_API_VISIBILITY_HIDDEN, } ) public @interface ProfileApiVisibility { } /** * The api visibility value for this profile user is undefined or unknown. * * @hide */ public static final int PROFILE_API_VISIBILITY_UNKNOWN = -1; /** * Indicates that information about this profile user should be shown in API surfaces. * * @hide */ public static final int PROFILE_API_VISIBILITY_VISIBLE = 0; /** * Indicates that information about this profile should be not be visible in API surfaces. * * @hide */ public static final int PROFILE_API_VISIBILITY_HIDDEN = 1; /** * Creates a UserProperties (intended for the SystemServer) that stores a reference to the given * default properties, which it uses for any property not subsequently set. * @hide */ public UserProperties(@NonNull UserProperties defaultProperties) { mDefaultProperties = defaultProperties; mPropertiesPresent = 0; } /** * Copies the given UserProperties, excluding any information that doesn't satisfy the specified * permissions. * Can only be used on the original version (one that won't throw on permission errors). * Note that, internally, this does not perform an exact copy. * @hide */ public UserProperties(UserProperties orig, boolean exposeAllFields, boolean hasManagePermission, boolean hasQueryOrManagePermission) { if (orig.mDefaultProperties == null) { throw new IllegalArgumentException("Attempting to copy a non-original UserProperties."); } this.mDefaultProperties = null; // Insert each setter into the following hierarchy based on its permission requirements. // NOTE: Copy each property using getters to ensure default values are copied if needed. if (exposeAllFields) { // Add items that require exposeAllFields to be true (strictest permission level). setStartWithParent(orig.getStartWithParent()); setInheritDevicePolicy(orig.getInheritDevicePolicy()); setUpdateCrossProfileIntentFiltersOnOTA(orig.getUpdateCrossProfileIntentFiltersOnOTA()); setCrossProfileIntentFilterAccessControl( orig.getCrossProfileIntentFilterAccessControl()); setCrossProfileIntentResolutionStrategy(orig.getCrossProfileIntentResolutionStrategy()); setDeleteAppWithParent(orig.getDeleteAppWithParent()); setAlwaysVisible(orig.getAlwaysVisible()); setAllowStoppingUserWithDelayedLocking(orig.getAllowStoppingUserWithDelayedLocking()); } if (hasManagePermission) { // Add items that require MANAGE_USERS or stronger. setShowInSettings(orig.getShowInSettings()); setUseParentsContacts(orig.getUseParentsContacts()); setAuthAlwaysRequiredToDisableQuietMode( orig.isAuthAlwaysRequiredToDisableQuietMode()); } if (hasQueryOrManagePermission) { // Add items that require QUERY_USERS or stronger. } // Add items that have no permission requirements at all. setShowInLauncher(orig.getShowInLauncher()); setMediaSharedWithParent(orig.isMediaSharedWithParent()); setCredentialShareableWithParent(orig.isCredentialShareableWithParent()); setShowInQuietMode(orig.getShowInQuietMode()); setShowInSharingSurfaces(orig.getShowInSharingSurfaces()); setCrossProfileContentSharingStrategy(orig.getCrossProfileContentSharingStrategy()); setProfileApiVisibility(orig.getProfileApiVisibility()); setItemsRestrictedOnHomeScreen(orig.areItemsRestrictedOnHomeScreen()); } /** * Indicates that the given property is being stored explicitly in this object. * If false, it means that either *
  • the default property for the user type should be used instead (for SystemServer callers) *
  • the caller lacks permission to see this property (for all other callers) */ private boolean isPresent(@PropertyIndex long index) { return (mPropertiesPresent & (1L << index)) != 0; } /** Indicates that the given property is henceforth being explicitly stored in this object. */ private void setPresent(@PropertyIndex long index) { mPropertiesPresent |= (1L << index); } /** @hide Returns the internal mPropertiesPresent value. Only for testing purposes. */ @VisibleForTesting public long getPropertiesPresent() { return mPropertiesPresent; } /** * Returns whether, and how, a user should be shown in the Launcher. * This is generally inapplicable for non-profile users. * * Possible return values include * {@link #SHOW_IN_LAUNCHER_WITH_PARENT}}, * {@link #SHOW_IN_LAUNCHER_SEPARATE}, * and {@link #SHOW_IN_LAUNCHER_NO}. * * @return whether, and how, a profile should be shown in the Launcher. * @hide */ @TestApi public @ShowInLauncher int getShowInLauncher() { if (isPresent(INDEX_SHOW_IN_LAUNCHER)) return mShowInLauncher; if (mDefaultProperties != null) return mDefaultProperties.mShowInLauncher; throw new SecurityException("You don't have permission to query showInLauncher"); } /** @hide */ public void setShowInLauncher(@ShowInLauncher int val) { this.mShowInLauncher = val; setPresent(INDEX_SHOW_IN_LAUNCHER); } private @ShowInLauncher int mShowInLauncher; /** * Returns whether, and how, a user should be shown in the Settings app. * This is generally inapplicable for non-profile users. * * Possible return values include * {@link #SHOW_IN_SETTINGS_WITH_PARENT}}, * {@link #SHOW_IN_SETTINGS_SEPARATE}, * and {@link #SHOW_IN_SETTINGS_NO}. * *

    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 user should be shown in the Settings and sharing surfaces depending on the * {@link android.os.UserManager#requestQuietModeEnabled(boolean, android.os.UserHandle) * quiet mode}. This is only applicable to profile users since the quiet mode concept is only * applicable to profile users. * *

    Please note that, in Settings, this property takes effect only if * {@link #getShowInSettings()} does not return {@link #SHOW_IN_SETTINGS_NO}. * Also note that in Sharing surfaces this property takes effect only if * {@link #getShowInSharingSurfaces()} does not return {@link #SHOW_IN_SHARING_SURFACES_NO}. * * @return One of {@link #SHOW_IN_QUIET_MODE_HIDDEN}, * {@link #SHOW_IN_QUIET_MODE_PAUSED}, or * {@link #SHOW_IN_QUIET_MODE_DEFAULT} depending on whether the profile should be * shown in quiet mode or not. */ @SuppressLint("UnflaggedApi") // b/306636213 public @ShowInQuietMode int getShowInQuietMode() { // NOTE: Launcher currently does not make use of this property. if (isPresent(INDEX_SHOW_IN_QUIET_MODE)) return mShowInQuietMode; if (mDefaultProperties != null) return mDefaultProperties.mShowInQuietMode; throw new SecurityException( "You don't have permission to query ShowInQuietMode"); } /** @hide */ public void setShowInQuietMode(@ShowInQuietMode int showInQuietMode) { this.mShowInQuietMode = showInQuietMode; setPresent(INDEX_SHOW_IN_QUIET_MODE); } private int mShowInQuietMode; /** * Returns whether a user's data and apps should be shown in sharing surfaces in a separate tab * or mixed with the parent user's data/apps. This is only applicable to profile users. * * @return One of {@link #SHOW_IN_SHARING_SURFACES_NO}, * {@link #SHOW_IN_SHARING_SURFACES_SEPARATE}, or * {@link #SHOW_IN_SHARING_SURFACES_WITH_PARENT} depending on whether the profile * should be shown separate from its parent's data, mixed with the parent's data, or * not shown at all. */ @SuppressLint("UnflaggedApi") // b/306636213 public @ShowInSharingSurfaces int getShowInSharingSurfaces() { if (isPresent(INDEX_SHOW_IN_SHARING_SURFACES)) return mShowInSharingSurfaces; if (mDefaultProperties != null) return mDefaultProperties.mShowInSharingSurfaces; throw new SecurityException( "You don't have permission to query ShowInSharingSurfaces"); } /** @hide */ public void setShowInSharingSurfaces(@ShowInSharingSurfaces int showInSharingSurfaces) { this.mShowInSharingSurfaces = showInSharingSurfaces; setPresent(INDEX_SHOW_IN_SHARING_SURFACES); } private int mShowInSharingSurfaces; /** * 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). * @hide */ public boolean getStartWithParent() { if (isPresent(INDEX_START_WITH_PARENT)) return mStartWithParent; if (mDefaultProperties != null) return mDefaultProperties.mStartWithParent; throw new SecurityException("You don't have permission to query startWithParent"); } /** @hide */ public void setStartWithParent(boolean val) { this.mStartWithParent = val; setPresent(INDEX_START_WITH_PARENT); } private boolean mStartWithParent; /** * Returns whether an app in the profile should be deleted when the same package in * the parent user is being deleted. * This only applies for users that have parents (i.e. for profiles). * @hide */ public boolean getDeleteAppWithParent() { if (isPresent(INDEX_DELETE_APP_WITH_PARENT)) return mDeleteAppWithParent; if (mDefaultProperties != null) return mDefaultProperties.mDeleteAppWithParent; throw new SecurityException("You don't have permission to query deleteAppWithParent"); } /** @hide */ public void setDeleteAppWithParent(boolean val) { this.mDeleteAppWithParent = val; setPresent(INDEX_DELETE_APP_WITH_PARENT); } private boolean mDeleteAppWithParent; /** * Returns whether the user should always * be {@link android.os.UserManager#isUserVisible() visible}. * The intended usage is for the Communal Profile, which is running and accessible at all times. * @hide */ public boolean getAlwaysVisible() { if (isPresent(INDEX_ALWAYS_VISIBLE)) return mAlwaysVisible; if (mDefaultProperties != null) return mDefaultProperties.mAlwaysVisible; throw new SecurityException("You don't have permission to query alwaysVisible"); } /** @hide */ public void setAlwaysVisible(boolean val) { this.mAlwaysVisible = val; setPresent(INDEX_ALWAYS_VISIBLE); } private boolean mAlwaysVisible; /** * Return whether, and how, select user restrictions or device policies should be inherited * from other user. * * Possible return values include * {@link #INHERIT_DEVICE_POLICY_FROM_PARENT} or {@link #INHERIT_DEVICE_POLICY_NO} * * @hide */ public @InheritDevicePolicy int getInheritDevicePolicy() { if (isPresent(INDEX_INHERIT_DEVICE_POLICY)) return mInheritDevicePolicy; if (mDefaultProperties != null) return mDefaultProperties.mInheritDevicePolicy; throw new SecurityException("You don't have permission to query inheritDevicePolicy"); } /** @hide */ public void setInheritDevicePolicy(@InheritDevicePolicy int val) { this.mInheritDevicePolicy = val; setPresent(INDEX_INHERIT_DEVICE_POLICY); } private @InheritDevicePolicy int mInheritDevicePolicy; /** * Returns whether the current user must use parent user's contacts. If true, writes to the * ContactsProvider corresponding to the current user will be disabled and reads will be * redirected to the parent. * * This only applies to users that have parents (i.e. profiles) and is used to ensure * they can access contacts from the parent profile. This will be generally inapplicable for * non-profile users. * * Please note that in case of the clone profiles, only the allow-listed apps would be allowed * to access contacts across profiles and other apps will not see any contacts. * TODO(b/256126819) Add link to the method returning apps allow-listed for app-cloning * * @return whether contacts access from an associated profile is enabled for the user * @hide */ public boolean getUseParentsContacts() { if (isPresent(INDEX_USE_PARENTS_CONTACTS)) return mUseParentsContacts; if (mDefaultProperties != null) return mDefaultProperties.mUseParentsContacts; throw new SecurityException("You don't have permission to query useParentsContacts"); } /** @hide */ public void setUseParentsContacts(boolean val) { this.mUseParentsContacts = val; setPresent(INDEX_USE_PARENTS_CONTACTS); } /** * Indicates whether the current user should use parent user's contacts. * If this property is set true, the user will be blocked from storing any contacts in its * own contacts database and will serve all read contacts calls through the parent's contacts. */ private boolean mUseParentsContacts; /** * Returns true if user needs to update default * {@link com.android.server.pm.CrossProfileIntentFilter} with its parents during an OTA update * @hide */ public boolean getUpdateCrossProfileIntentFiltersOnOTA() { if (isPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA)) { return mUpdateCrossProfileIntentFiltersOnOTA; } if (mDefaultProperties != null) { return mDefaultProperties.mUpdateCrossProfileIntentFiltersOnOTA; } throw new SecurityException("You don't have permission to query " + "updateCrossProfileIntentFiltersOnOTA"); } /** @hide */ public void setUpdateCrossProfileIntentFiltersOnOTA(boolean val) { this.mUpdateCrossProfileIntentFiltersOnOTA = val; setPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA); } /** Indicate if {@link com.android.server.pm.CrossProfileIntentFilter}s need to be updated during OTA update between user-parent */ private boolean mUpdateCrossProfileIntentFiltersOnOTA; /** * Returns whether a profile shares media with its parent user. * This only applies for users that have parents (i.e. for profiles). */ public boolean isMediaSharedWithParent() { if (isPresent(INDEX_MEDIA_SHARED_WITH_PARENT)) return mMediaSharedWithParent; if (mDefaultProperties != null) return mDefaultProperties.mMediaSharedWithParent; throw new SecurityException("You don't have permission to query mediaSharedWithParent"); } /** @hide */ public void setMediaSharedWithParent(boolean val) { this.mMediaSharedWithParent = val; setPresent(INDEX_MEDIA_SHARED_WITH_PARENT); } private boolean mMediaSharedWithParent; /** * Returns whether a profile can have shared lockscreen credential with its parent user. * This only applies for users that have parents (i.e. for profiles). */ public boolean isCredentialShareableWithParent() { if (isPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT)) { return mCredentialShareableWithParent; } if (mDefaultProperties != null) return mDefaultProperties.mCredentialShareableWithParent; throw new SecurityException( "You don't have permission to query credentialShareableWithParent"); } /** @hide */ public void setCredentialShareableWithParent(boolean val) { this.mCredentialShareableWithParent = val; setPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT); } private boolean mCredentialShareableWithParent; /** * Returns whether the profile always requires user authentication to disable from quiet mode. * *

    Settings this field to true will ensure that the credential confirmation activity is * always shown whenever the user requests to disable quiet mode. The behavior of credential * checks is not guaranteed when the property is false and may vary depending on user types. * @hide */ public boolean isAuthAlwaysRequiredToDisableQuietMode() { if (isPresent(INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE)) { return mAuthAlwaysRequiredToDisableQuietMode; } if (mDefaultProperties != null) { return mDefaultProperties.mAuthAlwaysRequiredToDisableQuietMode; } throw new SecurityException( "You don't have permission to query authAlwaysRequiredToDisableQuietMode"); } /** @hide */ public void setAuthAlwaysRequiredToDisableQuietMode(boolean val) { this.mAuthAlwaysRequiredToDisableQuietMode = val; setPresent(INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE); } private boolean mAuthAlwaysRequiredToDisableQuietMode; /** * Returns whether a user (usually a profile) is allowed to leave the CE storage unlocked when * stopped. * *

    Setting this property to true will enable the user's CE storage to remain unlocked when * the user is stopped using * {@link com.android.server.am.ActivityManagerService#stopUserWithDelayedLocking(int, * IStopUserCallback)}. * *

    When this property is false, delayed locking may still be applicable at a global * level for all users via the {@code config_multiuserDelayUserDataLocking}. That is, delayed * locking for a user can happen if either the device configuration is set or if this property * is set. When both, the config and the property value is false, the user storage is always * locked when the user is stopped. * @hide */ public boolean getAllowStoppingUserWithDelayedLocking() { if (isPresent(INDEX_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING)) { return mAllowStoppingUserWithDelayedLocking; } if (mDefaultProperties != null) { return mDefaultProperties.mAllowStoppingUserWithDelayedLocking; } throw new SecurityException( "You don't have permission to query allowStoppingUserWithDelayedLocking"); } /** @hide */ public void setAllowStoppingUserWithDelayedLocking(boolean val) { this.mAllowStoppingUserWithDelayedLocking = val; setPresent(INDEX_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING); } private boolean mAllowStoppingUserWithDelayedLocking; /** * Returns the user's {@link CrossProfileIntentFilterAccessControlLevel}. * @hide */ public @CrossProfileIntentFilterAccessControlLevel int getCrossProfileIntentFilterAccessControl() { if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) { return mCrossProfileIntentFilterAccessControl; } if (mDefaultProperties != null) { return mDefaultProperties.mCrossProfileIntentFilterAccessControl; } throw new SecurityException("You don't have permission to query " + "crossProfileIntentFilterAccessControl"); } /** * Sets {@link CrossProfileIntentFilterAccessControlLevel} for the user. * @param val access control for user * @hide */ public void setCrossProfileIntentFilterAccessControl( @CrossProfileIntentFilterAccessControlLevel int val) { this.mCrossProfileIntentFilterAccessControl = val; setPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL); } private @CrossProfileIntentFilterAccessControlLevel int mCrossProfileIntentFilterAccessControl; /** * Returns the user's {@link CrossProfileIntentResolutionStrategy}. * @return user's {@link CrossProfileIntentResolutionStrategy}. * * @hide */ public @CrossProfileIntentResolutionStrategy int getCrossProfileIntentResolutionStrategy() { if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) { return mCrossProfileIntentResolutionStrategy; } if (mDefaultProperties != null) { return mDefaultProperties.mCrossProfileIntentResolutionStrategy; } throw new SecurityException("You don't have permission to query " + "crossProfileIntentResolutionStrategy"); } /** @hide */ public void setCrossProfileIntentResolutionStrategy( @CrossProfileIntentResolutionStrategy int val) { this.mCrossProfileIntentResolutionStrategy = val; setPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY); } private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy; /** * Returns the user's {@link CrossProfileContentSharingStrategy}. * * Content sharing applications, such as Android Sharesheet allow sharing of content * (an image, for ex.) between profiles, based upon cross-profile access checks between the * originating and destined profile. * In some cases however, we may want another user (such as profile parent) to serve as the * delegated user to be used for such checks. * To effect the same, clients can fetch this property and accordingly replace the * originating/destined profile by another user for cross-profile access checks. * * @return user's {@link CrossProfileContentSharingStrategy}. */ @SuppressLint("UnflaggedApi") // b/306636213 public @CrossProfileContentSharingStrategy int getCrossProfileContentSharingStrategy() { if (isPresent(INDEX_CROSS_PROFILE_CONTENT_SHARING_STRATEGY)) { return mCrossProfileContentSharingStrategy; } if (mDefaultProperties != null) { return mDefaultProperties.mCrossProfileContentSharingStrategy; } throw new SecurityException("You don't have permission to query " + "crossProfileContentSharingStrategy"); } /** @hide */ public void setCrossProfileContentSharingStrategy( @CrossProfileContentSharingStrategy int val) { this.mCrossProfileContentSharingStrategy = val; setPresent(INDEX_CROSS_PROFILE_CONTENT_SHARING_STRATEGY); } private @CrossProfileContentSharingStrategy int mCrossProfileContentSharingStrategy; /** * Returns the visibility of the profile user in API surfaces. Any information linked to the * profile (userId, package names) should be hidden API surfaces if a user is marked as hidden. * * @hide */ @NonNull public @ProfileApiVisibility int getProfileApiVisibility() { if (isPresent(INDEX_PROFILE_API_VISIBILITY)) return mProfileApiVisibility; if (mDefaultProperties != null) return mDefaultProperties.mProfileApiVisibility; throw new SecurityException("You don't have permission to query profileApiVisibility"); } /** @hide */ @NonNull public void setProfileApiVisibility(@ProfileApiVisibility int profileApiVisibility) { this.mProfileApiVisibility = profileApiVisibility; setPresent(INDEX_PROFILE_API_VISIBILITY); } private @ProfileApiVisibility int mProfileApiVisibility; /** * Returns whether a user (usually a profile) is allowed to have items such as Apps Pending * Installation, Widgets, Custom App Shortcuts, etc. on Launcher home screen. * *

    For a typical user/profile, this property will be false, allowing framework APIs to * provide information about such items to Launcher(s). When set true, framework APIs will * restrict the same. * *

    This property only restricts information about items that are accessed solely via the * Launcher home screen. Information about items such as App Icons, Deep Links, which can also * be accessed via other launcher components, such as All Apps Drawer is not restricted by this * property. * * @hide */ public boolean areItemsRestrictedOnHomeScreen() { if (isPresent(INDEX_ITEMS_RESTRICTED_ON_HOME_SCREEN)) { return mItemsRestrictedOnHomeScreen; } if (mDefaultProperties != null) { return mDefaultProperties.mItemsRestrictedOnHomeScreen; } throw new SecurityException( "You don't have permission to query mItemsRestrictedOnHomeScreen"); } /** @hide */ public void setItemsRestrictedOnHomeScreen(boolean val) { this.mItemsRestrictedOnHomeScreen = val; setPresent(INDEX_ITEMS_RESTRICTED_ON_HOME_SCREEN); } private boolean mItemsRestrictedOnHomeScreen; @Override public String toString() { // Please print in increasing order of PropertyIndex. return "UserProperties{" + "mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent) + ", mShowInLauncher=" + getShowInLauncher() + ", mStartWithParent=" + getStartWithParent() + ", mShowInSettings=" + getShowInSettings() + ", mInheritDevicePolicy=" + getInheritDevicePolicy() + ", mUseParentsContacts=" + getUseParentsContacts() + ", mUpdateCrossProfileIntentFiltersOnOTA=" + getUpdateCrossProfileIntentFiltersOnOTA() + ", mCrossProfileIntentFilterAccessControl=" + getCrossProfileIntentFilterAccessControl() + ", mCrossProfileIntentResolutionStrategy=" + getCrossProfileIntentResolutionStrategy() + ", mMediaSharedWithParent=" + isMediaSharedWithParent() + ", mCredentialShareableWithParent=" + isCredentialShareableWithParent() + ", mAuthAlwaysRequiredToDisableQuietMode=" + isAuthAlwaysRequiredToDisableQuietMode() + ", mAllowStoppingUserWithDelayedLocking=" + getAllowStoppingUserWithDelayedLocking() + ", mDeleteAppWithParent=" + getDeleteAppWithParent() + ", mAlwaysVisible=" + getAlwaysVisible() + ", mCrossProfileContentSharingStrategy=" + getCrossProfileContentSharingStrategy() + ", mProfileApiVisibility=" + getProfileApiVisibility() + ", mItemsRestrictedOnHomeScreen=" + areItemsRestrictedOnHomeScreen() + "}"; } /** * Print the UserProperties to the given PrintWriter. * @hide */ public void println(PrintWriter pw, String prefix) { // Please print in increasing order of PropertyIndex. pw.println(prefix + "UserProperties:"); pw.println(prefix + " mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent)); pw.println(prefix + " mShowInLauncher=" + getShowInLauncher()); pw.println(prefix + " mStartWithParent=" + getStartWithParent()); pw.println(prefix + " mShowInSettings=" + getShowInSettings()); pw.println(prefix + " mInheritDevicePolicy=" + getInheritDevicePolicy()); pw.println(prefix + " mUseParentsContacts=" + getUseParentsContacts()); pw.println(prefix + " mUpdateCrossProfileIntentFiltersOnOTA=" + getUpdateCrossProfileIntentFiltersOnOTA()); pw.println(prefix + " mCrossProfileIntentFilterAccessControl=" + getCrossProfileIntentFilterAccessControl()); pw.println(prefix + " mCrossProfileIntentResolutionStrategy=" + getCrossProfileIntentResolutionStrategy()); pw.println(prefix + " mMediaSharedWithParent=" + isMediaSharedWithParent()); pw.println(prefix + " mCredentialShareableWithParent=" + isCredentialShareableWithParent()); pw.println(prefix + " mAuthAlwaysRequiredToDisableQuietMode=" + isAuthAlwaysRequiredToDisableQuietMode()); pw.println(prefix + " mAllowStoppingUserWithDelayedLocking=" + getAllowStoppingUserWithDelayedLocking()); pw.println(prefix + " mDeleteAppWithParent=" + getDeleteAppWithParent()); pw.println(prefix + " mAlwaysVisible=" + getAlwaysVisible()); pw.println(prefix + " mCrossProfileContentSharingStrategy=" + getCrossProfileContentSharingStrategy()); pw.println(prefix + " mProfileApiVisibility=" + getProfileApiVisibility()); pw.println(prefix + " mItemsRestrictedOnHomeScreen=" + areItemsRestrictedOnHomeScreen()); } /** * Reads in a UserProperties from an xml file, for use by the SystemServer. * * The serializer should already be inside a tag from which to read the user properties. * * @param defaultUserPropertiesReference the default UserProperties to use for this user type. * @see #writeToXml * @hide */ public UserProperties( TypedXmlPullParser parser, @NonNull UserProperties defaultUserPropertiesReference) throws IOException, XmlPullParserException { this(defaultUserPropertiesReference); updateFromXml(parser); } /** * Parses the given xml file and updates this UserProperties with its data. * I.e., if a piece of data is present in the xml, it will overwrite whatever was * previously stored in this UserProperties. * @hide */ public void updateFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException { final int attributeCount = parser.getAttributeCount(); for (int i = 0; i < attributeCount; i++) { final String attributeName = parser.getAttributeName(i); switch(attributeName) { case ATTR_SHOW_IN_LAUNCHER: setShowInLauncher(parser.getAttributeInt(i)); break; case ATTR_START_WITH_PARENT: setStartWithParent(parser.getAttributeBoolean(i)); break; case ATTR_SHOW_IN_SETTINGS: setShowInSettings(parser.getAttributeInt(i)); break; case ATTR_SHOW_IN_QUIET_MODE: setShowInQuietMode(parser.getAttributeInt(i)); break; case ATTR_SHOW_IN_SHARING_SURFACES: setShowInSharingSurfaces(parser.getAttributeInt(i)); break; case ATTR_INHERIT_DEVICE_POLICY: setInheritDevicePolicy(parser.getAttributeInt(i)); break; case ATTR_USE_PARENTS_CONTACTS: setUseParentsContacts(parser.getAttributeBoolean(i)); break; case ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA: setUpdateCrossProfileIntentFiltersOnOTA(parser.getAttributeBoolean(i)); break; case ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL: setCrossProfileIntentFilterAccessControl(parser.getAttributeInt(i)); break; case ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY: setCrossProfileIntentResolutionStrategy(parser.getAttributeInt(i)); break; case ATTR_MEDIA_SHARED_WITH_PARENT: setMediaSharedWithParent(parser.getAttributeBoolean(i)); break; case ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT: setCredentialShareableWithParent(parser.getAttributeBoolean(i)); break; case ATTR_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE: setAuthAlwaysRequiredToDisableQuietMode(parser.getAttributeBoolean(i)); break; case ATTR_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING: setAllowStoppingUserWithDelayedLocking(parser.getAttributeBoolean(i)); break; case ATTR_DELETE_APP_WITH_PARENT: setDeleteAppWithParent(parser.getAttributeBoolean(i)); break; case ATTR_ALWAYS_VISIBLE: setAlwaysVisible(parser.getAttributeBoolean(i)); break; case ATTR_CROSS_PROFILE_CONTENT_SHARING_STRATEGY: setCrossProfileContentSharingStrategy(parser.getAttributeInt(i)); break; case ATTR_PROFILE_API_VISIBILITY: setProfileApiVisibility(parser.getAttributeInt(i)); break; case ITEMS_RESTRICTED_ON_HOME_SCREEN: setItemsRestrictedOnHomeScreen(parser.getAttributeBoolean(i)); break; default: Slog.w(LOG_TAG, "Skipping unknown property " + attributeName); } } } /** * Writes the UserProperties, as used by the SystemServer, to the xml file. * * The serializer should already be inside a tag in which to write the user properties. * * @see #UserProperties(TypedXmlPullParser, UserProperties) * @hide */ public void writeToXml(TypedXmlSerializer serializer) throws IOException, XmlPullParserException { if (isPresent(INDEX_SHOW_IN_LAUNCHER)) { serializer.attributeInt(null, ATTR_SHOW_IN_LAUNCHER, mShowInLauncher); } 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); } if (isPresent(INDEX_SHOW_IN_QUIET_MODE)) { serializer.attributeInt(null, ATTR_SHOW_IN_QUIET_MODE, mShowInQuietMode); } if (isPresent(INDEX_SHOW_IN_SHARING_SURFACES)) { serializer.attributeInt(null, ATTR_SHOW_IN_SHARING_SURFACES, mShowInSharingSurfaces); } if (isPresent(INDEX_INHERIT_DEVICE_POLICY)) { serializer.attributeInt(null, ATTR_INHERIT_DEVICE_POLICY, mInheritDevicePolicy); } if (isPresent(INDEX_USE_PARENTS_CONTACTS)) { serializer.attributeBoolean(null, ATTR_USE_PARENTS_CONTACTS, mUseParentsContacts); } if (isPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA)) { serializer.attributeBoolean(null, ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA, mUpdateCrossProfileIntentFiltersOnOTA); } if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) { serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL, mCrossProfileIntentFilterAccessControl); } if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) { serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY, mCrossProfileIntentResolutionStrategy); } if (isPresent(INDEX_MEDIA_SHARED_WITH_PARENT)) { serializer.attributeBoolean(null, ATTR_MEDIA_SHARED_WITH_PARENT, mMediaSharedWithParent); } if (isPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT)) { serializer.attributeBoolean(null, ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT, mCredentialShareableWithParent); } if (isPresent(INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE)) { serializer.attributeBoolean(null, ATTR_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE, mAuthAlwaysRequiredToDisableQuietMode); } if (isPresent(INDEX_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING)) { serializer.attributeBoolean(null, ATTR_ALLOW_STOPPING_USER_WITH_DELAYED_LOCKING, mAllowStoppingUserWithDelayedLocking); } if (isPresent(INDEX_DELETE_APP_WITH_PARENT)) { serializer.attributeBoolean(null, ATTR_DELETE_APP_WITH_PARENT, mDeleteAppWithParent); } if (isPresent(INDEX_ALWAYS_VISIBLE)) { serializer.attributeBoolean(null, ATTR_ALWAYS_VISIBLE, mAlwaysVisible); } if (isPresent(INDEX_CROSS_PROFILE_CONTENT_SHARING_STRATEGY)) { serializer.attributeInt(null, ATTR_CROSS_PROFILE_CONTENT_SHARING_STRATEGY, mCrossProfileContentSharingStrategy); } if (isPresent(INDEX_PROFILE_API_VISIBILITY)) { serializer.attributeInt(null, ATTR_PROFILE_API_VISIBILITY, mProfileApiVisibility); } if (isPresent(INDEX_ITEMS_RESTRICTED_ON_HOME_SCREEN)) { serializer.attributeBoolean(null, ITEMS_RESTRICTED_ON_HOME_SCREEN, mItemsRestrictedOnHomeScreen); } } // For use only with an object that has already had any permission-lacking fields stripped out. @Override public void writeToParcel(@NonNull Parcel dest, int parcelableFlags) { dest.writeLong(mPropertiesPresent); dest.writeInt(mShowInLauncher); dest.writeBoolean(mStartWithParent); dest.writeInt(mShowInSettings); dest.writeInt(mShowInQuietMode); dest.writeInt(mShowInSharingSurfaces); dest.writeInt(mInheritDevicePolicy); dest.writeBoolean(mUseParentsContacts); dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA); dest.writeInt(mCrossProfileIntentFilterAccessControl); dest.writeInt(mCrossProfileIntentResolutionStrategy); dest.writeBoolean(mMediaSharedWithParent); dest.writeBoolean(mCredentialShareableWithParent); dest.writeBoolean(mAuthAlwaysRequiredToDisableQuietMode); dest.writeBoolean(mAllowStoppingUserWithDelayedLocking); dest.writeBoolean(mDeleteAppWithParent); dest.writeBoolean(mAlwaysVisible); dest.writeInt(mCrossProfileContentSharingStrategy); dest.writeInt(mProfileApiVisibility); dest.writeBoolean(mItemsRestrictedOnHomeScreen); } /** * Reads a UserProperties object from the parcel. * Not suitable for the canonical SystemServer version since it lacks mDefaultProperties. */ private UserProperties(@NonNull Parcel source) { mDefaultProperties = null; mPropertiesPresent = source.readLong(); mShowInLauncher = source.readInt(); mStartWithParent = source.readBoolean(); mShowInSettings = source.readInt(); mShowInQuietMode = source.readInt(); mShowInSharingSurfaces = source.readInt(); mInheritDevicePolicy = source.readInt(); mUseParentsContacts = source.readBoolean(); mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean(); mCrossProfileIntentFilterAccessControl = source.readInt(); mCrossProfileIntentResolutionStrategy = source.readInt(); mMediaSharedWithParent = source.readBoolean(); mCredentialShareableWithParent = source.readBoolean(); mAuthAlwaysRequiredToDisableQuietMode = source.readBoolean(); mAllowStoppingUserWithDelayedLocking = source.readBoolean(); mDeleteAppWithParent = source.readBoolean(); mAlwaysVisible = source.readBoolean(); mCrossProfileContentSharingStrategy = source.readInt(); mProfileApiVisibility = source.readInt(); mItemsRestrictedOnHomeScreen = source.readBoolean(); } @Override public int describeContents() { return 0; } public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { public UserProperties createFromParcel(Parcel source) { return new UserProperties(source); } public UserProperties[] newArray(int size) { return new UserProperties[size]; } }; /** * Builder for the SystemServer's {@link UserProperties}; see that class for documentation. * Intended for building default values (and so all properties are present in the built object). * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 public static final class Builder { // 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; private @ShowInQuietMode int mShowInQuietMode = SHOW_IN_QUIET_MODE_PAUSED; private @ShowInSharingSurfaces int mShowInSharingSurfaces = SHOW_IN_SHARING_SURFACES_SEPARATE; private @InheritDevicePolicy int mInheritDevicePolicy = INHERIT_DEVICE_POLICY_NO; private boolean mUseParentsContacts = false; private boolean mUpdateCrossProfileIntentFiltersOnOTA = false; private @CrossProfileIntentFilterAccessControlLevel int mCrossProfileIntentFilterAccessControl = CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL; private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy = CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT; private boolean mMediaSharedWithParent = false; private boolean mCredentialShareableWithParent = false; private boolean mAuthAlwaysRequiredToDisableQuietMode = false; private boolean mAllowStoppingUserWithDelayedLocking = false; private boolean mDeleteAppWithParent = false; private boolean mAlwaysVisible = false; private @CrossProfileContentSharingStrategy int mCrossProfileContentSharingStrategy = CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION; private @ProfileApiVisibility int mProfileApiVisibility = 0; private boolean mItemsRestrictedOnHomeScreen = false; /** * @hide */ @SuppressLint("UnflaggedApi") // b/306636213 @TestApi public Builder() {} /** @hide */ public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) { mShowInLauncher = showInLauncher; return this; } /** @hide */ public Builder setStartWithParent(boolean startWithParent) { mStartWithParent = startWithParent; return this; } /** Sets the value for {@link #mShowInSettings} * @hide */ public Builder setShowInSettings(@ShowInSettings int showInSettings) { mShowInSettings = showInSettings; return this; } /** Sets the value for {@link #mShowInQuietMode} * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 @NonNull public Builder setShowInQuietMode(@ShowInQuietMode int showInQuietMode) { mShowInQuietMode = showInQuietMode; return this; } /** Sets the value for {@link #mShowInSharingSurfaces}. * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 @NonNull public Builder setShowInSharingSurfaces(@ShowInSharingSurfaces int showInSharingSurfaces) { mShowInSharingSurfaces = showInSharingSurfaces; return this; } /** Sets the value for {@link #mInheritDevicePolicy} * @hide */ public Builder setInheritDevicePolicy( @InheritDevicePolicy int inheritRestrictionsDevicePolicy) { mInheritDevicePolicy = inheritRestrictionsDevicePolicy; return this; } /** @hide */ public Builder setUseParentsContacts(boolean useParentsContacts) { mUseParentsContacts = useParentsContacts; return this; } /** Sets the value for {@link #mUpdateCrossProfileIntentFiltersOnOTA} * @hide */ public Builder setUpdateCrossProfileIntentFiltersOnOTA(boolean updateCrossProfileIntentFiltersOnOTA) { mUpdateCrossProfileIntentFiltersOnOTA = updateCrossProfileIntentFiltersOnOTA; return this; } /** Sets the value for {@link #mCrossProfileIntentFilterAccessControl} * @hide */ public Builder setCrossProfileIntentFilterAccessControl( @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl) { mCrossProfileIntentFilterAccessControl = crossProfileIntentFilterAccessControl; return this; } /** Sets the value for {@link #mCrossProfileIntentResolutionStrategy} * @hide */ public Builder setCrossProfileIntentResolutionStrategy(@CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy) { mCrossProfileIntentResolutionStrategy = crossProfileIntentResolutionStrategy; return this; } /** @hide */ public Builder setMediaSharedWithParent(boolean mediaSharedWithParent) { mMediaSharedWithParent = mediaSharedWithParent; return this; } /** @hide */ public Builder setCredentialShareableWithParent(boolean credentialShareableWithParent) { mCredentialShareableWithParent = credentialShareableWithParent; return this; } /** Sets the value for {@link #mAuthAlwaysRequiredToDisableQuietMode} * @hide */ public Builder setAuthAlwaysRequiredToDisableQuietMode( boolean authAlwaysRequiredToDisableQuietMode) { mAuthAlwaysRequiredToDisableQuietMode = authAlwaysRequiredToDisableQuietMode; return this; } /** Sets the value for {@link #mAllowStoppingUserWithDelayedLocking} * @hide */ public Builder setAllowStoppingUserWithDelayedLocking( boolean allowStoppingUserWithDelayedLocking) { mAllowStoppingUserWithDelayedLocking = allowStoppingUserWithDelayedLocking; return this; } /** Sets the value for {@link #mDeleteAppWithParent} * @hide */ public Builder setDeleteAppWithParent(boolean deleteAppWithParent) { mDeleteAppWithParent = deleteAppWithParent; return this; } /** Sets the value for {@link #mAlwaysVisible} * @hide */ public Builder setAlwaysVisible(boolean alwaysVisible) { mAlwaysVisible = alwaysVisible; return this; } /** Sets the value for {@link #mCrossProfileContentSharingStrategy} * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 @NonNull public Builder setCrossProfileContentSharingStrategy(@CrossProfileContentSharingStrategy int crossProfileContentSharingStrategy) { mCrossProfileContentSharingStrategy = crossProfileContentSharingStrategy; return this; } /** * Sets the value for {@link #mProfileApiVisibility} * @hide */ @NonNull public Builder setProfileApiVisibility(@ProfileApiVisibility int profileApiVisibility){ mProfileApiVisibility = profileApiVisibility; return this; } /** Sets the value for {@link #mItemsRestrictedOnHomeScreen} * @hide */ public Builder setItemsRestrictedOnHomeScreen( boolean itemsRestrictedOnHomeScreen) { mItemsRestrictedOnHomeScreen = itemsRestrictedOnHomeScreen; return this; } /** Builds a UserProperties object with *all* values populated. * @hide */ @TestApi @SuppressLint("UnflaggedApi") // b/306636213 @NonNull public UserProperties build() { return new UserProperties( mShowInLauncher, mStartWithParent, mShowInSettings, mShowInQuietMode, mShowInSharingSurfaces, mInheritDevicePolicy, mUseParentsContacts, mUpdateCrossProfileIntentFiltersOnOTA, mCrossProfileIntentFilterAccessControl, mCrossProfileIntentResolutionStrategy, mMediaSharedWithParent, mCredentialShareableWithParent, mAuthAlwaysRequiredToDisableQuietMode, mAllowStoppingUserWithDelayedLocking, mDeleteAppWithParent, mAlwaysVisible, mCrossProfileContentSharingStrategy, mProfileApiVisibility, mItemsRestrictedOnHomeScreen); } } // end Builder /** Creates a UserProperties with the given properties. Intended for building default values. */ private UserProperties( @ShowInLauncher int showInLauncher, boolean startWithParent, @ShowInSettings int showInSettings, @ShowInQuietMode int showInQuietMode, @ShowInSharingSurfaces int showInSharingSurfaces, @InheritDevicePolicy int inheritDevicePolicy, boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA, @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl, @CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy, boolean mediaSharedWithParent, boolean credentialShareableWithParent, boolean authAlwaysRequiredToDisableQuietMode, boolean allowStoppingUserWithDelayedLocking, boolean deleteAppWithParent, boolean alwaysVisible, @CrossProfileContentSharingStrategy int crossProfileContentSharingStrategy, @ProfileApiVisibility int profileApiVisibility, boolean itemsRestrictedOnHomeScreen) { mDefaultProperties = null; setShowInLauncher(showInLauncher); setStartWithParent(startWithParent); setShowInSettings(showInSettings); setShowInQuietMode(showInQuietMode); setShowInSharingSurfaces(showInSharingSurfaces); setInheritDevicePolicy(inheritDevicePolicy); setUseParentsContacts(useParentsContacts); setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA); setCrossProfileIntentFilterAccessControl(crossProfileIntentFilterAccessControl); setCrossProfileIntentResolutionStrategy(crossProfileIntentResolutionStrategy); setMediaSharedWithParent(mediaSharedWithParent); setCredentialShareableWithParent(credentialShareableWithParent); setAuthAlwaysRequiredToDisableQuietMode( authAlwaysRequiredToDisableQuietMode); setAllowStoppingUserWithDelayedLocking(allowStoppingUserWithDelayedLocking); setDeleteAppWithParent(deleteAppWithParent); setAlwaysVisible(alwaysVisible); setCrossProfileContentSharingStrategy(crossProfileContentSharingStrategy); setProfileApiVisibility(profileApiVisibility); setItemsRestrictedOnHomeScreen(itemsRestrictedOnHomeScreen); } }