blob: 77b1954c0f1bade92f1d72ae7836797674685f8b [file] [log] [blame]
/*
* 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.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_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_DELETE_APP_WITH_PARENT = "deleteAppWithParent";
/** 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,
})
@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;
/** 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_WITH_PARENT,
SHOW_IN_LAUNCHER_SEPARATE,
SHOW_IN_LAUNCHER_NO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShowInLauncher {
}
/**
* 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_WITH_PARENT,
SHOW_IN_SETTINGS_SEPARATE,
SHOW_IN_SETTINGS_NO,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShowInSettings {
}
/**
* Suggests that the Settings app should show this user's apps in the main tab.
* That is, either this user is a full user, so its apps should be presented accordingly, or, if
* this user is a profile, then its apps should be shown alongside its parent's apps.
* @hide
*/
public static final int SHOW_IN_SETTINGS_WITH_PARENT = 0;
/**
* Suggests that the Settings app should show this user's apps, but separately from the apps of
* this user's parent.
* @hide
*/
public static final int SHOW_IN_SETTINGS_SEPARATE = 1;
/**
* Suggests that the Settings app should not show this user.
* @hide
*/
public static final int SHOW_IN_SETTINGS_NO = 2;
/**
* 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.
*
*<p> All the user restrictions and device policies would be not propagated to the profile
* with this property value. The {(TODO:b/256978256) @link 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.
* <li>If non-null, then any absent property will use the default property from here instead.
* <li>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;
/**
* 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());
}
if (hasManagePermission) {
// Add items that require MANAGE_USERS or stronger.
setShowInSettings(orig.getShowInSettings());
setUseParentsContacts(orig.getUseParentsContacts());
}
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());
}
/**
* Indicates that the given property is being stored explicitly in this object.
* If false, it means that either
* <li>the default property for the user type should be used instead (for SystemServer callers)
* <li>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}.
*
* <p> The caller must have {@link android.Manifest.permission#MANAGE_USERS} to query this
* property.
*
* @return whether, and how, a profile should be shown in the Settings.
* @hide
*/
public @ShowInSettings int getShowInSettings() {
if (isPresent(INDEX_SHOW_IN_SETTINGS)) return mShowInSettings;
if (mDefaultProperties != null) return mDefaultProperties.mShowInSettings;
throw new SecurityException("You don't have permission to query mShowInSettings");
}
/** @hide */
public void setShowInSettings(@ShowInSettings int val) {
this.mShowInSettings = val;
setPresent(INDEX_SHOW_IN_SETTINGS);
}
private @ShowInSettings int mShowInSettings;
/**
* Returns whether a profile should be started when its parent starts (unless in quiet mode).
* This only applies for users that have parents (i.e. for profiles).
* @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;
/**
* 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);
}
/**
* 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;
/*
Indicate if {@link com.android.server.pm.CrossProfileIntentFilter}s need to be updated during
OTA update between user-parent
*/
private boolean mUpdateCrossProfileIntentFiltersOnOTA;
/**
* 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}. If not explicitly
* configured, default value is {@link #CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT}.
* @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");
}
/**
* Sets {@link CrossProfileIntentResolutionStrategy} for the user.
* @param val resolution strategy for user
* @hide
*/
public void setCrossProfileIntentResolutionStrategy(
@CrossProfileIntentResolutionStrategy int val) {
this.mCrossProfileIntentResolutionStrategy = val;
setPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY);
}
private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy;
@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()
+ ", mDeleteAppWithParent=" + getDeleteAppWithParent()
+ "}";
}
/**
* 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 + " mDeleteAppWithParent=" + getDeleteAppWithParent());
}
/**
* 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_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_DELETE_APP_WITH_PARENT:
setDeleteAppWithParent(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_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_DELETE_APP_WITH_PARENT)) {
serializer.attributeBoolean(null, ATTR_DELETE_APP_WITH_PARENT,
mDeleteAppWithParent);
}
}
// 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(mInheritDevicePolicy);
dest.writeBoolean(mUseParentsContacts);
dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA);
dest.writeInt(mCrossProfileIntentFilterAccessControl);
dest.writeInt(mCrossProfileIntentResolutionStrategy);
dest.writeBoolean(mMediaSharedWithParent);
dest.writeBoolean(mCredentialShareableWithParent);
dest.writeBoolean(mDeleteAppWithParent);
}
/**
* 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();
mInheritDevicePolicy = source.readInt();
mUseParentsContacts = source.readBoolean();
mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean();
mCrossProfileIntentFilterAccessControl = source.readInt();
mCrossProfileIntentResolutionStrategy = source.readInt();
mMediaSharedWithParent = source.readBoolean();
mCredentialShareableWithParent = source.readBoolean();
mDeleteAppWithParent = source.readBoolean();
}
@Override
public int describeContents() {
return 0;
}
public static final @android.annotation.NonNull Parcelable.Creator<UserProperties> CREATOR
= new Parcelable.Creator<UserProperties>() {
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
*/
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 @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 mDeleteAppWithParent = false;
public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) {
mShowInLauncher = showInLauncher;
return this;
}
public Builder setStartWithParent(boolean startWithParent) {
mStartWithParent = startWithParent;
return this;
}
/** Sets the value for {@link #mShowInSettings} */
public Builder setShowInSettings(@ShowInSettings int showInSettings) {
mShowInSettings = showInSettings;
return this;
}
/** Sets the value for {@link #mInheritDevicePolicy}*/
public Builder setInheritDevicePolicy(
@InheritDevicePolicy int inheritRestrictionsDevicePolicy) {
mInheritDevicePolicy = inheritRestrictionsDevicePolicy;
return this;
}
public Builder setUseParentsContacts(boolean useParentsContacts) {
mUseParentsContacts = useParentsContacts;
return this;
}
/** Sets the value for {@link #mUpdateCrossProfileIntentFiltersOnOTA} */
public Builder setUpdateCrossProfileIntentFiltersOnOTA(boolean
updateCrossProfileIntentFiltersOnOTA) {
mUpdateCrossProfileIntentFiltersOnOTA = updateCrossProfileIntentFiltersOnOTA;
return this;
}
/** Sets the value for {@link #mCrossProfileIntentFilterAccessControl} */
public Builder setCrossProfileIntentFilterAccessControl(
@CrossProfileIntentFilterAccessControlLevel int
crossProfileIntentFilterAccessControl) {
mCrossProfileIntentFilterAccessControl = crossProfileIntentFilterAccessControl;
return this;
}
/** Sets the value for {@link #mCrossProfileIntentResolutionStrategy} */
public Builder setCrossProfileIntentResolutionStrategy(@CrossProfileIntentResolutionStrategy
int crossProfileIntentResolutionStrategy) {
mCrossProfileIntentResolutionStrategy = crossProfileIntentResolutionStrategy;
return this;
}
public Builder setMediaSharedWithParent(boolean mediaSharedWithParent) {
mMediaSharedWithParent = mediaSharedWithParent;
return this;
}
public Builder setCredentialShareableWithParent(boolean credentialShareableWithParent) {
mCredentialShareableWithParent = credentialShareableWithParent;
return this;
}
/** Sets the value for {@link #mDeleteAppWithParent}*/
public Builder setDeleteAppWithParent(boolean deleteAppWithParent) {
mDeleteAppWithParent = deleteAppWithParent;
return this;
}
/** Builds a UserProperties object with *all* values populated. */
public UserProperties build() {
return new UserProperties(
mShowInLauncher,
mStartWithParent,
mShowInSettings,
mInheritDevicePolicy,
mUseParentsContacts,
mUpdateCrossProfileIntentFiltersOnOTA,
mCrossProfileIntentFilterAccessControl,
mCrossProfileIntentResolutionStrategy,
mMediaSharedWithParent,
mCredentialShareableWithParent,
mDeleteAppWithParent);
}
} // end Builder
/** Creates a UserProperties with the given properties. Intended for building default values. */
private UserProperties(
@ShowInLauncher int showInLauncher,
boolean startWithParent,
@ShowInSettings int showInSettings,
@InheritDevicePolicy int inheritDevicePolicy,
boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA,
@CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl,
@CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy,
boolean mediaSharedWithParent,
boolean credentialShareableWithParent,
boolean deleteAppWithParent) {
mDefaultProperties = null;
setShowInLauncher(showInLauncher);
setStartWithParent(startWithParent);
setShowInSettings(showInSettings);
setInheritDevicePolicy(inheritDevicePolicy);
setUseParentsContacts(useParentsContacts);
setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA);
setCrossProfileIntentFilterAccessControl(crossProfileIntentFilterAccessControl);
setCrossProfileIntentResolutionStrategy(crossProfileIntentResolutionStrategy);
setMediaSharedWithParent(mediaSharedWithParent);
setCredentialShareableWithParent(credentialShareableWithParent);
setDeleteAppWithParent(deleteAppWithParent);
}
}