1 /*
2  * Copyright (C) 2015 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 com.android.server.pm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.ActivityManager;
22 import android.app.AppGlobals;
23 import android.content.ContentResolver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.IPackageManager;
28 import android.content.pm.PackageManager;
29 import android.content.pm.PackageManagerInternal;
30 import android.hardware.display.AmbientDisplayConfiguration;
31 import android.os.Binder;
32 import android.os.Bundle;
33 import android.os.Process;
34 import android.os.RemoteException;
35 import android.os.UserHandle;
36 import android.os.UserManager;
37 import android.provider.Settings;
38 import android.telephony.SubscriptionInfo;
39 import android.telephony.SubscriptionManager;
40 import android.util.Log;
41 import android.util.Slog;
42 import android.util.SparseArray;
43 
44 import com.android.internal.util.Preconditions;
45 import com.android.internal.util.XmlUtils;
46 import com.android.modules.utils.TypedXmlPullParser;
47 import com.android.modules.utils.TypedXmlSerializer;
48 import com.android.server.BundleUtils;
49 import com.android.server.LocalServices;
50 
51 import com.google.android.collect.Sets;
52 
53 import org.xmlpull.v1.XmlPullParser;
54 import org.xmlpull.v1.XmlSerializer;
55 
56 import java.io.IOException;
57 import java.io.PrintWriter;
58 import java.util.List;
59 import java.util.Objects;
60 import java.util.Set;
61 
62 /**
63  * Utility methods for user restrictions.
64  *
65  * <p>See {@link UserManagerService} for the method suffixes.
66  */
67 public class UserRestrictionsUtils {
68     private static final String TAG = "UserRestrictionsUtils";
69 
UserRestrictionsUtils()70     private UserRestrictionsUtils() {
71     }
72 
newSetWithUniqueCheck(String[] strings)73     private static Set<String> newSetWithUniqueCheck(String[] strings) {
74         final Set<String> ret = Sets.newArraySet(strings);
75 
76         // Make sure there's no overlap.
77         Preconditions.checkState(ret.size() == strings.length);
78         return ret;
79     }
80 
81     public static final Set<String> USER_RESTRICTIONS = newSetWithUniqueCheck(new String[] {
82             UserManager.DISALLOW_CONFIG_WIFI,
83             UserManager.DISALLOW_CONFIG_LOCALE,
84             UserManager.DISALLOW_MODIFY_ACCOUNTS,
85             UserManager.DISALLOW_INSTALL_APPS,
86             UserManager.DISALLOW_UNINSTALL_APPS,
87             UserManager.DISALLOW_SHARE_LOCATION,
88             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
89             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
90             UserManager.DISALLOW_CONFIG_BLUETOOTH,
91             UserManager.DISALLOW_BLUETOOTH,
92             UserManager.DISALLOW_BLUETOOTH_SHARING,
93             UserManager.DISALLOW_USB_FILE_TRANSFER,
94             UserManager.DISALLOW_CONFIG_CREDENTIALS,
95             UserManager.DISALLOW_REMOVE_USER,
96             UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
97             UserManager.DISALLOW_DEBUGGING_FEATURES,
98             UserManager.DISALLOW_CONFIG_VPN,
99             UserManager.DISALLOW_CONFIG_DATE_TIME,
100             UserManager.DISALLOW_CONFIG_TETHERING,
101             UserManager.DISALLOW_NETWORK_RESET,
102             UserManager.DISALLOW_FACTORY_RESET,
103             UserManager.DISALLOW_ADD_USER,
104             UserManager.DISALLOW_ADD_MANAGED_PROFILE,
105             UserManager.DISALLOW_ADD_CLONE_PROFILE,
106             UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
107             UserManager.ENSURE_VERIFY_APPS,
108             UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
109             UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
110             UserManager.DISALLOW_APPS_CONTROL,
111             UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
112             UserManager.DISALLOW_UNMUTE_MICROPHONE,
113             UserManager.DISALLOW_ADJUST_VOLUME,
114             UserManager.DISALLOW_OUTGOING_CALLS,
115             UserManager.DISALLOW_SMS,
116             UserManager.DISALLOW_FUN,
117             UserManager.DISALLOW_CREATE_WINDOWS,
118             UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
119             UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
120             UserManager.DISALLOW_OUTGOING_BEAM,
121             UserManager.DISALLOW_WALLPAPER,
122             UserManager.DISALLOW_SAFE_BOOT,
123             UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
124             UserManager.DISALLOW_RECORD_AUDIO,
125             UserManager.DISALLOW_CAMERA,
126             UserManager.DISALLOW_RUN_IN_BACKGROUND,
127             UserManager.DISALLOW_DATA_ROAMING,
128             UserManager.DISALLOW_SET_USER_ICON,
129             UserManager.DISALLOW_SET_WALLPAPER,
130             UserManager.DISALLOW_OEM_UNLOCK,
131             UserManager.DISALLOW_UNMUTE_DEVICE,
132             UserManager.DISALLOW_AUTOFILL,
133             UserManager.DISALLOW_CONTENT_CAPTURE,
134             UserManager.DISALLOW_CONTENT_SUGGESTIONS,
135             UserManager.DISALLOW_USER_SWITCH,
136             UserManager.DISALLOW_UNIFIED_PASSWORD,
137             UserManager.DISALLOW_CONFIG_LOCATION,
138             UserManager.DISALLOW_AIRPLANE_MODE,
139             UserManager.DISALLOW_CONFIG_BRIGHTNESS,
140             UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,
141             UserManager.DISALLOW_AMBIENT_DISPLAY,
142             UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
143             UserManager.DISALLOW_PRINTING,
144             UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
145             UserManager.DISALLOW_MICROPHONE_TOGGLE,
146             UserManager.DISALLOW_CAMERA_TOGGLE,
147             UserManager.DISALLOW_CHANGE_WIFI_STATE,
148             UserManager.DISALLOW_WIFI_TETHERING,
149             UserManager.DISALLOW_GRANT_ADMIN,
150             UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,
151             UserManager.DISALLOW_WIFI_DIRECT,
152             UserManager.DISALLOW_ADD_WIFI_CONFIG,
153             UserManager.DISALLOW_CELLULAR_2G,
154             UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
155             UserManager.DISALLOW_CONFIG_DEFAULT_APPS,
156             UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
157             UserManager.DISALLOW_SIM_GLOBALLY,
158             UserManager.DISALLOW_ASSIST_CONTENT,
159             UserManager.DISALLOW_THREAD_NETWORK,
160             UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
161     });
162 
163     public static final Set<String> DEPRECATED_USER_RESTRICTIONS = Sets.newArraySet(
164             UserManager.DISALLOW_ADD_MANAGED_PROFILE,
165             UserManager.DISALLOW_REMOVE_MANAGED_PROFILE
166     );
167 
168     /**
169      * Set of user restriction which we don't want to persist.
170      */
171     private static final Set<String> NON_PERSIST_USER_RESTRICTIONS = Sets.newArraySet(
172             UserManager.DISALLOW_RECORD_AUDIO
173     );
174 
175     /**
176      * User restrictions that can only be set by profile owners on the main user, or by device
177      * owners. When set by DO they will be applied to all users.
178      */
179     private static final Set<String> MAIN_USER_ONLY_RESTRICTIONS = Sets.newArraySet(
180             UserManager.DISALLOW_BLUETOOTH,
181             UserManager.DISALLOW_USB_FILE_TRANSFER,
182             UserManager.DISALLOW_CONFIG_TETHERING,
183             UserManager.DISALLOW_NETWORK_RESET,
184             UserManager.DISALLOW_FACTORY_RESET,
185             UserManager.DISALLOW_ADD_USER,
186             UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
187             UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
188             UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
189             UserManager.DISALLOW_SMS,
190             UserManager.DISALLOW_FUN,
191             UserManager.DISALLOW_SAFE_BOOT,
192             UserManager.DISALLOW_CREATE_WINDOWS,
193             UserManager.DISALLOW_DATA_ROAMING,
194             UserManager.DISALLOW_AIRPLANE_MODE
195     );
196 
197     /**
198      * User restrictions that cannot be set by profile owners. Applied to all users.
199      */
200     private static final Set<String> DEVICE_OWNER_ONLY_RESTRICTIONS = Sets.newArraySet(
201             UserManager.DISALLOW_USER_SWITCH,
202             UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
203             UserManager.DISALLOW_MICROPHONE_TOGGLE,
204             UserManager.DISALLOW_CAMERA_TOGGLE,
205             UserManager.DISALLOW_CHANGE_WIFI_STATE,
206             UserManager.DISALLOW_WIFI_TETHERING,
207             UserManager.DISALLOW_WIFI_DIRECT,
208             UserManager.DISALLOW_ADD_WIFI_CONFIG,
209             UserManager.DISALLOW_CELLULAR_2G,
210             UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
211             UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
212             UserManager.DISALLOW_THREAD_NETWORK,
213             UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
214     );
215 
216     /**
217      * User restrictions that can't be changed by device owner or profile owner.
218      */
219     private static final Set<String> IMMUTABLE_BY_OWNERS = Sets.newArraySet(
220             UserManager.DISALLOW_RECORD_AUDIO,
221             UserManager.DISALLOW_WALLPAPER,
222             UserManager.DISALLOW_OEM_UNLOCK
223     );
224 
225     /**
226      * Special user restrictions that can be applied to a user as well as to all users globally,
227      * depending on callers.  When device owner sets them, they'll be applied to all users.
228      */
229     private static final Set<String> GLOBAL_RESTRICTIONS = Sets.newArraySet(
230             UserManager.DISALLOW_ADJUST_VOLUME,
231             UserManager.DISALLOW_BLUETOOTH_SHARING,
232             UserManager.DISALLOW_CONFIG_DATE_TIME,
233             UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
234             UserManager.DISALLOW_RUN_IN_BACKGROUND,
235             UserManager.DISALLOW_UNMUTE_MICROPHONE,
236             UserManager.DISALLOW_UNMUTE_DEVICE,
237             UserManager.DISALLOW_CAMERA,
238             UserManager.DISALLOW_ASSIST_CONTENT,
239             UserManager.DISALLOW_CONFIG_DEFAULT_APPS
240     );
241 
242     /**
243      * Special user restrictions that profile owner of an organization-owned managed profile can
244      * set on the parent profile instance to apply them globally.
245      */
246     private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS =
247             Sets.newArraySet(
248                     UserManager.DISALLOW_AIRPLANE_MODE,
249                     UserManager.DISALLOW_CONFIG_DATE_TIME,
250                     UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
251                     UserManager.DISALLOW_CHANGE_WIFI_STATE,
252                     UserManager.DISALLOW_DEBUGGING_FEATURES,
253                     UserManager.DISALLOW_WIFI_TETHERING,
254                     UserManager.DISALLOW_WIFI_DIRECT,
255                     UserManager.DISALLOW_ADD_WIFI_CONFIG,
256                     UserManager.DISALLOW_CELLULAR_2G,
257                     UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
258                     UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
259                     UserManager.DISALLOW_THREAD_NETWORK,
260                     UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
261             );
262 
263     /**
264      * Special user restrictions that profile owner of an organization-owned managed profile can
265      * set on the profile, which regular profile owners cannot set.
266      */
267     private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_PROFILE_RESTRICTIONS =
268             Sets.newArraySet(
269                     UserManager.DISALLOW_SIM_GLOBALLY
270             );
271 
272     /**
273      * Special user restrictions that profile owner of an organization-owned managed profile can
274      * set on the parent profile instance to apply them on the personal profile.
275      */
276     private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_LOCAL_RESTRICTIONS =
277             Sets.newArraySet(
278                     UserManager.DISALLOW_CONFIG_BLUETOOTH,
279                     UserManager.DISALLOW_CONFIG_LOCATION,
280                     UserManager.DISALLOW_CONFIG_WIFI,
281                     UserManager.DISALLOW_CONTENT_CAPTURE,
282                     UserManager.DISALLOW_CONTENT_SUGGESTIONS,
283                     UserManager.DISALLOW_DEBUGGING_FEATURES,
284                     UserManager.DISALLOW_SHARE_LOCATION,
285                     UserManager.DISALLOW_OUTGOING_CALLS,
286                     UserManager.DISALLOW_CAMERA,
287                     UserManager.DISALLOW_BLUETOOTH,
288                     UserManager.DISALLOW_BLUETOOTH_SHARING,
289                     UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
290                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
291                     UserManager.DISALLOW_CONFIG_TETHERING,
292                     UserManager.DISALLOW_DATA_ROAMING,
293                     UserManager.DISALLOW_SAFE_BOOT,
294                     UserManager.DISALLOW_SMS,
295                     UserManager.DISALLOW_USB_FILE_TRANSFER,
296                     UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
297                     UserManager.DISALLOW_UNMUTE_MICROPHONE,
298                     UserManager.DISALLOW_CONFIG_DEFAULT_APPS,
299                     UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
300                     UserManager.DISALLOW_CONFIG_BRIGHTNESS,
301                     UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
302     );
303 
304     /**
305      * User restrictions that default to {@code true} for managed profile owners.
306      *
307      * NB: {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} is also set by default but it is
308      * not set to existing profile owners unless they used to have INSTALL_NON_MARKET_APPS disabled
309      * in settings. So it is handled separately.
310      */
311     private static final Set<String> DEFAULT_ENABLED_FOR_MANAGED_PROFILES = Sets.newArraySet(
312             UserManager.DISALLOW_BLUETOOTH_SHARING
313     );
314 
315     /**
316      * Special user restrictions that are always applied to all users no matter who sets them.
317      */
318     private static final Set<String> PROFILE_GLOBAL_RESTRICTIONS = Sets.newArraySet(
319             UserManager.ENSURE_VERIFY_APPS,
320             UserManager.DISALLOW_AIRPLANE_MODE,
321             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
322             UserManager.DISALLOW_SIM_GLOBALLY
323     );
324 
325     /**
326      * User restrictions available to a device owner whose type is
327      * {@link android.app.admin.DevicePolicyManager#DEVICE_OWNER_TYPE_FINANCED}.
328      */
329     private static final Set<String> FINANCED_DEVICE_OWNER_RESTRICTIONS = Sets.newArraySet(
330             UserManager.DISALLOW_ADD_USER,
331             UserManager.DISALLOW_DEBUGGING_FEATURES,
332             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
333             UserManager.DISALLOW_SAFE_BOOT,
334             UserManager.DISALLOW_CONFIG_DATE_TIME,
335             UserManager.DISALLOW_OUTGOING_CALLS
336     );
337 
338     /**
339      * Returns whether the given restriction name is valid (and logs it if it isn't).
340      */
isValidRestriction(@onNull String restriction)341     public static boolean isValidRestriction(@NonNull String restriction) {
342         if (!USER_RESTRICTIONS.contains(restriction)) {
343             // Log this, with severity depending on the source.
344             final int uid = Binder.getCallingUid();
345             String[] pkgs = null;
346             try {
347                 pkgs = AppGlobals.getPackageManager().getPackagesForUid(uid);
348             } catch (RemoteException e) {
349                 // Ignore
350             }
351             StringBuilder msg = new StringBuilder("Unknown restriction queried by uid ");
352             msg.append(uid);
353             if (pkgs != null && pkgs.length > 0) {
354                 msg.append(" (");
355                 msg.append(pkgs[0]);
356                 if (pkgs.length > 1) {
357                     msg.append(" et al");
358                 }
359                 msg.append(")");
360             }
361             msg.append(": ");
362             msg.append(restriction);
363             if (restriction != null && isSystemApp(uid, pkgs)) {
364                 Slog.wtf(TAG, msg.toString());
365             } else {
366                 Slog.e(TAG, msg.toString());
367             }
368             return false;
369         }
370         return true;
371     }
372 
373     /** Returns whether the given uid (or corresponding packageList) is for a System app. */
isSystemApp(int uid, String[] packageList)374     private static boolean isSystemApp(int uid, String[] packageList) {
375         if (UserHandle.isCore(uid)) {
376             return true;
377         }
378         if (packageList == null) {
379             return false;
380         }
381         final IPackageManager pm = AppGlobals.getPackageManager();
382         for (int i = 0; i < packageList.length; i++) {
383             try {
384                 final int flags = PackageManager.MATCH_UNINSTALLED_PACKAGES
385                         | PackageManager.MATCH_DIRECT_BOOT_AWARE
386                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
387                 final ApplicationInfo appInfo =
388                         pm.getApplicationInfo(packageList[i], flags, UserHandle.getUserId(uid));
389                 if (appInfo != null && appInfo.isSystemApp()) {
390                     return true;
391                 }
392             } catch (RemoteException e) {
393                 // Ignore
394             }
395         }
396         return false;
397     }
398 
writeRestrictions(@onNull XmlSerializer serializer, @Nullable Bundle restrictions, @NonNull String tag)399     public static void writeRestrictions(@NonNull XmlSerializer serializer,
400             @Nullable Bundle restrictions, @NonNull String tag) throws IOException {
401         writeRestrictions(XmlUtils.makeTyped(serializer), restrictions, tag);
402     }
403 
writeRestrictions(@onNull TypedXmlSerializer serializer, @Nullable Bundle restrictions, @NonNull String tag)404     public static void writeRestrictions(@NonNull TypedXmlSerializer serializer,
405             @Nullable Bundle restrictions, @NonNull String tag) throws IOException {
406         if (restrictions == null) {
407             return;
408         }
409 
410         serializer.startTag(null, tag);
411         for (String key : restrictions.keySet()) {
412             if (NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
413                 continue; // Don't persist.
414             }
415             if (USER_RESTRICTIONS.contains(key)) {
416                 if (restrictions.getBoolean(key)) {
417                     serializer.attributeBoolean(null, key, true);
418                 }
419                 continue;
420             }
421             Log.w(TAG, "Unknown user restriction detected: " + key);
422         }
423         serializer.endTag(null, tag);
424     }
425 
readRestrictions(XmlPullParser parser, Bundle restrictions)426     public static void readRestrictions(XmlPullParser parser, Bundle restrictions) {
427         readRestrictions(XmlUtils.makeTyped(parser), restrictions);
428     }
429 
readRestrictions(TypedXmlPullParser parser, Bundle restrictions)430     public static void readRestrictions(TypedXmlPullParser parser, Bundle restrictions) {
431         restrictions.clear();
432         for (String key : USER_RESTRICTIONS) {
433             final boolean value = parser.getAttributeBoolean(null, key, false);
434             if (value) {
435                 restrictions.putBoolean(key, true);
436             }
437         }
438     }
439 
readRestrictions(XmlPullParser parser)440     public static Bundle readRestrictions(XmlPullParser parser) {
441         return readRestrictions(XmlUtils.makeTyped(parser));
442     }
443 
readRestrictions(TypedXmlPullParser parser)444     public static Bundle readRestrictions(TypedXmlPullParser parser) {
445         final Bundle result = new Bundle();
446         readRestrictions(parser, result);
447         return result;
448     }
449 
450     /**
451      * @return {@code in} itself when it's not null, or an empty bundle (which can writable).
452      */
nonNull(@ullable Bundle in)453     public static Bundle nonNull(@Nullable Bundle in) {
454         return in != null ? in : new Bundle();
455     }
456 
457     /**
458      * Returns {@code true} if given bundle is not null and contains {@code true} for a given
459      * restriction.
460      */
contains(@ullable Bundle in, String restriction)461     public static boolean contains(@Nullable Bundle in, String restriction) {
462         return in != null && in.getBoolean(restriction);
463     }
464 
merge(@onNull Bundle dest, @Nullable Bundle in)465     public static void merge(@NonNull Bundle dest, @Nullable Bundle in) {
466         Objects.requireNonNull(dest);
467         Preconditions.checkArgument(dest != in);
468         if (in == null) {
469             return;
470         }
471         for (String key : in.keySet()) {
472             if (in.getBoolean(key, false)) {
473                 dest.putBoolean(key, true);
474             }
475         }
476     }
477 
478     /**
479      * @return true if a restriction is settable by device owner.
480      */
canDeviceOwnerChange(String restriction)481     public static boolean canDeviceOwnerChange(String restriction) {
482         return !IMMUTABLE_BY_OWNERS.contains(restriction);
483     }
484 
485     /**
486      * Checks whether a restriction is settable by a profile owner
487      *
488      * <p> Whether a restriction is settable by a profile owner is a property of the restriction and
489      * defined statically by the restriction. It may depend on other context information, such
490      * as whether the relevant user is the {@link UserManager#isMainUser() MainUser}.
491      *
492      * @param restriction the restrictions to check
493      * @param isMainUser true if the relevant user is the {@link UserManager#isMainUser() MainUser}.
494      *                   Some restrictions can be changed by PO only when it's running on the main
495      *                   user.
496      * @param isProfileOwnerOnOrgOwnedDevice true if the relevant user is the profile owner of an
497      *                                       organization owned device. Some restrictions can only
498      *                                       be set by PO when it's running as the profile owner
499      *                                       on an organization owned device.
500      * @return true if a restriction is settable by a profile owner
501      */
canProfileOwnerChange( String restriction, boolean isMainUser, boolean isProfileOwnerOnOrgOwnedDevice)502     public static boolean canProfileOwnerChange(
503             String restriction,
504             boolean isMainUser,
505             boolean isProfileOwnerOnOrgOwnedDevice) {
506         if (android.app.admin.flags.Flags.esimManagementEnabled()) {
507             if (IMMUTABLE_BY_OWNERS.contains(restriction)) {
508                 return false;
509             }
510             if (DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction)) {
511                 return false;
512             }
513             if (!isMainUser && MAIN_USER_ONLY_RESTRICTIONS.contains(restriction)) {
514                 return false;
515             }
516             if (!isProfileOwnerOnOrgOwnedDevice
517                     && PROFILE_OWNER_ORGANIZATION_OWNED_PROFILE_RESTRICTIONS.contains(
518                             restriction)) {
519                 return false;
520             }
521             return true;
522         }
523         return !IMMUTABLE_BY_OWNERS.contains(restriction)
524                 && !DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction)
525                 && !(!isMainUser && MAIN_USER_ONLY_RESTRICTIONS.contains(restriction));
526     }
527 
528     /**
529      * Checks whether a restriction is settable by a profile owner on the parent instance
530      * of an organization owned device.
531      *
532      * <p> Whether a restriction is settable by a profile owner is a property of the restriction and
533      * defined statically by the restriction.
534      *
535      * <p> Note: This is used to check whether a restriction can be set by a profile owner
536      *     on the parent instance.
537      *
538      * @param restriction the restrictions to check
539      * @return true if a restriction is settable by a profile owner on the parent instance
540      */
canParentOfProfileOwnerOfOrganizationOwnedDeviceChange( String restriction)541     public static boolean canParentOfProfileOwnerOfOrganizationOwnedDeviceChange(
542             String restriction) {
543         return PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS.contains(restriction)
544                 || PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_LOCAL_RESTRICTIONS.contains(restriction);
545     }
546 
547     /**
548      * Returns the user restrictions that default to {@code true} for managed profile owners.
549      */
getDefaultEnabledForManagedProfiles()550     public static @NonNull Set<String> getDefaultEnabledForManagedProfiles() {
551         return DEFAULT_ENABLED_FOR_MANAGED_PROFILES;
552     }
553 
554     /**
555      * @return {@code true} only if the restriction is allowed for financed devices and can be set
556      * by a device owner. Otherwise, {@code false} would be returned.
557      */
canFinancedDeviceOwnerChange(String restriction)558     public static boolean canFinancedDeviceOwnerChange(String restriction) {
559         return FINANCED_DEVICE_OWNER_RESTRICTIONS.contains(restriction)
560                 && canDeviceOwnerChange(restriction);
561     }
562 
563     /**
564      * Whether given user restriction should be enforced globally.
565      */
isGlobal(@serManagerInternal.OwnerType int restrictionOwnerType, String key)566     public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType,
567             String key) {
568         return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && (
569                 MAIN_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
570                 || ((restrictionOwnerType
571                 == UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)
572                 && (PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS.contains(key)))
573                 || PROFILE_GLOBAL_RESTRICTIONS.contains(key)
574                 || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key);
575     }
576 
577     /**
578      * Whether given user restriction should be enforced locally.
579      */
isLocal(@serManagerInternal.OwnerType int restrictionOwnerType, String key)580     public static boolean isLocal(@UserManagerInternal.OwnerType int restrictionOwnerType,
581             String key) {
582         return !isGlobal(restrictionOwnerType, key);
583     }
584 
585     /**
586      * @return true if two Bundles contain the same user restriction.
587      * A null bundle and an empty bundle are considered to be equal.
588      */
areEqual(@ullable Bundle a, @Nullable Bundle b)589     public static boolean areEqual(@Nullable Bundle a, @Nullable Bundle b) {
590         if (a == b) {
591             return true;
592         }
593         if (BundleUtils.isEmpty(a)) {
594             return BundleUtils.isEmpty(b);
595         }
596         if (BundleUtils.isEmpty(b)) {
597             return false;
598         }
599         for (String key : a.keySet()) {
600             if (a.getBoolean(key) != b.getBoolean(key)) {
601                 return false;
602             }
603         }
604         for (String key : b.keySet()) {
605             if (a.getBoolean(key) != b.getBoolean(key)) {
606                 return false;
607             }
608         }
609         return true;
610     }
611 
612     /**
613      * Takes a new use restriction set and the previous set, and apply the restrictions that have
614      * changed.
615      *
616      * <p>Note this method is called by {@link UserManagerService} without holding any locks.
617      */
applyUserRestrictions(Context context, int userId, Bundle newRestrictions, Bundle prevRestrictions)618     public static void applyUserRestrictions(Context context, int userId,
619             Bundle newRestrictions, Bundle prevRestrictions) {
620         for (String key : USER_RESTRICTIONS) {
621             final boolean newValue = newRestrictions.getBoolean(key);
622             final boolean prevValue = prevRestrictions.getBoolean(key);
623 
624             if (newValue != prevValue) {
625                 applyUserRestriction(context, userId, key, newValue);
626             }
627         }
628     }
629 
630     /**
631      * Apply each user restriction.
632      *
633      * <p>See also {@link #isSettingRestrictedForUser()},
634      * which should be in sync with this method.
635      */
applyUserRestriction(Context context, int userId, String key, boolean newValue)636     private static void applyUserRestriction(Context context, int userId, String key,
637             boolean newValue) {
638         if (UserManagerService.DBG) {
639             Log.d(TAG, "Applying user restriction: userId=" + userId
640                     + " key=" + key + " value=" + newValue);
641         }
642         // When certain restrictions are cleared, we don't update the system settings,
643         // because these settings are changeable on the Settings UI and we don't know the original
644         // value -- for example LOCATION_MODE might have been off already when the restriction was
645         // set, and in that case even if the restriction is lifted, changing it to ON would be
646         // wrong.  So just don't do anything in such a case.  If the user hopes to enable location
647         // later, they can do it on the Settings UI.
648         // WARNING: Remember that Settings.Global and Settings.Secure are changeable via adb.
649         // To prevent this from happening for a given user restriction, you have to add a check to
650         // SettingsProvider.isGlobalOrSecureSettingRestrictedForUser.
651 
652         final ContentResolver cr = context.getContentResolver();
653         final long id = Binder.clearCallingIdentity();
654         try {
655             switch (key) {
656                 case UserManager.DISALLOW_DATA_ROAMING:
657                     if (newValue) {
658                         // DISALLOW_DATA_ROAMING user restriction is set.
659 
660                         // Multi sim device.
661                         SubscriptionManager subscriptionManager = context
662                                 .getSystemService(SubscriptionManager.class);
663                         final List<SubscriptionInfo> subscriptionInfoList =
664                             subscriptionManager.getActiveSubscriptionInfoList();
665                         if (subscriptionInfoList != null) {
666                             for (SubscriptionInfo subInfo : subscriptionInfoList) {
667                                 android.provider.Settings.Global.putStringForUser(cr,
668                                     android.provider.Settings.Global.DATA_ROAMING
669                                     + subInfo.getSubscriptionId(), "0", userId);
670                             }
671                         }
672 
673                         // Single sim device.
674                         android.provider.Settings.Global.putStringForUser(cr,
675                             android.provider.Settings.Global.DATA_ROAMING, "0", userId);
676                     }
677                     break;
678                 case UserManager.DISALLOW_SHARE_LOCATION:
679                     if (newValue) {
680                         android.provider.Settings.Secure.putIntForUser(cr,
681                                 android.provider.Settings.Secure.LOCATION_MODE,
682                                 android.provider.Settings.Secure.LOCATION_MODE_OFF,
683                                 userId);
684                     }
685                     break;
686                 case UserManager.DISALLOW_DEBUGGING_FEATURES:
687                     if (newValue) {
688                         // Only disable adb if changing for system user, since it is global
689                         // TODO: should this be admin user?
690                         if (userId == UserHandle.USER_SYSTEM) {
691                             android.provider.Settings.Global.putStringForUser(cr,
692                                     android.provider.Settings.Global.ADB_ENABLED, "0",
693                                     userId);
694                             android.provider.Settings.Global.putStringForUser(cr,
695                                     android.provider.Settings.Global.ADB_WIFI_ENABLED, "0",
696                                     userId);
697                         }
698                     }
699                     break;
700                 case UserManager.ENSURE_VERIFY_APPS:
701                     if (newValue) {
702                         android.provider.Settings.Global.putStringForUser(
703                                 context.getContentResolver(),
704                                 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
705                                 userId);
706                     }
707                     break;
708                 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY:
709                     setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
710                             context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
711                             newValue));
712                     break;
713                 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
714                     // Since Android O, the secure setting is not available to be changed by the
715                     // user. Hence, when the restriction is cleared, we need to reset the state of
716                     // the setting to its default value which is now 1.
717                     setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
718                             context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
719                             newValue));
720                     break;
721                 case UserManager.DISALLOW_RUN_IN_BACKGROUND:
722                     if (newValue) {
723                         final ActivityManager am = context.getSystemService(ActivityManager.class);
724                         if (!am.isProfileForeground(UserHandle.of(userId))
725                                 && userId != UserHandle.USER_SYSTEM) {
726                             try {
727                                 ActivityManager.getService().stopUserExceptCertainProfiles(
728                                         userId, false, null);
729                             } catch (RemoteException e) {
730                                 throw e.rethrowAsRuntimeException();
731                             }
732                         }
733                     }
734                     break;
735                 case UserManager.DISALLOW_SAFE_BOOT:
736                     // Unlike with the other restrictions, we want to propagate the new value to
737                     // the system settings even if it is false. The other restrictions modify
738                     // settings which could be manually changed by the user from the Settings app
739                     // after the policies enforcing these restrictions have been revoked, so we
740                     // leave re-setting of those settings to the user.
741                     android.provider.Settings.Global.putInt(
742                             context.getContentResolver(),
743                             android.provider.Settings.Global.SAFE_BOOT_DISALLOWED,
744                             newValue ? 1 : 0);
745                     break;
746                 case UserManager.DISALLOW_AIRPLANE_MODE:
747                     if (newValue) {
748                         final boolean airplaneMode = Settings.Global.getInt(
749                                 context.getContentResolver(),
750                                 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
751                         if (airplaneMode) {
752                             android.provider.Settings.Global.putInt(
753                                     context.getContentResolver(),
754                                     android.provider.Settings.Global.AIRPLANE_MODE_ON, 0);
755                             // Post the intent.
756                             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
757                             intent.putExtra("state", false);
758                             context.sendBroadcastAsUser(intent, UserHandle.ALL);
759                         }
760                     }
761                     break;
762                 case UserManager.DISALLOW_AMBIENT_DISPLAY:
763                     if (newValue) {
764                         final AmbientDisplayConfiguration config =
765                                 new AmbientDisplayConfiguration(context);
766                         config.disableDozeSettings(userId);
767                     }
768                     break;
769                 case UserManager.DISALLOW_APPS_CONTROL:
770                     // Intentional fall-through
771                 case UserManager.DISALLOW_UNINSTALL_APPS:
772                     final PackageManagerInternal pmi = LocalServices.getService(
773                             PackageManagerInternal.class);
774                     pmi.removeAllNonSystemPackageSuspensions(userId);
775                     pmi.removeAllDistractingPackageRestrictions(userId);
776                     pmi.flushPackageRestrictions(userId);
777                     break;
778             }
779         } finally {
780             Binder.restoreCallingIdentity(id);
781         }
782     }
783 
isSettingRestrictedForUser(Context context, @NonNull String setting, int userId, String value, int callingUid)784     public static boolean isSettingRestrictedForUser(Context context, @NonNull String setting,
785             int userId, String value, int callingUid) {
786         Objects.requireNonNull(setting);
787         final UserManager mUserManager = context.getSystemService(UserManager.class);
788         String restriction;
789         boolean checkAllUser = false;
790         switch (setting) {
791             case android.provider.Settings.Secure.LOCATION_MODE:
792                 if (mUserManager.hasUserRestriction(
793                         UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId))
794                         && callingUid != Process.SYSTEM_UID) {
795                     return true;
796                 } else if (String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(value)) {
797                     return false;
798                 }
799                 restriction = UserManager.DISALLOW_SHARE_LOCATION;
800                 break;
801 
802             case android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS:
803                 if ("0".equals(value)) {
804                     return false;
805                 }
806                 restriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
807                 break;
808 
809             case android.provider.Settings.Global.ADB_ENABLED:
810             case android.provider.Settings.Global.ADB_WIFI_ENABLED:
811                 if ("0".equals(value)) {
812                     return false;
813                 }
814                 restriction = UserManager.DISALLOW_DEBUGGING_FEATURES;
815                 break;
816 
817             case android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB:
818                 if ("1".equals(value)) {
819                     return false;
820                 }
821                 restriction = UserManager.ENSURE_VERIFY_APPS;
822                 break;
823 
824             case android.provider.Settings.Global.PREFERRED_NETWORK_MODE:
825                 restriction = UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
826                 break;
827 
828             case android.provider.Settings.Secure.ALWAYS_ON_VPN_APP:
829             case android.provider.Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN:
830             case android.provider.Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST:
831                 // Allowlist system uid (ConnectivityService) and root uid to change always-on vpn
832                 final int appId = UserHandle.getAppId(callingUid);
833                 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
834                     return false;
835                 }
836                 restriction = UserManager.DISALLOW_CONFIG_VPN;
837                 break;
838 
839             case android.provider.Settings.Global.SAFE_BOOT_DISALLOWED:
840                 if ("1".equals(value)) {
841                     return false;
842                 }
843                 restriction = UserManager.DISALLOW_SAFE_BOOT;
844                 break;
845 
846             case android.provider.Settings.Global.AIRPLANE_MODE_ON:
847                 if ("0".equals(value)) {
848                     return false;
849                 }
850                 restriction = UserManager.DISALLOW_AIRPLANE_MODE;
851                 break;
852 
853             case android.provider.Settings.Secure.DOZE_ENABLED:
854             case android.provider.Settings.Secure.DOZE_ALWAYS_ON:
855             case android.provider.Settings.Secure.DOZE_PICK_UP_GESTURE:
856             case android.provider.Settings.Secure.DOZE_PULSE_ON_LONG_PRESS:
857             case android.provider.Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
858                 if ("0".equals(value)) {
859                     return false;
860                 }
861                 restriction = UserManager.DISALLOW_AMBIENT_DISPLAY;
862                 break;
863 
864             case android.provider.Settings.System.SCREEN_BRIGHTNESS:
865             case android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE:
866                 if (callingUid == Process.SYSTEM_UID) {
867                     return false;
868                 }
869                 restriction = UserManager.DISALLOW_CONFIG_BRIGHTNESS;
870                 break;
871 
872             case android.provider.Settings.Global.AUTO_TIME:
873             case android.provider.Settings.Global.AUTO_TIME_ZONE:
874                 if (callingUid == Process.SYSTEM_UID) {
875                     return false;
876                 }
877                 restriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
878                 break;
879 
880             case android.provider.Settings.System.SCREEN_OFF_TIMEOUT:
881                 if (callingUid == Process.SYSTEM_UID) {
882                     return false;
883                 }
884                 restriction = UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT;
885                 break;
886 
887             case android.provider.Settings.Global.PRIVATE_DNS_MODE:
888             case android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER:
889                 if (callingUid == Process.SYSTEM_UID) {
890                     return false;
891                 }
892                 restriction = UserManager.DISALLOW_CONFIG_PRIVATE_DNS;
893                 break;
894             default:
895                 if (setting.startsWith(Settings.Global.DATA_ROAMING)) {
896                     if ("0".equals(value)) {
897                         return false;
898                     }
899                     restriction = UserManager.DISALLOW_DATA_ROAMING;
900                     break;
901                 }
902                 return false;
903         }
904 
905         if (checkAllUser) {
906             return mUserManager.hasUserRestrictionOnAnyUser(restriction);
907         } else {
908             return mUserManager.hasUserRestriction(restriction, UserHandle.of(userId));
909         }
910     }
911 
dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions)912     public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) {
913         boolean noneSet = true;
914         if (restrictions != null) {
915             for (String key : restrictions.keySet()) {
916                 if (restrictions.getBoolean(key, false)) {
917                     pw.println(prefix + key);
918                     noneSet = false;
919                 }
920             }
921             if (noneSet) {
922                 pw.println(prefix + "none");
923             }
924         } else {
925             pw.println(prefix + "null");
926         }
927     }
928 
929     /**
930      * Moves a particular restriction from one array of restrictions sets to a restriction set,
931      * e.g. for all users.
932      */
moveRestriction(String restrictionKey, SparseArray<RestrictionsSet> sourceRestrictionsSets, RestrictionsSet destRestrictionSet)933     public static void moveRestriction(String restrictionKey,
934             SparseArray<RestrictionsSet> sourceRestrictionsSets,
935             RestrictionsSet destRestrictionSet) {
936         for (int i = 0; i < sourceRestrictionsSets.size(); i++) {
937             final RestrictionsSet sourceRestrictionsSet = sourceRestrictionsSets.valueAt(i);
938             sourceRestrictionsSet.moveRestriction(destRestrictionSet, restrictionKey);
939         }
940     }
941 
942     /**
943      * Returns whether restrictions differ between two bundles.
944      * @param oldRestrictions old bundle of restrictions.
945      * @param newRestrictions new bundle of restrictions
946      * @param restrictions restrictions of interest, if empty, all restrictions are checked.
947      */
restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions, String... restrictions)948     public static boolean restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions,
949             String... restrictions) {
950         if (restrictions.length == 0) {
951             return areEqual(oldRestrictions, newRestrictions);
952         }
953         for (final String restriction : restrictions) {
954             if (oldRestrictions.getBoolean(restriction, false) !=
955                     newRestrictions.getBoolean(restriction, false)) {
956                 return true;
957             }
958         }
959         return false;
960     }
961 
setInstallMarketAppsRestriction(ContentResolver cr, int userId, int settingValue)962     private static void setInstallMarketAppsRestriction(ContentResolver cr, int userId,
963             int settingValue) {
964         android.provider.Settings.Secure.putIntForUser(
965                 cr, android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, settingValue, userId);
966     }
967 
getNewUserRestrictionSetting(Context context, int userId, String userRestriction, boolean newValue)968     private static int getNewUserRestrictionSetting(Context context, int userId,
969                 String userRestriction, boolean newValue) {
970         return (newValue || UserManager.get(context).hasUserRestriction(userRestriction,
971                 UserHandle.of(userId))) ? 0 : 1;
972     }
973 }
974