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