1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.content.pm;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.annotation.TestApi;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.util.Slog;
27 
28 import com.android.internal.annotations.VisibleForTesting;
29 import com.android.modules.utils.TypedXmlPullParser;
30 import com.android.modules.utils.TypedXmlSerializer;
31 
32 import org.xmlpull.v1.XmlPullParserException;
33 
34 import java.io.IOException;
35 import java.io.PrintWriter;
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 
39 /**
40  * Class holding the properties of a user that derive mostly from its user type.
41  *
42  * @hide
43  */
44 @SystemApi
45 public final class UserProperties implements Parcelable {
46     private static final String LOG_TAG = UserProperties.class.getSimpleName();
47 
48     // Attribute strings for reading/writing properties to/from XML.
49     private static final String ATTR_SHOW_IN_LAUNCHER = "showInLauncher";
50     private static final String ATTR_START_WITH_PARENT = "startWithParent";
51     private static final String ATTR_SHOW_IN_SETTINGS = "showInSettings";
52     private static final String ATTR_INHERIT_DEVICE_POLICY = "inheritDevicePolicy";
53     private static final String ATTR_USE_PARENTS_CONTACTS = "useParentsContacts";
54     private static final String ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA =
55             "updateCrossProfileIntentFiltersOnOTA";
56     private static final String ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL =
57             "crossProfileIntentFilterAccessControl";
58     private static final String ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY =
59             "crossProfileIntentResolutionStrategy";
60     private static final String ATTR_MEDIA_SHARED_WITH_PARENT =
61             "mediaSharedWithParent";
62     private static final String ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT =
63             "credentialShareableWithParent";
64     private static final String ATTR_DELETE_APP_WITH_PARENT = "deleteAppWithParent";
65 
66     /** Index values of each property (to indicate whether they are present in this object). */
67     @IntDef(prefix = "INDEX_", value = {
68             INDEX_SHOW_IN_LAUNCHER,
69             INDEX_START_WITH_PARENT,
70             INDEX_SHOW_IN_SETTINGS,
71             INDEX_INHERIT_DEVICE_POLICY,
72             INDEX_USE_PARENTS_CONTACTS,
73             INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA,
74             INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL,
75             INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY,
76             INDEX_MEDIA_SHARED_WITH_PARENT,
77             INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT,
78             INDEX_DELETE_APP_WITH_PARENT,
79     })
80     @Retention(RetentionPolicy.SOURCE)
81     private @interface PropertyIndex {
82     }
83     private static final int INDEX_SHOW_IN_LAUNCHER = 0;
84     private static final int INDEX_START_WITH_PARENT = 1;
85     private static final int INDEX_SHOW_IN_SETTINGS = 2;
86     private static final int INDEX_INHERIT_DEVICE_POLICY = 3;
87     private static final int INDEX_USE_PARENTS_CONTACTS = 4;
88     private static final int INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA = 5;
89     private static final int INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL = 6;
90     private static final int INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY = 7;
91     private static final int INDEX_MEDIA_SHARED_WITH_PARENT = 8;
92     private static final int INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT = 9;
93     private static final int INDEX_DELETE_APP_WITH_PARENT = 10;
94     /** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */
95     private long mPropertiesPresent = 0;
96 
97 
98     /**
99      * Possible values for whether or how to show this user in the Launcher.
100      * @hide
101      */
102     @IntDef(prefix = "SHOW_IN_LAUNCHER_", value = {
103             SHOW_IN_LAUNCHER_WITH_PARENT,
104             SHOW_IN_LAUNCHER_SEPARATE,
105             SHOW_IN_LAUNCHER_NO,
106     })
107     @Retention(RetentionPolicy.SOURCE)
108     public @interface ShowInLauncher {
109     }
110     /**
111      * Suggests that the launcher should show this user's apps in the main tab.
112      * That is, either this user is a full user, so its apps should be presented accordingly, or, if
113      * this user is a profile, then its apps should be shown alongside its parent's apps.
114      * @hide
115      */
116     @TestApi
117     public static final int SHOW_IN_LAUNCHER_WITH_PARENT = 0;
118     /**
119      * Suggests that the launcher should show this user's apps, but separately from the apps of this
120      * user's parent.
121      * @hide
122      */
123     @TestApi
124     public static final int SHOW_IN_LAUNCHER_SEPARATE = 1;
125     /**
126      * Suggests that the launcher should not show this user.
127      * @hide
128      */
129     @TestApi
130     public static final int SHOW_IN_LAUNCHER_NO = 2;
131 
132     /**
133      * Possible values for whether or how to show this user in the Settings app.
134      * @hide
135      */
136     @IntDef(prefix = "SHOW_IN_SETTINGS_", value = {
137             SHOW_IN_SETTINGS_WITH_PARENT,
138             SHOW_IN_SETTINGS_SEPARATE,
139             SHOW_IN_SETTINGS_NO,
140     })
141     @Retention(RetentionPolicy.SOURCE)
142     public @interface ShowInSettings {
143     }
144     /**
145      * Suggests that the Settings app should show this user's apps in the main tab.
146      * That is, either this user is a full user, so its apps should be presented accordingly, or, if
147      * this user is a profile, then its apps should be shown alongside its parent's apps.
148      * @hide
149      */
150     public static final int SHOW_IN_SETTINGS_WITH_PARENT = 0;
151     /**
152      * Suggests that the Settings app should show this user's apps, but separately from the apps of
153      * this user's parent.
154      * @hide
155      */
156     public static final int SHOW_IN_SETTINGS_SEPARATE = 1;
157     /**
158      * Suggests that the Settings app should not show this user.
159      * @hide
160      */
161     public static final int SHOW_IN_SETTINGS_NO = 2;
162 
163     /**
164      * Possible values for whether (and from whom) to inherit select user restrictions
165      * or device policies.
166      *
167      * @hide
168      */
169     @IntDef(prefix = "INHERIT_DEVICE_POLICY", value = {
170             INHERIT_DEVICE_POLICY_NO,
171             INHERIT_DEVICE_POLICY_FROM_PARENT,
172     })
173     @Retention(RetentionPolicy.SOURCE)
174     public @interface InheritDevicePolicy {
175     }
176     /**
177      * Suggests that the given user profile should not inherit user restriction or device policy
178      * from any other user. This is the default value for any new user type.
179      * @hide
180      */
181     public static final int INHERIT_DEVICE_POLICY_NO = 0;
182     /**
183      * Suggests that the given user profile should inherit select user restrictions or
184      * device policies from its parent profile.
185      *
186      *<p> All the user restrictions and device policies would be not propagated to the profile
187      * with this property value. The {@link com.android.server.devicepolicy.DevicePolicyEngine}
188      * uses this property to determine and propagate only select ones to the given profile.
189      *
190      * @hide
191      */
192     public static final int INHERIT_DEVICE_POLICY_FROM_PARENT = 1;
193 
194     /**
195      * Reference to the default user properties for this user's user type.
196      * <li>If non-null, then any absent property will use the default property from here instead.
197      * <li>If null, then any absent property indicates that the caller lacks permission to see it,
198      *          so attempting to get that property will trigger a SecurityException.
199      */
200     private final @Nullable UserProperties mDefaultProperties;
201 
202     /**
203      * CrossProfileIntentFilterAccessControlLevel provides level of access for user to create/modify
204      * {@link CrossProfileIntentFilter}. Each level have value assigned, the higher the value
205      * implies higher restriction for creation/modification.
206      * CrossProfileIntentFilterAccessControlLevel allows us to protect against malicious changes in
207      * user's {@link CrossProfileIntentFilter}s, which might add/remove
208      * {@link CrossProfileIntentFilter} leading to unprecedented results.
209      *
210      * @hide
211      */
212     @IntDef(prefix = {"CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_"}, value = {
213             CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL,
214             CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM,
215             CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY,
216     })
217     @Retention(RetentionPolicy.SOURCE)
218     public @interface CrossProfileIntentFilterAccessControlLevel {
219     }
220 
221     /**
222      * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL signifies that irrespective of user we would
223      * allow access (addition/modification/removal) for CrossProfileIntentFilter.
224      * This is the default access control level.
225      *
226      * @hide
227      */
228     public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL = 0;
229 
230     /**
231      * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM signifies that only system/root user would
232      * be able to access (addition/modification/removal) CrossProfileIntentFilter.
233      *
234      * @hide
235      */
236     public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM = 10;
237 
238     /**
239      * CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY signifies that only system/root
240      * user would be able to add CrossProfileIntentFilter but not modify/remove. Once added, it
241      * cannot be modified or removed.
242      *
243      * @hide
244      */
245     public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY = 20;
246 
247     /**
248      * Possible values for cross profile intent resolution strategy.
249      *
250      * @hide
251      */
252     @IntDef(prefix = {"CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_"}, value = {
253             CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT,
254             CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING
255     })
256     @Retention(RetentionPolicy.SOURCE)
257     public @interface CrossProfileIntentResolutionStrategy {
258     }
259 
260     /**
261      * Signifies to use {@link DefaultCrossProfileResolver} strategy, which
262      * check if it needs to skip the initiating profile, resolves intent in target profile.
263      * {@link DefaultCrossProfileResolver} also filters the {@link ResolveInfo} after intent
264      * resolution based on their domain approval level
265      *
266      * @hide
267      */
268     public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT = 0;
269 
270     /**
271      * Signifies that there is no need to filter {@link ResolveInfo} after cross profile intent
272      * resolution across. This strategy is for profile acting transparent to end-user and resolves
273      * all allowed intent without giving any profile priority.
274      *
275      * @hide
276      */
277     public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING = 1;
278 
279 
280     /**
281      * Creates a UserProperties (intended for the SystemServer) that stores a reference to the given
282      * default properties, which it uses for any property not subsequently set.
283      * @hide
284      */
UserProperties(@onNull UserProperties defaultProperties)285     public UserProperties(@NonNull UserProperties defaultProperties) {
286         mDefaultProperties = defaultProperties;
287         mPropertiesPresent = 0;
288     }
289 
290     /**
291      * Copies the given UserProperties, excluding any information that doesn't satisfy the specified
292      * permissions.
293      * Can only be used on the original version (one that won't throw on permission errors).
294      * Note that, internally, this does not perform an exact copy.
295      * @hide
296      */
UserProperties(UserProperties orig, boolean exposeAllFields, boolean hasManagePermission, boolean hasQueryOrManagePermission)297     public UserProperties(UserProperties orig,
298             boolean exposeAllFields,
299             boolean hasManagePermission,
300             boolean hasQueryOrManagePermission) {
301 
302         if (orig.mDefaultProperties == null) {
303             throw new IllegalArgumentException("Attempting to copy a non-original UserProperties.");
304         }
305 
306         this.mDefaultProperties = null;
307 
308         // Insert each setter into the following hierarchy based on its permission requirements.
309         // NOTE: Copy each property using getters to ensure default values are copied if needed.
310         if (exposeAllFields) {
311             // Add items that require exposeAllFields to be true (strictest permission level).
312             setStartWithParent(orig.getStartWithParent());
313             setInheritDevicePolicy(orig.getInheritDevicePolicy());
314             setUpdateCrossProfileIntentFiltersOnOTA(orig.getUpdateCrossProfileIntentFiltersOnOTA());
315             setCrossProfileIntentFilterAccessControl(
316                     orig.getCrossProfileIntentFilterAccessControl());
317             setCrossProfileIntentResolutionStrategy(orig.getCrossProfileIntentResolutionStrategy());
318             setDeleteAppWithParent(orig.getDeleteAppWithParent());
319         }
320         if (hasManagePermission) {
321             // Add items that require MANAGE_USERS or stronger.
322             setShowInSettings(orig.getShowInSettings());
323             setUseParentsContacts(orig.getUseParentsContacts());
324         }
325         if (hasQueryOrManagePermission) {
326             // Add items that require QUERY_USERS or stronger.
327         }
328         // Add items that have no permission requirements at all.
329         setShowInLauncher(orig.getShowInLauncher());
330         setMediaSharedWithParent(orig.isMediaSharedWithParent());
331         setCredentialShareableWithParent(orig.isCredentialShareableWithParent());
332     }
333 
334     /**
335      * Indicates that the given property is being stored explicitly in this object.
336      * If false, it means that either
337      * <li>the default property for the user type should be used instead (for SystemServer callers)
338      * <li>the caller lacks permission to see this property (for all other callers)
339      */
isPresent(@ropertyIndex long index)340     private boolean isPresent(@PropertyIndex long index) {
341         return (mPropertiesPresent & (1L << index)) != 0;
342     }
343 
344     /** Indicates that the given property is henceforth being explicitly stored in this object. */
setPresent(@ropertyIndex long index)345     private void setPresent(@PropertyIndex long index) {
346         mPropertiesPresent |= (1L << index);
347     }
348 
349     /** @hide Returns the internal mPropertiesPresent value. Only for testing purposes. */
350     @VisibleForTesting
getPropertiesPresent()351     public long getPropertiesPresent() {
352         return mPropertiesPresent;
353     }
354 
355     /**
356      * Returns whether, and how, a user should be shown in the Launcher.
357      * This is generally inapplicable for non-profile users.
358      *
359      * Possible return values include
360      *    {@link #SHOW_IN_LAUNCHER_WITH_PARENT}},
361      *    {@link #SHOW_IN_LAUNCHER_SEPARATE},
362      *    and {@link #SHOW_IN_LAUNCHER_NO}.
363      *
364      * @return whether, and how, a profile should be shown in the Launcher.
365      * @hide
366      */
367     @TestApi
getShowInLauncher()368     public @ShowInLauncher int getShowInLauncher() {
369         if (isPresent(INDEX_SHOW_IN_LAUNCHER)) return mShowInLauncher;
370         if (mDefaultProperties != null) return mDefaultProperties.mShowInLauncher;
371         throw new SecurityException("You don't have permission to query showInLauncher");
372     }
373     /** @hide */
setShowInLauncher(@howInLauncher int val)374     public void setShowInLauncher(@ShowInLauncher int val) {
375         this.mShowInLauncher = val;
376         setPresent(INDEX_SHOW_IN_LAUNCHER);
377     }
378     private @ShowInLauncher int mShowInLauncher;
379 
380     /**
381      * Returns whether, and how, a user should be shown in the Settings app.
382      * This is generally inapplicable for non-profile users.
383      *
384      * Possible return values include
385      *    {@link #SHOW_IN_SETTINGS_WITH_PARENT}},
386      *    {@link #SHOW_IN_SETTINGS_SEPARATE},
387      *    and {@link #SHOW_IN_SETTINGS_NO}.
388      *
389      * <p> The caller must have {@link android.Manifest.permission#MANAGE_USERS} to query this
390      * property.
391      *
392      * @return whether, and how, a profile should be shown in the Settings.
393      * @hide
394      */
getShowInSettings()395     public @ShowInSettings int getShowInSettings() {
396         if (isPresent(INDEX_SHOW_IN_SETTINGS)) return mShowInSettings;
397         if (mDefaultProperties != null) return mDefaultProperties.mShowInSettings;
398         throw new SecurityException("You don't have permission to query mShowInSettings");
399     }
400     /** @hide */
setShowInSettings(@howInSettings int val)401     public void setShowInSettings(@ShowInSettings int val) {
402         this.mShowInSettings = val;
403         setPresent(INDEX_SHOW_IN_SETTINGS);
404     }
405     private @ShowInSettings int mShowInSettings;
406 
407     /**
408      * Returns whether a profile should be started when its parent starts (unless in quiet mode).
409      * This only applies for users that have parents (i.e. for profiles).
410      * @hide
411      */
getStartWithParent()412     public boolean getStartWithParent() {
413         if (isPresent(INDEX_START_WITH_PARENT)) return mStartWithParent;
414         if (mDefaultProperties != null) return mDefaultProperties.mStartWithParent;
415         throw new SecurityException("You don't have permission to query startWithParent");
416     }
417     /** @hide */
setStartWithParent(boolean val)418     public void setStartWithParent(boolean val) {
419         this.mStartWithParent = val;
420         setPresent(INDEX_START_WITH_PARENT);
421     }
422     private boolean mStartWithParent;
423 
424     /**
425      * Returns whether an app in the profile should be deleted when the same package in
426      * the parent user is being deleted.
427      * This only applies for users that have parents (i.e. for profiles).
428      * @hide
429      */
getDeleteAppWithParent()430     public boolean getDeleteAppWithParent() {
431         if (isPresent(INDEX_DELETE_APP_WITH_PARENT)) return mDeleteAppWithParent;
432         if (mDefaultProperties != null) return mDefaultProperties.mDeleteAppWithParent;
433         throw new SecurityException("You don't have permission to query deleteAppWithParent");
434     }
435     /** @hide */
setDeleteAppWithParent(boolean val)436     public void setDeleteAppWithParent(boolean val) {
437         this.mDeleteAppWithParent = val;
438         setPresent(INDEX_DELETE_APP_WITH_PARENT);
439     }
440     private boolean mDeleteAppWithParent;
441 
442     /**
443      * Return whether, and how, select user restrictions or device policies should be inherited
444      * from other user.
445      *
446      * Possible return values include
447      * {@link #INHERIT_DEVICE_POLICY_FROM_PARENT} or {@link #INHERIT_DEVICE_POLICY_NO}
448      *
449      * @hide
450      */
getInheritDevicePolicy()451     public @InheritDevicePolicy int getInheritDevicePolicy() {
452         if (isPresent(INDEX_INHERIT_DEVICE_POLICY)) return mInheritDevicePolicy;
453         if (mDefaultProperties != null) return mDefaultProperties.mInheritDevicePolicy;
454         throw new SecurityException("You don't have permission to query inheritDevicePolicy");
455     }
456     /** @hide */
setInheritDevicePolicy(@nheritDevicePolicy int val)457     public void setInheritDevicePolicy(@InheritDevicePolicy int val) {
458         this.mInheritDevicePolicy = val;
459         setPresent(INDEX_INHERIT_DEVICE_POLICY);
460     }
461     private @InheritDevicePolicy int mInheritDevicePolicy;
462 
463     /**
464      * Returns whether the current user must use parent user's contacts. If true, writes to the
465      * ContactsProvider corresponding to the current user will be disabled and reads will be
466      * redirected to the parent.
467      *
468      * This only applies to users that have parents (i.e. profiles) and is used to ensure
469      * they can access contacts from the parent profile. This will be generally inapplicable for
470      * non-profile users.
471      *
472      * Please note that in case of the clone profiles, only the allow-listed apps would be allowed
473      * to access contacts across profiles and other apps will not see any contacts.
474      * TODO(b/256126819) Add link to the method returning apps allow-listed for app-cloning
475      *
476      * @return whether contacts access from an associated profile is enabled for the user
477      * @hide
478      */
getUseParentsContacts()479     public boolean getUseParentsContacts() {
480         if (isPresent(INDEX_USE_PARENTS_CONTACTS)) return mUseParentsContacts;
481         if (mDefaultProperties != null) return mDefaultProperties.mUseParentsContacts;
482         throw new SecurityException("You don't have permission to query useParentsContacts");
483     }
484     /** @hide */
setUseParentsContacts(boolean val)485     public void setUseParentsContacts(boolean val) {
486         this.mUseParentsContacts = val;
487         setPresent(INDEX_USE_PARENTS_CONTACTS);
488     }
489     /**
490      * Indicates whether the current user should use parent user's contacts.
491      * If this property is set true, the user will be blocked from storing any contacts in its
492      * own contacts database and will serve all read contacts calls through the parent's contacts.
493      */
494     private boolean mUseParentsContacts;
495 
496     /**
497      * Returns true if user needs to update default
498      * {@link com.android.server.pm.CrossProfileIntentFilter} with its parents during an OTA update
499      * @hide
500      */
getUpdateCrossProfileIntentFiltersOnOTA()501     public boolean getUpdateCrossProfileIntentFiltersOnOTA() {
502         if (isPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA)) {
503             return mUpdateCrossProfileIntentFiltersOnOTA;
504         }
505         if (mDefaultProperties != null) {
506             return mDefaultProperties.mUpdateCrossProfileIntentFiltersOnOTA;
507         }
508         throw new SecurityException("You don't have permission to query "
509                 + "updateCrossProfileIntentFiltersOnOTA");
510     }
511     /** @hide */
setUpdateCrossProfileIntentFiltersOnOTA(boolean val)512     public void setUpdateCrossProfileIntentFiltersOnOTA(boolean val) {
513         this.mUpdateCrossProfileIntentFiltersOnOTA = val;
514         setPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA);
515     }
516 
517     /**
518      * Returns whether a profile shares media with its parent user.
519      * This only applies for users that have parents (i.e. for profiles).
520      */
isMediaSharedWithParent()521     public boolean isMediaSharedWithParent() {
522         if (isPresent(INDEX_MEDIA_SHARED_WITH_PARENT)) return mMediaSharedWithParent;
523         if (mDefaultProperties != null) return mDefaultProperties.mMediaSharedWithParent;
524         throw new SecurityException("You don't have permission to query mediaSharedWithParent");
525     }
526     /** @hide */
setMediaSharedWithParent(boolean val)527     public void setMediaSharedWithParent(boolean val) {
528         this.mMediaSharedWithParent = val;
529         setPresent(INDEX_MEDIA_SHARED_WITH_PARENT);
530     }
531     private boolean mMediaSharedWithParent;
532 
533     /**
534      * Returns whether a profile can have shared lockscreen credential with its parent user.
535      * This only applies for users that have parents (i.e. for profiles).
536      */
isCredentialShareableWithParent()537     public boolean isCredentialShareableWithParent() {
538         if (isPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT)) {
539             return mCredentialShareableWithParent;
540         }
541         if (mDefaultProperties != null) return mDefaultProperties.mCredentialShareableWithParent;
542         throw new SecurityException(
543                 "You don't have permission to query credentialShareableWithParent");
544     }
545     /** @hide */
setCredentialShareableWithParent(boolean val)546     public void setCredentialShareableWithParent(boolean val) {
547         this.mCredentialShareableWithParent = val;
548         setPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT);
549     }
550     private boolean mCredentialShareableWithParent;
551 
552     /*
553      Indicate if {@link com.android.server.pm.CrossProfileIntentFilter}s need to be updated during
554      OTA update between user-parent
555      */
556     private boolean mUpdateCrossProfileIntentFiltersOnOTA;
557 
558 
559     /**
560      * Returns the user's {@link CrossProfileIntentFilterAccessControlLevel}.
561      * @hide
562      */
563     public @CrossProfileIntentFilterAccessControlLevel int
getCrossProfileIntentFilterAccessControl()564             getCrossProfileIntentFilterAccessControl() {
565         if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) {
566             return mCrossProfileIntentFilterAccessControl;
567         }
568         if (mDefaultProperties != null) {
569             return mDefaultProperties.mCrossProfileIntentFilterAccessControl;
570         }
571         throw new SecurityException("You don't have permission to query "
572                 + "crossProfileIntentFilterAccessControl");
573     }
574     /**
575      * Sets {@link CrossProfileIntentFilterAccessControlLevel} for the user.
576      * @param val access control for user
577      * @hide
578      */
setCrossProfileIntentFilterAccessControl( @rossProfileIntentFilterAccessControlLevel int val)579     public void setCrossProfileIntentFilterAccessControl(
580             @CrossProfileIntentFilterAccessControlLevel int val) {
581         this.mCrossProfileIntentFilterAccessControl = val;
582         setPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL);
583     }
584     private @CrossProfileIntentFilterAccessControlLevel int mCrossProfileIntentFilterAccessControl;
585 
586     /**
587      * Returns the user's {@link CrossProfileIntentResolutionStrategy}. If not explicitly
588      * configured, default value is {@link #CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT}.
589      * @return user's {@link CrossProfileIntentResolutionStrategy}.
590      *
591      * @hide
592      */
getCrossProfileIntentResolutionStrategy()593     public @CrossProfileIntentResolutionStrategy int getCrossProfileIntentResolutionStrategy() {
594         if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) {
595             return mCrossProfileIntentResolutionStrategy;
596         }
597         if (mDefaultProperties != null) {
598             return mDefaultProperties.mCrossProfileIntentResolutionStrategy;
599         }
600         throw new SecurityException("You don't have permission to query "
601                 + "crossProfileIntentResolutionStrategy");
602     }
603     /**
604      * Sets {@link CrossProfileIntentResolutionStrategy} for the user.
605      * @param val resolution strategy for user
606      * @hide
607      */
setCrossProfileIntentResolutionStrategy( @rossProfileIntentResolutionStrategy int val)608     public void setCrossProfileIntentResolutionStrategy(
609             @CrossProfileIntentResolutionStrategy int val) {
610         this.mCrossProfileIntentResolutionStrategy = val;
611         setPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY);
612     }
613     private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy;
614 
615 
616     @Override
toString()617     public String toString() {
618         // Please print in increasing order of PropertyIndex.
619         return "UserProperties{"
620                 + "mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent)
621                 + ", mShowInLauncher=" + getShowInLauncher()
622                 + ", mStartWithParent=" + getStartWithParent()
623                 + ", mShowInSettings=" + getShowInSettings()
624                 + ", mInheritDevicePolicy=" + getInheritDevicePolicy()
625                 + ", mUseParentsContacts=" + getUseParentsContacts()
626                 + ", mUpdateCrossProfileIntentFiltersOnOTA="
627                 + getUpdateCrossProfileIntentFiltersOnOTA()
628                 + ", mCrossProfileIntentFilterAccessControl="
629                 + getCrossProfileIntentFilterAccessControl()
630                 + ", mCrossProfileIntentResolutionStrategy="
631                 + getCrossProfileIntentResolutionStrategy()
632                 + ", mMediaSharedWithParent=" + isMediaSharedWithParent()
633                 + ", mCredentialShareableWithParent=" + isCredentialShareableWithParent()
634                 + ", mDeleteAppWithParent=" + getDeleteAppWithParent()
635                 + "}";
636     }
637 
638     /**
639      * Print the UserProperties to the given PrintWriter.
640      * @hide
641      */
println(PrintWriter pw, String prefix)642     public void println(PrintWriter pw, String prefix) {
643         // Please print in increasing order of PropertyIndex.
644         pw.println(prefix + "UserProperties:");
645         pw.println(prefix + "    mPropertiesPresent=" + Long.toBinaryString(mPropertiesPresent));
646         pw.println(prefix + "    mShowInLauncher=" + getShowInLauncher());
647         pw.println(prefix + "    mStartWithParent=" + getStartWithParent());
648         pw.println(prefix + "    mShowInSettings=" + getShowInSettings());
649         pw.println(prefix + "    mInheritDevicePolicy=" + getInheritDevicePolicy());
650         pw.println(prefix + "    mUseParentsContacts=" + getUseParentsContacts());
651         pw.println(prefix + "    mUpdateCrossProfileIntentFiltersOnOTA="
652                 + getUpdateCrossProfileIntentFiltersOnOTA());
653         pw.println(prefix + "    mCrossProfileIntentFilterAccessControl="
654                 + getCrossProfileIntentFilterAccessControl());
655         pw.println(prefix + "    mCrossProfileIntentResolutionStrategy="
656                 + getCrossProfileIntentResolutionStrategy());
657         pw.println(prefix + "    mMediaSharedWithParent=" + isMediaSharedWithParent());
658         pw.println(prefix + "    mCredentialShareableWithParent="
659                 + isCredentialShareableWithParent());
660         pw.println(prefix + "    mDeleteAppWithParent=" + getDeleteAppWithParent());
661     }
662 
663     /**
664      * Reads in a UserProperties from an xml file, for use by the SystemServer.
665      *
666      * The serializer should already be inside a tag from which to read the user properties.
667      *
668      * @param defaultUserPropertiesReference the default UserProperties to use for this user type.
669      * @see #writeToXml
670      * @hide
671      */
UserProperties( TypedXmlPullParser parser, @NonNull UserProperties defaultUserPropertiesReference)672     public UserProperties(
673             TypedXmlPullParser parser,
674             @NonNull UserProperties defaultUserPropertiesReference)
675             throws IOException, XmlPullParserException {
676 
677         this(defaultUserPropertiesReference);
678         updateFromXml(parser);
679     }
680 
681     /**
682      * Parses the given xml file and updates this UserProperties with its data.
683      * I.e., if a piece of data is present in the xml, it will overwrite whatever was
684      * previously stored in this UserProperties.
685      * @hide
686      */
updateFromXml(TypedXmlPullParser parser)687     public void updateFromXml(TypedXmlPullParser parser)
688             throws IOException, XmlPullParserException {
689 
690         final int attributeCount = parser.getAttributeCount();
691         for (int i = 0; i < attributeCount; i++) {
692             final String attributeName = parser.getAttributeName(i);
693             switch(attributeName) {
694                 case ATTR_SHOW_IN_LAUNCHER:
695                     setShowInLauncher(parser.getAttributeInt(i));
696                     break;
697                 case ATTR_START_WITH_PARENT:
698                     setStartWithParent(parser.getAttributeBoolean(i));
699                     break;
700                 case ATTR_SHOW_IN_SETTINGS:
701                     setShowInSettings(parser.getAttributeInt(i));
702                     break;
703                 case ATTR_INHERIT_DEVICE_POLICY:
704                     setInheritDevicePolicy(parser.getAttributeInt(i));
705                     break;
706                 case ATTR_USE_PARENTS_CONTACTS:
707                     setUseParentsContacts(parser.getAttributeBoolean(i));
708                     break;
709                 case ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA:
710                     setUpdateCrossProfileIntentFiltersOnOTA(parser.getAttributeBoolean(i));
711                     break;
712                 case ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL:
713                     setCrossProfileIntentFilterAccessControl(parser.getAttributeInt(i));
714                     break;
715                 case ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY:
716                     setCrossProfileIntentResolutionStrategy(parser.getAttributeInt(i));
717                     break;
718                 case ATTR_MEDIA_SHARED_WITH_PARENT:
719                     setMediaSharedWithParent(parser.getAttributeBoolean(i));
720                     break;
721                 case ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT:
722                     setCredentialShareableWithParent(parser.getAttributeBoolean(i));
723                     break;
724                 case ATTR_DELETE_APP_WITH_PARENT:
725                     setDeleteAppWithParent(parser.getAttributeBoolean(i));
726                     break;
727                 default:
728                     Slog.w(LOG_TAG, "Skipping unknown property " + attributeName);
729             }
730         }
731     }
732 
733     /**
734      * Writes the UserProperties, as used by the SystemServer, to the xml file.
735      *
736      * The serializer should already be inside a tag in which to write the user properties.
737      *
738      * @see  #UserProperties(TypedXmlPullParser, UserProperties)
739      * @hide
740      */
writeToXml(TypedXmlSerializer serializer)741     public void writeToXml(TypedXmlSerializer serializer)
742             throws IOException, XmlPullParserException {
743 
744         if (isPresent(INDEX_SHOW_IN_LAUNCHER)) {
745             serializer.attributeInt(null, ATTR_SHOW_IN_LAUNCHER, mShowInLauncher);
746         }
747         if (isPresent(INDEX_START_WITH_PARENT)) {
748             serializer.attributeBoolean(null, ATTR_START_WITH_PARENT, mStartWithParent);
749         }
750         if (isPresent(INDEX_SHOW_IN_SETTINGS)) {
751             serializer.attributeInt(null, ATTR_SHOW_IN_SETTINGS, mShowInSettings);
752         }
753         if (isPresent(INDEX_INHERIT_DEVICE_POLICY)) {
754             serializer.attributeInt(null, ATTR_INHERIT_DEVICE_POLICY,
755                     mInheritDevicePolicy);
756         }
757         if (isPresent(INDEX_USE_PARENTS_CONTACTS)) {
758             serializer.attributeBoolean(null, ATTR_USE_PARENTS_CONTACTS,
759                     mUseParentsContacts);
760         }
761         if (isPresent(INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA)) {
762             serializer.attributeBoolean(null,
763                     ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA,
764                     mUpdateCrossProfileIntentFiltersOnOTA);
765         }
766         if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) {
767             serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL,
768                     mCrossProfileIntentFilterAccessControl);
769         }
770         if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) {
771             serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY,
772                     mCrossProfileIntentResolutionStrategy);
773         }
774         if (isPresent(INDEX_MEDIA_SHARED_WITH_PARENT)) {
775             serializer.attributeBoolean(null, ATTR_MEDIA_SHARED_WITH_PARENT,
776                     mMediaSharedWithParent);
777         }
778         if (isPresent(INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT)) {
779             serializer.attributeBoolean(null, ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT,
780                     mCredentialShareableWithParent);
781         }
782         if (isPresent(INDEX_DELETE_APP_WITH_PARENT)) {
783             serializer.attributeBoolean(null, ATTR_DELETE_APP_WITH_PARENT,
784                     mDeleteAppWithParent);
785         }
786     }
787 
788     // For use only with an object that has already had any permission-lacking fields stripped out.
789     @Override
writeToParcel(@onNull Parcel dest, int parcelableFlags)790     public void writeToParcel(@NonNull Parcel dest, int parcelableFlags) {
791         dest.writeLong(mPropertiesPresent);
792         dest.writeInt(mShowInLauncher);
793         dest.writeBoolean(mStartWithParent);
794         dest.writeInt(mShowInSettings);
795         dest.writeInt(mInheritDevicePolicy);
796         dest.writeBoolean(mUseParentsContacts);
797         dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA);
798         dest.writeInt(mCrossProfileIntentFilterAccessControl);
799         dest.writeInt(mCrossProfileIntentResolutionStrategy);
800         dest.writeBoolean(mMediaSharedWithParent);
801         dest.writeBoolean(mCredentialShareableWithParent);
802         dest.writeBoolean(mDeleteAppWithParent);
803     }
804 
805     /**
806      * Reads a UserProperties object from the parcel.
807      * Not suitable for the canonical SystemServer version since it lacks mDefaultProperties.
808       */
UserProperties(@onNull Parcel source)809     private UserProperties(@NonNull Parcel source) {
810         mDefaultProperties = null;
811 
812         mPropertiesPresent = source.readLong();
813         mShowInLauncher = source.readInt();
814         mStartWithParent = source.readBoolean();
815         mShowInSettings = source.readInt();
816         mInheritDevicePolicy = source.readInt();
817         mUseParentsContacts = source.readBoolean();
818         mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean();
819         mCrossProfileIntentFilterAccessControl = source.readInt();
820         mCrossProfileIntentResolutionStrategy = source.readInt();
821         mMediaSharedWithParent = source.readBoolean();
822         mCredentialShareableWithParent = source.readBoolean();
823         mDeleteAppWithParent = source.readBoolean();
824     }
825 
826     @Override
describeContents()827     public int describeContents() {
828         return 0;
829     }
830 
831     public static final @android.annotation.NonNull Parcelable.Creator<UserProperties> CREATOR
832             = new Parcelable.Creator<UserProperties>() {
833         public UserProperties createFromParcel(Parcel source) {
834             return new UserProperties(source);
835         }
836         public UserProperties[] newArray(int size) {
837             return new UserProperties[size];
838         }
839     };
840 
841     /**
842      * Builder for the SystemServer's {@link UserProperties}; see that class for documentation.
843      * Intended for building default values (and so all properties are present in the built object).
844      * @hide
845      */
846     public static final class Builder {
847         // UserProperties fields and their default values.
848         private @ShowInLauncher int mShowInLauncher = SHOW_IN_LAUNCHER_WITH_PARENT;
849         private boolean mStartWithParent = false;
850         private @ShowInSettings int mShowInSettings = SHOW_IN_SETTINGS_WITH_PARENT;
851         private @InheritDevicePolicy int mInheritDevicePolicy = INHERIT_DEVICE_POLICY_NO;
852         private boolean mUseParentsContacts = false;
853         private boolean mUpdateCrossProfileIntentFiltersOnOTA = false;
854         private @CrossProfileIntentFilterAccessControlLevel int
855                 mCrossProfileIntentFilterAccessControl =
856                 CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL;
857         private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy =
858                 CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT;
859         private boolean mMediaSharedWithParent = false;
860         private boolean mCredentialShareableWithParent = false;
861         private boolean mDeleteAppWithParent = false;
862 
setShowInLauncher(@howInLauncher int showInLauncher)863         public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) {
864             mShowInLauncher = showInLauncher;
865             return this;
866         }
867 
setStartWithParent(boolean startWithParent)868         public Builder setStartWithParent(boolean startWithParent) {
869             mStartWithParent = startWithParent;
870             return this;
871         }
872 
873         /** Sets the value for {@link #mShowInSettings} */
setShowInSettings(@howInSettings int showInSettings)874         public Builder setShowInSettings(@ShowInSettings int showInSettings) {
875             mShowInSettings = showInSettings;
876             return this;
877         }
878 
879         /** Sets the value for {@link #mInheritDevicePolicy}*/
setInheritDevicePolicy( @nheritDevicePolicy int inheritRestrictionsDevicePolicy)880         public Builder setInheritDevicePolicy(
881                 @InheritDevicePolicy int inheritRestrictionsDevicePolicy) {
882             mInheritDevicePolicy = inheritRestrictionsDevicePolicy;
883             return this;
884         }
885 
setUseParentsContacts(boolean useParentsContacts)886         public Builder setUseParentsContacts(boolean useParentsContacts) {
887             mUseParentsContacts = useParentsContacts;
888             return this;
889         }
890 
891         /** Sets the value for {@link #mUpdateCrossProfileIntentFiltersOnOTA} */
setUpdateCrossProfileIntentFiltersOnOTA(boolean updateCrossProfileIntentFiltersOnOTA)892         public Builder setUpdateCrossProfileIntentFiltersOnOTA(boolean
893                 updateCrossProfileIntentFiltersOnOTA) {
894             mUpdateCrossProfileIntentFiltersOnOTA = updateCrossProfileIntentFiltersOnOTA;
895             return this;
896         }
897 
898         /** Sets the value for {@link #mCrossProfileIntentFilterAccessControl} */
setCrossProfileIntentFilterAccessControl( @rossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl)899         public Builder setCrossProfileIntentFilterAccessControl(
900                 @CrossProfileIntentFilterAccessControlLevel int
901                         crossProfileIntentFilterAccessControl) {
902             mCrossProfileIntentFilterAccessControl = crossProfileIntentFilterAccessControl;
903             return this;
904         }
905 
906         /** Sets the value for {@link #mCrossProfileIntentResolutionStrategy} */
setCrossProfileIntentResolutionStrategy(@rossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy)907         public Builder setCrossProfileIntentResolutionStrategy(@CrossProfileIntentResolutionStrategy
908                 int crossProfileIntentResolutionStrategy) {
909             mCrossProfileIntentResolutionStrategy = crossProfileIntentResolutionStrategy;
910             return this;
911         }
912 
setMediaSharedWithParent(boolean mediaSharedWithParent)913         public Builder setMediaSharedWithParent(boolean mediaSharedWithParent) {
914             mMediaSharedWithParent = mediaSharedWithParent;
915             return this;
916         }
917 
setCredentialShareableWithParent(boolean credentialShareableWithParent)918         public Builder setCredentialShareableWithParent(boolean credentialShareableWithParent) {
919             mCredentialShareableWithParent = credentialShareableWithParent;
920             return this;
921         }
922 
923         /** Sets the value for {@link #mDeleteAppWithParent}*/
setDeleteAppWithParent(boolean deleteAppWithParent)924         public Builder setDeleteAppWithParent(boolean deleteAppWithParent) {
925             mDeleteAppWithParent = deleteAppWithParent;
926             return this;
927         }
928 
929         /** Builds a UserProperties object with *all* values populated. */
build()930         public UserProperties build() {
931             return new UserProperties(
932                     mShowInLauncher,
933                     mStartWithParent,
934                     mShowInSettings,
935                     mInheritDevicePolicy,
936                     mUseParentsContacts,
937                     mUpdateCrossProfileIntentFiltersOnOTA,
938                     mCrossProfileIntentFilterAccessControl,
939                     mCrossProfileIntentResolutionStrategy,
940                     mMediaSharedWithParent,
941                     mCredentialShareableWithParent,
942                     mDeleteAppWithParent);
943         }
944     } // end Builder
945 
946     /** Creates a UserProperties with the given properties. Intended for building default values. */
UserProperties( @howInLauncher 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)947     private UserProperties(
948             @ShowInLauncher int showInLauncher,
949             boolean startWithParent,
950             @ShowInSettings int showInSettings,
951             @InheritDevicePolicy int inheritDevicePolicy,
952             boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA,
953             @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl,
954             @CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy,
955             boolean mediaSharedWithParent,
956             boolean credentialShareableWithParent,
957             boolean deleteAppWithParent) {
958         mDefaultProperties = null;
959         setShowInLauncher(showInLauncher);
960         setStartWithParent(startWithParent);
961         setShowInSettings(showInSettings);
962         setInheritDevicePolicy(inheritDevicePolicy);
963         setUseParentsContacts(useParentsContacts);
964         setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA);
965         setCrossProfileIntentFilterAccessControl(crossProfileIntentFilterAccessControl);
966         setCrossProfileIntentResolutionStrategy(crossProfileIntentResolutionStrategy);
967         setMediaSharedWithParent(mediaSharedWithParent);
968         setCredentialShareableWithParent(credentialShareableWithParent);
969         setDeleteAppWithParent(deleteAppWithParent);
970     }
971 }
972