/* * 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. *
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