• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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             UserManager.DISALLOW_DEBUGGING_FEATURES
314     );
315 
316     /**
317      * Special user restrictions that are always applied to all users no matter who sets them.
318      */
319     private static final Set<String> PROFILE_GLOBAL_RESTRICTIONS = Sets.newArraySet(
320             UserManager.ENSURE_VERIFY_APPS,
321             UserManager.DISALLOW_AIRPLANE_MODE,
322             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
323             UserManager.DISALLOW_SIM_GLOBALLY
324     );
325 
326     /**
327      * User restrictions available to a device owner whose type is
328      * {@link android.app.admin.DevicePolicyManager#DEVICE_OWNER_TYPE_FINANCED}.
329      */
330     private static final Set<String> FINANCED_DEVICE_OWNER_RESTRICTIONS = Sets.newArraySet(
331             UserManager.DISALLOW_ADD_USER,
332             UserManager.DISALLOW_DEBUGGING_FEATURES,
333             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
334             UserManager.DISALLOW_SAFE_BOOT,
335             UserManager.DISALLOW_CONFIG_DATE_TIME,
336             UserManager.DISALLOW_OUTGOING_CALLS
337     );
338 
339     /**
340      * Returns whether the given restriction name is valid (and logs it if it isn't).
341      */
isValidRestriction(@onNull String restriction)342     public static boolean isValidRestriction(@NonNull String restriction) {
343         if (!USER_RESTRICTIONS.contains(restriction)) {
344             // Log this, with severity depending on the source.
345             final int uid = Binder.getCallingUid();
346             String[] pkgs = null;
347             try {
348                 pkgs = AppGlobals.getPackageManager().getPackagesForUid(uid);
349             } catch (RemoteException e) {
350                 // Ignore
351             }
352             StringBuilder msg = new StringBuilder("Unknown restriction queried by uid ");
353             msg.append(uid);
354             if (pkgs != null && pkgs.length > 0) {
355                 msg.append(" (");
356                 msg.append(pkgs[0]);
357                 if (pkgs.length > 1) {
358                     msg.append(" et al");
359                 }
360                 msg.append(")");
361             }
362             msg.append(": ");
363             msg.append(restriction);
364             if (restriction != null && isSystemApp(uid, pkgs)) {
365                 Slog.wtf(TAG, msg.toString());
366             } else {
367                 Slog.e(TAG, msg.toString());
368             }
369             return false;
370         }
371         return true;
372     }
373 
374     /** Returns whether the given uid (or corresponding packageList) is for a System app. */
isSystemApp(int uid, String[] packageList)375     private static boolean isSystemApp(int uid, String[] packageList) {
376         if (UserHandle.isCore(uid)) {
377             return true;
378         }
379         if (packageList == null) {
380             return false;
381         }
382         final IPackageManager pm = AppGlobals.getPackageManager();
383         for (int i = 0; i < packageList.length; i++) {
384             try {
385                 final int flags = PackageManager.MATCH_UNINSTALLED_PACKAGES
386                         | PackageManager.MATCH_DIRECT_BOOT_AWARE
387                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
388                 final ApplicationInfo appInfo =
389                         pm.getApplicationInfo(packageList[i], flags, UserHandle.getUserId(uid));
390                 if (appInfo != null && appInfo.isSystemApp()) {
391                     return true;
392                 }
393             } catch (RemoteException e) {
394                 // Ignore
395             }
396         }
397         return false;
398     }
399 
writeRestrictions(@onNull XmlSerializer serializer, @Nullable Bundle restrictions, @NonNull String tag)400     public static void writeRestrictions(@NonNull XmlSerializer serializer,
401             @Nullable Bundle restrictions, @NonNull String tag) throws IOException {
402         writeRestrictions(XmlUtils.makeTyped(serializer), restrictions, tag);
403     }
404 
writeRestrictions(@onNull TypedXmlSerializer serializer, @Nullable Bundle restrictions, @NonNull String tag)405     public static void writeRestrictions(@NonNull TypedXmlSerializer serializer,
406             @Nullable Bundle restrictions, @NonNull String tag) throws IOException {
407         if (restrictions == null) {
408             return;
409         }
410 
411         serializer.startTag(null, tag);
412         for (String key : restrictions.keySet()) {
413             if (NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
414                 continue; // Don't persist.
415             }
416             if (USER_RESTRICTIONS.contains(key)) {
417                 if (restrictions.getBoolean(key)) {
418                     serializer.attributeBoolean(null, key, true);
419                 }
420                 continue;
421             }
422             Log.w(TAG, "Unknown user restriction detected: " + key);
423         }
424         serializer.endTag(null, tag);
425     }
426 
readRestrictions(XmlPullParser parser, Bundle restrictions)427     public static void readRestrictions(XmlPullParser parser, Bundle restrictions) {
428         readRestrictions(XmlUtils.makeTyped(parser), restrictions);
429     }
430 
readRestrictions(TypedXmlPullParser parser, Bundle restrictions)431     public static void readRestrictions(TypedXmlPullParser parser, Bundle restrictions) {
432         restrictions.clear();
433         for (String key : USER_RESTRICTIONS) {
434             final boolean value = parser.getAttributeBoolean(null, key, false);
435             if (value) {
436                 restrictions.putBoolean(key, true);
437             }
438         }
439     }
440 
readRestrictions(XmlPullParser parser)441     public static Bundle readRestrictions(XmlPullParser parser) {
442         return readRestrictions(XmlUtils.makeTyped(parser));
443     }
444 
readRestrictions(TypedXmlPullParser parser)445     public static Bundle readRestrictions(TypedXmlPullParser parser) {
446         final Bundle result = new Bundle();
447         readRestrictions(parser, result);
448         return result;
449     }
450 
451     /**
452      * @return {@code in} itself when it's not null, or an empty bundle (which can writable).
453      */
nonNull(@ullable Bundle in)454     public static Bundle nonNull(@Nullable Bundle in) {
455         return in != null ? in : new Bundle();
456     }
457 
458     /**
459      * Returns {@code true} if given bundle is not null and contains {@code true} for a given
460      * restriction.
461      */
contains(@ullable Bundle in, String restriction)462     public static boolean contains(@Nullable Bundle in, String restriction) {
463         return in != null && in.getBoolean(restriction);
464     }
465 
merge(@onNull Bundle dest, @Nullable Bundle in)466     public static void merge(@NonNull Bundle dest, @Nullable Bundle in) {
467         Objects.requireNonNull(dest);
468         Preconditions.checkArgument(dest != in);
469         if (in == null) {
470             return;
471         }
472         for (String key : in.keySet()) {
473             if (in.getBoolean(key, false)) {
474                 dest.putBoolean(key, true);
475             }
476         }
477     }
478 
479     /**
480      * @return true if a restriction is settable by device owner.
481      */
canDeviceOwnerChange(String restriction)482     public static boolean canDeviceOwnerChange(String restriction) {
483         return !IMMUTABLE_BY_OWNERS.contains(restriction);
484     }
485 
486     /**
487      * Checks whether a restriction is settable by a profile owner
488      *
489      * <p> Whether a restriction is settable by a profile owner is a property of the restriction and
490      * defined statically by the restriction. It may depend on other context information, such
491      * as whether the relevant user is the {@link UserManager#isMainUser() MainUser}.
492      *
493      * @param restriction the restrictions to check
494      * @param isMainUser true if the relevant user is the {@link UserManager#isMainUser() MainUser}.
495      *                   Some restrictions can be changed by PO only when it's running on the main
496      *                   user.
497      * @param isProfileOwnerOnOrgOwnedDevice true if the relevant user is the profile owner of an
498      *                                       organization owned device. Some restrictions can only
499      *                                       be set by PO when it's running as the profile owner
500      *                                       on an organization owned device.
501      * @return true if a restriction is settable by a profile owner
502      */
canProfileOwnerChange( String restriction, boolean isMainUser, boolean isProfileOwnerOnOrgOwnedDevice)503     public static boolean canProfileOwnerChange(
504             String restriction,
505             boolean isMainUser,
506             boolean isProfileOwnerOnOrgOwnedDevice) {
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 
524     /**
525      * Checks whether a restriction is settable by a profile owner on the parent instance
526      * of an organization owned device.
527      *
528      * <p> Whether a restriction is settable by a profile owner is a property of the restriction and
529      * defined statically by the restriction.
530      *
531      * <p> Note: This is used to check whether a restriction can be set by a profile owner
532      *     on the parent instance.
533      *
534      * @param restriction the restrictions to check
535      * @return true if a restriction is settable by a profile owner on the parent instance
536      */
canParentOfProfileOwnerOfOrganizationOwnedDeviceChange( String restriction)537     public static boolean canParentOfProfileOwnerOfOrganizationOwnedDeviceChange(
538             String restriction) {
539         return PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS.contains(restriction)
540                 || PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_LOCAL_RESTRICTIONS.contains(restriction);
541     }
542 
543     /**
544      * Returns the user restrictions that default to {@code true} for managed profile owners.
545      */
getDefaultEnabledForManagedProfiles()546     public static @NonNull Set<String> getDefaultEnabledForManagedProfiles() {
547         return DEFAULT_ENABLED_FOR_MANAGED_PROFILES;
548     }
549 
550     /**
551      * @return {@code true} only if the restriction is allowed for financed devices and can be set
552      * by a device owner. Otherwise, {@code false} would be returned.
553      */
canFinancedDeviceOwnerChange(String restriction)554     public static boolean canFinancedDeviceOwnerChange(String restriction) {
555         return FINANCED_DEVICE_OWNER_RESTRICTIONS.contains(restriction)
556                 && canDeviceOwnerChange(restriction);
557     }
558 
559     /**
560      * Whether given user restriction should be enforced globally.
561      */
isGlobal(@serManagerInternal.OwnerType int restrictionOwnerType, String key)562     public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType,
563             String key) {
564         return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && (
565                 MAIN_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
566                 || ((restrictionOwnerType
567                 == UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)
568                 && (PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS.contains(key)))
569                 || PROFILE_GLOBAL_RESTRICTIONS.contains(key)
570                 || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key);
571     }
572 
573     /**
574      * Whether given user restriction should be enforced locally.
575      */
isLocal(@serManagerInternal.OwnerType int restrictionOwnerType, String key)576     public static boolean isLocal(@UserManagerInternal.OwnerType int restrictionOwnerType,
577             String key) {
578         return !isGlobal(restrictionOwnerType, key);
579     }
580 
581     /**
582      * @return true if two Bundles contain the same user restriction.
583      * A null bundle and an empty bundle are considered to be equal.
584      */
areEqual(@ullable Bundle a, @Nullable Bundle b)585     public static boolean areEqual(@Nullable Bundle a, @Nullable Bundle b) {
586         if (a == b) {
587             return true;
588         }
589         if (BundleUtils.isEmpty(a)) {
590             return BundleUtils.isEmpty(b);
591         }
592         if (BundleUtils.isEmpty(b)) {
593             return false;
594         }
595         for (String key : a.keySet()) {
596             if (a.getBoolean(key) != b.getBoolean(key)) {
597                 return false;
598             }
599         }
600         for (String key : b.keySet()) {
601             if (a.getBoolean(key) != b.getBoolean(key)) {
602                 return false;
603             }
604         }
605         return true;
606     }
607 
608     /**
609      * Takes a new use restriction set and the previous set, and apply the restrictions that have
610      * changed.
611      *
612      * <p>Note this method is called by {@link UserManagerService} without holding any locks.
613      */
applyUserRestrictions(Context context, int userId, Bundle newRestrictions, Bundle prevRestrictions)614     public static void applyUserRestrictions(Context context, int userId,
615             Bundle newRestrictions, Bundle prevRestrictions) {
616         for (String key : USER_RESTRICTIONS) {
617             final boolean newValue = newRestrictions.getBoolean(key);
618             final boolean prevValue = prevRestrictions.getBoolean(key);
619 
620             if (newValue != prevValue) {
621                 applyUserRestriction(context, userId, key, newValue);
622             }
623         }
624     }
625 
626     /**
627      * Apply each user restriction.
628      *
629      * <p>See also {@link #isSettingRestrictedForUser()},
630      * which should be in sync with this method.
631      */
applyUserRestriction(Context context, int userId, String key, boolean newValue)632     private static void applyUserRestriction(Context context, int userId, String key,
633             boolean newValue) {
634         if (UserManagerService.DBG) {
635             Log.d(TAG, "Applying user restriction: userId=" + userId
636                     + " key=" + key + " value=" + newValue);
637         }
638         // When certain restrictions are cleared, we don't update the system settings,
639         // because these settings are changeable on the Settings UI and we don't know the original
640         // value -- for example LOCATION_MODE might have been off already when the restriction was
641         // set, and in that case even if the restriction is lifted, changing it to ON would be
642         // wrong.  So just don't do anything in such a case.  If the user hopes to enable location
643         // later, they can do it on the Settings UI.
644         // WARNING: Remember that Settings.Global and Settings.Secure are changeable via adb.
645         // To prevent this from happening for a given user restriction, you have to add a check to
646         // SettingsProvider.isGlobalOrSecureSettingRestrictedForUser.
647 
648         final ContentResolver cr = context.getContentResolver();
649         final long id = Binder.clearCallingIdentity();
650         try {
651             switch (key) {
652                 case UserManager.DISALLOW_DATA_ROAMING:
653                     if (newValue) {
654                         // DISALLOW_DATA_ROAMING user restriction is set.
655 
656                         // Multi sim device.
657                         SubscriptionManager subscriptionManager = context
658                                 .getSystemService(SubscriptionManager.class);
659                         final List<SubscriptionInfo> subscriptionInfoList =
660                             subscriptionManager.getActiveSubscriptionInfoList();
661                         if (subscriptionInfoList != null) {
662                             for (SubscriptionInfo subInfo : subscriptionInfoList) {
663                                 android.provider.Settings.Global.putStringForUser(cr,
664                                     android.provider.Settings.Global.DATA_ROAMING
665                                     + subInfo.getSubscriptionId(), "0", userId);
666                             }
667                         }
668 
669                         // Single sim device.
670                         android.provider.Settings.Global.putStringForUser(cr,
671                             android.provider.Settings.Global.DATA_ROAMING, "0", userId);
672                     }
673                     break;
674                 case UserManager.DISALLOW_SHARE_LOCATION:
675                     if (newValue) {
676                         android.provider.Settings.Secure.putIntForUser(cr,
677                                 android.provider.Settings.Secure.LOCATION_MODE,
678                                 android.provider.Settings.Secure.LOCATION_MODE_OFF,
679                                 userId);
680                     }
681                     break;
682                 case UserManager.DISALLOW_DEBUGGING_FEATURES:
683                     if (newValue) {
684                         // Only disable adb if changing for system user, since it is global
685                         // TODO: should this be admin user?
686                         if (userId == UserHandle.USER_SYSTEM) {
687                             android.provider.Settings.Global.putStringForUser(cr,
688                                     android.provider.Settings.Global.ADB_ENABLED, "0",
689                                     userId);
690                             android.provider.Settings.Global.putStringForUser(cr,
691                                     android.provider.Settings.Global.ADB_WIFI_ENABLED, "0",
692                                     userId);
693                         }
694                     }
695                     break;
696                 case UserManager.ENSURE_VERIFY_APPS:
697                     if (newValue) {
698                         android.provider.Settings.Global.putStringForUser(
699                                 context.getContentResolver(),
700                                 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
701                                 userId);
702                     }
703                     break;
704                 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY:
705                     setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
706                             context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
707                             newValue));
708                     break;
709                 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
710                     // Since Android O, the secure setting is not available to be changed by the
711                     // user. Hence, when the restriction is cleared, we need to reset the state of
712                     // the setting to its default value which is now 1.
713                     setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
714                             context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
715                             newValue));
716                     break;
717                 case UserManager.DISALLOW_RUN_IN_BACKGROUND:
718                     if (newValue) {
719                         final ActivityManager am = context.getSystemService(ActivityManager.class);
720                         if (!am.isProfileForeground(UserHandle.of(userId))
721                                 && userId != UserHandle.USER_SYSTEM) {
722                             try {
723                                 ActivityManager.getService().stopUserExceptCertainProfiles(
724                                         userId, false, null);
725                             } catch (RemoteException e) {
726                                 throw e.rethrowAsRuntimeException();
727                             }
728                         }
729                     }
730                     break;
731                 case UserManager.DISALLOW_SAFE_BOOT:
732                     // Unlike with the other restrictions, we want to propagate the new value to
733                     // the system settings even if it is false. The other restrictions modify
734                     // settings which could be manually changed by the user from the Settings app
735                     // after the policies enforcing these restrictions have been revoked, so we
736                     // leave re-setting of those settings to the user.
737                     android.provider.Settings.Global.putInt(
738                             context.getContentResolver(),
739                             android.provider.Settings.Global.SAFE_BOOT_DISALLOWED,
740                             newValue ? 1 : 0);
741                     break;
742                 case UserManager.DISALLOW_AIRPLANE_MODE:
743                     if (newValue) {
744                         final boolean airplaneMode = Settings.Global.getInt(
745                                 context.getContentResolver(),
746                                 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
747                         if (airplaneMode) {
748                             android.provider.Settings.Global.putInt(
749                                     context.getContentResolver(),
750                                     android.provider.Settings.Global.AIRPLANE_MODE_ON, 0);
751                             // Post the intent.
752                             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
753                             intent.putExtra("state", false);
754                             context.sendBroadcastAsUser(intent, UserHandle.ALL);
755                         }
756                     }
757                     break;
758                 case UserManager.DISALLOW_AMBIENT_DISPLAY:
759                     if (newValue) {
760                         final AmbientDisplayConfiguration config =
761                                 new AmbientDisplayConfiguration(context);
762                         config.disableDozeSettings(userId);
763                     }
764                     break;
765                 case UserManager.DISALLOW_APPS_CONTROL:
766                     // Intentional fall-through
767                 case UserManager.DISALLOW_UNINSTALL_APPS:
768                     final PackageManagerInternal pmi = LocalServices.getService(
769                             PackageManagerInternal.class);
770                     pmi.removeAllNonSystemPackageSuspensions(userId);
771                     pmi.removeAllDistractingPackageRestrictions(userId);
772                     pmi.flushPackageRestrictions(userId);
773                     break;
774             }
775         } finally {
776             Binder.restoreCallingIdentity(id);
777         }
778     }
779 
isSettingRestrictedForUser(Context context, @NonNull String setting, int userId, String value, int callingUid)780     public static boolean isSettingRestrictedForUser(Context context, @NonNull String setting,
781             int userId, String value, int callingUid) {
782         Objects.requireNonNull(setting);
783         final UserManager mUserManager = context.getSystemService(UserManager.class);
784         String restriction;
785         boolean checkAllUser = false;
786         switch (setting) {
787             case android.provider.Settings.Secure.LOCATION_MODE:
788                 if (mUserManager.hasUserRestriction(
789                         UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId))
790                         && callingUid != Process.SYSTEM_UID) {
791                     return true;
792                 } else if (String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(value)) {
793                     return false;
794                 }
795                 restriction = UserManager.DISALLOW_SHARE_LOCATION;
796                 break;
797 
798             case android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS:
799                 if ("0".equals(value)) {
800                     return false;
801                 }
802                 restriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
803                 break;
804 
805             case android.provider.Settings.Global.ADB_ENABLED:
806             case android.provider.Settings.Global.ADB_WIFI_ENABLED:
807                 if ("0".equals(value)) {
808                     return false;
809                 }
810                 restriction = UserManager.DISALLOW_DEBUGGING_FEATURES;
811                 break;
812 
813             case android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB:
814                 if ("1".equals(value)) {
815                     return false;
816                 }
817                 restriction = UserManager.ENSURE_VERIFY_APPS;
818                 break;
819 
820             case android.provider.Settings.Global.PREFERRED_NETWORK_MODE:
821                 restriction = UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
822                 break;
823 
824             case android.provider.Settings.Secure.ALWAYS_ON_VPN_APP:
825             case android.provider.Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN:
826             case android.provider.Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST:
827                 // Allowlist system uid (ConnectivityService) and root uid to change always-on vpn
828                 final int appId = UserHandle.getAppId(callingUid);
829                 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
830                     return false;
831                 }
832                 restriction = UserManager.DISALLOW_CONFIG_VPN;
833                 break;
834 
835             case android.provider.Settings.Global.SAFE_BOOT_DISALLOWED:
836                 if ("1".equals(value)) {
837                     return false;
838                 }
839                 restriction = UserManager.DISALLOW_SAFE_BOOT;
840                 break;
841 
842             case android.provider.Settings.Global.AIRPLANE_MODE_ON:
843                 if ("0".equals(value)) {
844                     return false;
845                 }
846                 restriction = UserManager.DISALLOW_AIRPLANE_MODE;
847                 break;
848 
849             case android.provider.Settings.Secure.DOZE_ENABLED:
850             case android.provider.Settings.Secure.DOZE_ALWAYS_ON:
851             case android.provider.Settings.Secure.DOZE_PICK_UP_GESTURE:
852             case android.provider.Settings.Secure.DOZE_PULSE_ON_LONG_PRESS:
853             case android.provider.Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
854                 if ("0".equals(value)) {
855                     return false;
856                 }
857                 restriction = UserManager.DISALLOW_AMBIENT_DISPLAY;
858                 break;
859 
860             case android.provider.Settings.System.SCREEN_BRIGHTNESS:
861             case android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE:
862                 if (callingUid == Process.SYSTEM_UID) {
863                     return false;
864                 }
865                 restriction = UserManager.DISALLOW_CONFIG_BRIGHTNESS;
866                 break;
867 
868             case android.provider.Settings.Global.AUTO_TIME:
869             case android.provider.Settings.Global.AUTO_TIME_ZONE:
870                 if (callingUid == Process.SYSTEM_UID) {
871                     return false;
872                 }
873                 restriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
874                 break;
875 
876             case android.provider.Settings.System.SCREEN_OFF_TIMEOUT:
877                 if (callingUid == Process.SYSTEM_UID) {
878                     return false;
879                 }
880                 restriction = UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT;
881                 break;
882 
883             case android.provider.Settings.Global.PRIVATE_DNS_MODE:
884             case android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER:
885                 if (callingUid == Process.SYSTEM_UID) {
886                     return false;
887                 }
888                 restriction = UserManager.DISALLOW_CONFIG_PRIVATE_DNS;
889                 break;
890             default:
891                 if (setting.startsWith(Settings.Global.DATA_ROAMING)) {
892                     if ("0".equals(value)) {
893                         return false;
894                     }
895                     restriction = UserManager.DISALLOW_DATA_ROAMING;
896                     break;
897                 }
898                 return false;
899         }
900 
901         if (checkAllUser) {
902             return mUserManager.hasUserRestrictionOnAnyUser(restriction);
903         } else {
904             return mUserManager.hasUserRestriction(restriction, UserHandle.of(userId));
905         }
906     }
907 
dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions)908     public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) {
909         boolean noneSet = true;
910         if (restrictions != null) {
911             for (String key : restrictions.keySet()) {
912                 if (restrictions.getBoolean(key, false)) {
913                     pw.println(prefix + key);
914                     noneSet = false;
915                 }
916             }
917             if (noneSet) {
918                 pw.println(prefix + "none");
919             }
920         } else {
921             pw.println(prefix + "null");
922         }
923     }
924 
925     /**
926      * Moves a particular restriction from one array of restrictions sets to a restriction set,
927      * e.g. for all users.
928      */
moveRestriction(String restrictionKey, SparseArray<RestrictionsSet> sourceRestrictionsSets, RestrictionsSet destRestrictionSet)929     public static void moveRestriction(String restrictionKey,
930             SparseArray<RestrictionsSet> sourceRestrictionsSets,
931             RestrictionsSet destRestrictionSet) {
932         for (int i = 0; i < sourceRestrictionsSets.size(); i++) {
933             final RestrictionsSet sourceRestrictionsSet = sourceRestrictionsSets.valueAt(i);
934             sourceRestrictionsSet.moveRestriction(destRestrictionSet, restrictionKey);
935         }
936     }
937 
938     /**
939      * Returns whether restrictions differ between two bundles.
940      * @param oldRestrictions old bundle of restrictions.
941      * @param newRestrictions new bundle of restrictions
942      * @param restrictions restrictions of interest, if empty, all restrictions are checked.
943      */
restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions, String... restrictions)944     public static boolean restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions,
945             String... restrictions) {
946         if (restrictions.length == 0) {
947             return areEqual(oldRestrictions, newRestrictions);
948         }
949         for (final String restriction : restrictions) {
950             if (oldRestrictions.getBoolean(restriction, false) !=
951                     newRestrictions.getBoolean(restriction, false)) {
952                 return true;
953             }
954         }
955         return false;
956     }
957 
setInstallMarketAppsRestriction(ContentResolver cr, int userId, int settingValue)958     private static void setInstallMarketAppsRestriction(ContentResolver cr, int userId,
959             int settingValue) {
960         android.provider.Settings.Secure.putIntForUser(
961                 cr, android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, settingValue, userId);
962     }
963 
getNewUserRestrictionSetting(Context context, int userId, String userRestriction, boolean newValue)964     private static int getNewUserRestrictionSetting(Context context, int userId,
965                 String userRestriction, boolean newValue) {
966         return (newValue || UserManager.get(context).hasUserRestriction(userRestriction,
967                 UserHandle.of(userId))) ? 0 : 1;
968     }
969 }
970