1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.provider; 18 19 import static android.Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG; 20 import static android.Manifest.permission.READ_DEVICE_CONFIG; 21 import static android.Manifest.permission.WRITE_DEVICE_CONFIG; 22 import static android.Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG; 23 24 import android.Manifest; 25 import android.annotation.CallbackExecutor; 26 import android.annotation.IntDef; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.annotation.RequiresPermission; 30 import android.annotation.SuppressLint; 31 import android.annotation.SystemApi; 32 import android.content.ContentResolver; 33 import android.database.ContentObserver; 34 import android.net.Uri; 35 import com.android.modules.utils.build.SdkLevel; 36 import android.util.ArrayMap; 37 import android.util.Log; 38 import android.util.Pair; 39 40 import com.android.internal.annotations.GuardedBy; 41 42 import java.lang.annotation.ElementType; 43 import java.lang.annotation.Retention; 44 import java.lang.annotation.RetentionPolicy; 45 import java.lang.annotation.Target; 46 47 import java.util.Arrays; 48 import java.util.Collections; 49 import java.util.HashMap; 50 import java.util.HashSet; 51 import java.util.List; 52 import java.util.Map; 53 import java.util.Objects; 54 import java.util.Set; 55 import java.util.concurrent.Executor; 56 57 import android.util.Log; 58 59 import android.provider.aidl.IDeviceConfigManager; 60 import android.provider.DeviceConfigServiceManager; 61 import android.provider.DeviceConfigInitializer; 62 import android.os.IBinder; 63 64 /** 65 * Device level configuration parameters which can be tuned by a separate configuration service. 66 * Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used 67 * by native code and should be pushed to system properties to make them accessible. 68 * 69 * @hide 70 */ 71 @SystemApi 72 public final class DeviceConfig { 73 74 /** 75 * The name of the service that provides the logic to these APIs 76 * 77 * @hide 78 */ 79 public static final String SERVICE_NAME = "device_config_updatable"; 80 81 /** 82 * Namespace for all accessibility related features. 83 * 84 * @hide 85 */ 86 @SystemApi 87 public static final String NAMESPACE_ACCESSIBILITY = "accessibility"; 88 89 /** 90 * Namespace for activity manager related features. These features will be applied 91 * immediately upon change. 92 * 93 * @hide 94 */ 95 @SystemApi 96 public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager"; 97 98 /** 99 * Namespace for activity manager, specific to the "component alias" feature. We needed a 100 * different namespace in order to avoid phonetype from resetting it. 101 * @hide 102 */ 103 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 104 public static final String NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS = "activity_manager_ca"; 105 106 /** 107 * Namespace for features related to auto pin confirmation. 108 * 109 * @hide 110 */ 111 @SystemApi 112 public static final String NAMESPACE_AUTO_PIN_CONFIRMATION = "auto_pin_confirmation"; 113 114 /** 115 * Namespace for all activity manager related features that are used at the native level. 116 * These features are applied at reboot. 117 * 118 * @hide 119 */ 120 @SystemApi 121 public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT = 122 "activity_manager_native_boot"; 123 124 /** 125 * Namespace for AlarmManager configurations. 126 * 127 * @hide 128 */ 129 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 130 public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager"; 131 132 /** 133 * Namespace for all app compat related features. These features will be applied 134 * immediately upon change. 135 * 136 * @hide 137 */ 138 @SystemApi 139 public static final String NAMESPACE_APP_COMPAT = "app_compat"; 140 141 /** 142 * Namespace for all app hibernation related features. 143 * @hide 144 */ 145 @SystemApi 146 public static final String NAMESPACE_APP_HIBERNATION = "app_hibernation"; 147 148 /** 149 * Namespace for all AppSearch related features. 150 * @hide 151 */ 152 @SystemApi 153 public static final String NAMESPACE_APPSEARCH = "appsearch"; 154 155 /** 156 * Namespace for app standby configurations. 157 * 158 * @hide 159 */ 160 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 161 public static final String NAMESPACE_APP_STANDBY = "app_standby"; 162 163 /** 164 * Namespace for all App Cloning related features. 165 * @hide 166 */ 167 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 168 public static final String NAMESPACE_APP_CLONING = "app_cloning"; 169 170 /** 171 * Namespace for AttentionManagerService related features. 172 * 173 * @hide 174 */ 175 @SystemApi 176 public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service"; 177 178 /** 179 * Namespace for autofill feature that provides suggestions across all apps when 180 * the user interacts with input fields. 181 * 182 * @hide 183 */ 184 @SystemApi 185 public static final String NAMESPACE_AUTOFILL = "autofill"; 186 187 /** 188 * Namespace for battery saver feature. 189 * 190 * @hide 191 */ 192 @SystemApi 193 public static final String NAMESPACE_BATTERY_SAVER = "battery_saver"; 194 195 /** 196 * Namespace for holding battery stats configuration. 197 * 198 * @hide 199 */ 200 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 201 public static final String NAMESPACE_BATTERY_STATS = "battery_stats"; 202 203 /** 204 * Namespace for blobstore feature that allows apps to share data blobs. 205 * 206 * @hide 207 */ 208 @SystemApi 209 public static final String NAMESPACE_BLOBSTORE = "blobstore"; 210 211 /** 212 * Namespace for all Bluetooth related features. 213 * 214 * @hide 215 */ 216 @SystemApi 217 public static final String NAMESPACE_BLUETOOTH = "bluetooth"; 218 219 /** 220 * Namespace for features relating to android core experiments team internal usage. 221 * 222 * @hide 223 */ 224 @SystemApi 225 public static final String NAMESPACE_CORE_EXPERIMENTS_TEAM_INTERNAL = "core_experiments_team_internal"; 226 227 /** 228 * Namespace for all camera-related features that are used at the native level. 229 * 230 * @hide 231 */ 232 @SystemApi 233 public static final String NAMESPACE_CAMERA_NATIVE = "camera_native"; 234 235 /** 236 * Namespace for cellular security related features. 237 * 238 * @hide 239 */ 240 @SystemApi 241 public static final String NAMESPACE_CELLULAR_SECURITY = "cellular_security"; 242 243 /** 244 * Namespace for features relating to clipboard. 245 * 246 * @hide 247 */ 248 @SystemApi 249 public static final String NAMESPACE_CLIPBOARD = "clipboard"; 250 251 /** 252 * Namespace for all networking connectivity related features. 253 * 254 * @hide 255 */ 256 @SystemApi 257 public static final String NAMESPACE_CONNECTIVITY = "connectivity"; 258 259 /** 260 * Namespace for CaptivePortalLogin module. 261 * 262 * @hide 263 */ 264 @SystemApi 265 public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login"; 266 267 /** 268 * Namespace for all EdgeTpu related features. 269 * 270 * @hide 271 */ 272 @SystemApi 273 public static final String NAMESPACE_EDGETPU_NATIVE = "edgetpu_native"; 274 275 /** 276 * Namespace for all HealthFitness related features. 277 * 278 * @hide 279 */ 280 @SystemApi 281 public static final String NAMESPACE_HEALTH_FITNESS = "health_fitness"; 282 283 /** 284 * Namespace for Tethering module. 285 * 286 * @hide 287 */ 288 @SystemApi 289 public static final String NAMESPACE_TETHERING = "tethering"; 290 291 292 /** 293 * Namespace for Nearby module. 294 * 295 * @hide 296 */ 297 @SystemApi 298 public static final String NAMESPACE_NEARBY = "nearby"; 299 300 /** 301 * Namespace for content capture feature used by on-device machine intelligence 302 * to provide suggestions in a privacy-safe manner. 303 * 304 * @hide 305 */ 306 @SystemApi 307 public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; 308 309 /** 310 * Namespace for credential manager. 311 * 312 * @hide 313 */ 314 @SystemApi 315 public static final String NAMESPACE_CREDENTIAL = "credential_manager"; 316 317 /** 318 * Namespace for device idle configurations. 319 * 320 * @hide 321 */ 322 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 323 public static final String NAMESPACE_DEVICE_IDLE = "device_idle"; 324 325 /** 326 * Namespace for how dex runs. The feature requires a reboot to reach a clean state. 327 * 328 * @deprecated No longer used 329 * @hide 330 */ 331 @Deprecated 332 @SystemApi 333 public static final String NAMESPACE_DEX_BOOT = "dex_boot"; 334 335 /** 336 * Namespace for display manager related features. The names to access the properties in this 337 * namespace should be defined in {@link android.hardware.display.DisplayManager}. 338 * 339 * @hide 340 */ 341 @SystemApi 342 public static final String NAMESPACE_DISPLAY_MANAGER = "display_manager"; 343 344 /** 345 * Namespace for all Game Driver features. 346 * 347 * @hide 348 */ 349 @SystemApi 350 public static final String NAMESPACE_GAME_DRIVER = "game_driver"; 351 352 /** 353 * Namespace for all HDMI Control features. 354 * 355 * @hide 356 */ 357 @SystemApi 358 public static final String NAMESPACE_HDMI_CONTROL = "hdmi_control"; 359 360 /** 361 * Namespace for all input-related features that are used at the native level. 362 * These features are applied at reboot. 363 * 364 * @hide 365 */ 366 @SystemApi 367 public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot"; 368 369 /** 370 * Namespace for attention-based features provided by on-device machine intelligence. 371 * 372 * @hide 373 */ 374 @SystemApi 375 public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention"; 376 377 /** 378 * Definitions for properties related to Content Suggestions. 379 * 380 * @hide 381 */ 382 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 383 public static final String NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS = 384 "intelligence_content_suggestions"; 385 386 /** 387 * Namespace for JobScheduler configurations. 388 * @hide 389 */ 390 @SystemApi 391 public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler"; 392 393 /** 394 * Namespace for all lmkd related features. 395 * 396 * @hide 397 */ 398 @SystemApi 399 public static final String NAMESPACE_LMKD_NATIVE = "lmkd_native"; 400 401 /** 402 * Namespace for all location related features. 403 * 404 * @hide 405 */ 406 @SystemApi 407 public static final String NAMESPACE_LOCATION = "location"; 408 409 /** 410 * Namespace for all media related features. 411 * 412 * @hide 413 */ 414 @SystemApi 415 public static final String NAMESPACE_MEDIA = "media"; 416 417 /** 418 * Namespace for all media native related features. 419 * 420 * @hide 421 */ 422 @SystemApi 423 public static final String NAMESPACE_MEDIA_NATIVE = "media_native"; 424 425 /** 426 * Namespace for all Kernel Multi-Gen LRU feature. 427 * 428 * @hide 429 */ 430 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 431 public static final String NAMESPACE_MGLRU_NATIVE = "mglru_native"; 432 433 /** 434 * Namespace for all netd related features. 435 * 436 * @hide 437 */ 438 @SystemApi 439 public static final String NAMESPACE_NETD_NATIVE = "netd_native"; 440 441 /** 442 * Namespace for all Android NNAPI related features. 443 * 444 * @hide 445 */ 446 @SystemApi 447 public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native"; 448 449 /** 450 * Namespace for all OnDevicePersonalization related feature. 451 * @hide 452 */ 453 @SystemApi 454 public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization"; 455 456 /** 457 * Namespace for features related to the Package Manager Service. 458 * 459 * @hide 460 */ 461 @SystemApi 462 public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service"; 463 464 /** 465 * Namespace for features related to the Profcollect native Service. 466 * These features are applied at reboot. 467 * 468 * @hide 469 */ 470 @SystemApi 471 public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot"; 472 473 /** 474 * Namespace for features related to Reboot Readiness detection. 475 * 476 * @hide 477 */ 478 @SystemApi 479 public static final String NAMESPACE_REBOOT_READINESS = "reboot_readiness"; 480 481 /** 482 * Namespace for Remote Key Provisioning related features. 483 * 484 * @hide 485 */ 486 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 487 public static final String NAMESPACE_REMOTE_KEY_PROVISIONING_NATIVE = 488 "remote_key_provisioning_native"; 489 490 /** 491 * Namespace for Rollback flags that are applied immediately. 492 * 493 * @hide 494 */ 495 @SystemApi 496 public static final String NAMESPACE_ROLLBACK = "rollback"; 497 498 /** 499 * Namespace for Rollback flags that are applied after a reboot. 500 * 501 * @hide 502 */ 503 @SystemApi 504 public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot"; 505 506 /** 507 * Namespace for Rotation Resolver Manager Service. 508 * 509 * @hide 510 */ 511 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 512 public static final String NAMESPACE_ROTATION_RESOLVER = "rotation_resolver"; 513 514 /** 515 * Namespace for all runtime related features that don't require a reboot to become active. 516 * There are no feature flags using NAMESPACE_RUNTIME. 517 * 518 * @hide 519 */ 520 @SystemApi 521 public static final String NAMESPACE_RUNTIME = "runtime"; 522 523 /** 524 * Namespace for all runtime related features that require system properties for accessing 525 * the feature flags from C++ or Java language code. One example is the app image startup 526 * cache feature use_app_image_startup_cache. 527 * 528 * @hide 529 */ 530 @SystemApi 531 public static final String NAMESPACE_RUNTIME_NATIVE = "runtime_native"; 532 533 /** 534 * Namespace for all runtime native boot related features. Boot in this case refers to the 535 * fact that the properties only take effect after rebooting the device. 536 * 537 * @hide 538 */ 539 @SystemApi 540 public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot"; 541 542 /** 543 * Namespace for system scheduler related features. These features will be applied 544 * immediately upon change. 545 * 546 * @hide 547 */ 548 @SystemApi 549 public static final String NAMESPACE_SCHEDULER = "scheduler"; 550 551 /** 552 * Namespace for all SdkSandbox related features. 553 * @hide 554 */ 555 @SystemApi 556 public static final String NAMESPACE_SDK_SANDBOX = "sdk_sandbox"; 557 558 /** 559 * Namespace for settings statistics features. 560 * 561 * @hide 562 */ 563 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 564 public static final String NAMESPACE_SETTINGS_STATS = "settings_stats"; 565 566 /** 567 * Namespace for all statsd java features that can be applied immediately. 568 * 569 * @hide 570 */ 571 @SystemApi 572 public static final String NAMESPACE_STATSD_JAVA = "statsd_java"; 573 574 /** 575 * Namespace for all statsd java features that are applied on boot. 576 * 577 * @hide 578 */ 579 @SystemApi 580 public static final String NAMESPACE_STATSD_JAVA_BOOT = "statsd_java_boot"; 581 582 /** 583 * Namespace for all statsd native features that can be applied immediately. 584 * 585 * @hide 586 */ 587 @SystemApi 588 public static final String NAMESPACE_STATSD_NATIVE = "statsd_native"; 589 590 /** 591 * Namespace for all statsd native features that are applied on boot. 592 * 593 * @hide 594 */ 595 @SystemApi 596 public static final String NAMESPACE_STATSD_NATIVE_BOOT = "statsd_native_boot"; 597 598 /** 599 * Namespace for storage-related features. 600 * 601 * @deprecated Replace storage namespace with storage_native_boot. 602 * @hide 603 */ 604 @Deprecated 605 @SystemApi 606 public static final String NAMESPACE_STORAGE = "storage"; 607 608 /** 609 * Namespace for storage-related features, including native and boot. 610 * 611 * @hide 612 */ 613 @SystemApi 614 public static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot"; 615 616 /** 617 * Namespace for all AdServices related features. 618 * @hide 619 */ 620 @SystemApi 621 public static final String NAMESPACE_ADSERVICES = "adservices"; 622 623 /** 624 * Namespace for all SurfaceFlinger features that are used at the native level. 625 * These features are applied on boot or after reboot. 626 * 627 * @hide 628 */ 629 @SystemApi 630 public static final String NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT = 631 "surface_flinger_native_boot"; 632 633 /** 634 * Namespace for swcodec native related features. 635 * 636 * @hide 637 */ 638 @SystemApi 639 public static final String NAMESPACE_SWCODEC_NATIVE = "swcodec_native"; 640 641 642 /** 643 * Namespace for System UI related features. 644 * 645 * @hide 646 */ 647 @SystemApi 648 public static final String NAMESPACE_SYSTEMUI = "systemui"; 649 650 /** 651 * Namespace for system time and time zone detection related features / behavior. 652 * 653 * @hide 654 */ 655 @SystemApi 656 public static final String NAMESPACE_SYSTEM_TIME = "system_time"; 657 658 /** 659 * Namespace for TARE configurations. 660 * 661 * @hide 662 */ 663 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 664 public static final String NAMESPACE_TARE = "tare"; 665 666 /** 667 * Telephony related properties. 668 * 669 * @hide 670 */ 671 @SystemApi 672 public static final String NAMESPACE_TELEPHONY = "telephony"; 673 674 /** 675 * Namespace for TextClassifier related features. 676 * 677 * @hide 678 * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS 679 */ 680 @SystemApi 681 public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; 682 683 /** 684 * Namespace for contacts provider related features. 685 * 686 * @hide 687 */ 688 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 689 public static final String NAMESPACE_CONTACTS_PROVIDER = "contacts_provider"; 690 691 /** 692 * Namespace for settings ui related features 693 * 694 * @hide 695 */ 696 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 697 public static final String NAMESPACE_SETTINGS_UI = "settings_ui"; 698 699 /** 700 * Namespace for android related features, i.e. for flags that affect not just a single 701 * component, but the entire system. 702 * 703 * The keys for this namespace are defined in {@link AndroidDeviceConfig}. 704 * 705 * @hide 706 */ 707 @SystemApi 708 public static final String NAMESPACE_ANDROID = "android"; 709 710 /** 711 * Namespace for window manager related features. 712 * 713 * @hide 714 */ 715 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 716 public static final String NAMESPACE_WINDOW_MANAGER = "window_manager"; 717 718 /** 719 * Namespace for window manager features accessible by native code and 720 * loaded once per boot. 721 * 722 * @hide 723 */ 724 @SystemApi 725 public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot"; 726 727 /** 728 * Definitions for selection toolbar related functions. 729 * 730 * @hide 731 */ 732 @SystemApi 733 public static final String NAMESPACE_SELECTION_TOOLBAR = "selection_toolbar"; 734 735 /** 736 * Definitions for voice interaction related functions. 737 * 738 * @hide 739 */ 740 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 741 public static final String NAMESPACE_VOICE_INTERACTION = "voice_interaction"; 742 743 /** 744 * Namespace for DevicePolicyManager related features. 745 * 746 * @hide 747 */ 748 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 749 public static final String NAMESPACE_DEVICE_POLICY_MANAGER = 750 "device_policy_manager"; 751 752 /** 753 * List of namespaces which can be read without READ_DEVICE_CONFIG permission 754 * 755 * @hide 756 */ 757 @NonNull 758 private static final List<String> PUBLIC_NAMESPACES = 759 Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME, NAMESPACE_STATSD_JAVA, 760 NAMESPACE_STATSD_JAVA_BOOT, NAMESPACE_SELECTION_TOOLBAR, NAMESPACE_AUTOFILL, 761 NAMESPACE_DEVICE_POLICY_MANAGER, NAMESPACE_CONTENT_CAPTURE); 762 /** 763 * Privacy related properties definitions. 764 * 765 * @hide 766 */ 767 @SystemApi 768 public static final String NAMESPACE_PRIVACY = "privacy"; 769 770 /** 771 * Namespace for biometrics related features 772 * 773 * @hide 774 */ 775 @SystemApi 776 public static final String NAMESPACE_BIOMETRICS = "biometrics"; 777 778 /** 779 * Permission related properties definitions. 780 * 781 * @hide 782 */ 783 @SystemApi 784 public static final String NAMESPACE_PERMISSIONS = "permissions"; 785 786 /** 787 * Namespace for ota related features. 788 * 789 * @hide 790 */ 791 @SystemApi 792 public static final String NAMESPACE_OTA = "ota"; 793 794 /** 795 * Namespace for all widget related features. 796 * 797 * @hide 798 */ 799 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 800 public static final String NAMESPACE_WIDGET = "widget"; 801 802 /** 803 * Namespace for connectivity thermal power manager features. 804 * 805 * @hide 806 */ 807 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 808 public static final String NAMESPACE_CONNECTIVITY_THERMAL_POWER_MANAGER = 809 "connectivity_thermal_power_manager"; 810 811 /** 812 * Namespace for configuration related features. 813 * 814 * @hide 815 */ 816 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 817 public static final String NAMESPACE_CONFIGURATION = "configuration"; 818 819 /** 820 * LatencyTracker properties definitions. 821 * 822 * @hide 823 */ 824 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 825 public static final String NAMESPACE_LATENCY_TRACKER = "latency_tracker"; 826 827 /** 828 * InteractionJankMonitor properties definitions. 829 * 830 * @hide 831 */ 832 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 833 @SuppressLint("IntentName") 834 public static final String NAMESPACE_INTERACTION_JANK_MONITOR = "interaction_jank_monitor"; 835 836 /** 837 * Namespace for game overlay related features. 838 * 839 * @hide 840 */ 841 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 842 public static final String NAMESPACE_GAME_OVERLAY = "game_overlay"; 843 844 /** 845 * Namespace for Android Virtualization Framework related features accessible by native code. 846 * 847 * @hide 848 */ 849 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 850 public static final String NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE = 851 "virtualization_framework_native"; 852 853 /** 854 * Namespace for Constrain Display APIs related features. 855 * 856 * @hide 857 */ 858 @SystemApi 859 public static final String NAMESPACE_CONSTRAIN_DISPLAY_APIS = "constrain_display_apis"; 860 861 /** 862 * Namespace for App Compat Overrides related features. 863 * 864 * @hide 865 */ 866 @SystemApi 867 public static final String NAMESPACE_APP_COMPAT_OVERRIDES = "app_compat_overrides"; 868 869 /** 870 * Namespace for all ultra wideband (uwb) related features. 871 * 872 * @hide 873 */ 874 @SystemApi 875 public static final String NAMESPACE_UWB = "uwb"; 876 877 /** 878 * Namespace for AmbientContextEventManagerService related features. 879 * 880 * @hide 881 */ 882 @SystemApi 883 public static final String NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE = 884 "ambient_context_manager_service"; 885 886 /** 887 * Namespace for WearableSensingManagerService related features. 888 * 889 * @hide 890 */ 891 @SystemApi 892 public static final String NAMESPACE_WEARABLE_SENSING = 893 "wearable_sensing"; 894 895 /** 896 * Namespace for Vendor System Native related features. 897 * 898 * @hide 899 */ 900 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 901 public static final String NAMESPACE_VENDOR_SYSTEM_NATIVE = "vendor_system_native"; 902 903 /** 904 * Namespace for Vendor System Native Boot related features. 905 * 906 * @hide 907 */ 908 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 909 public static final String NAMESPACE_VENDOR_SYSTEM_NATIVE_BOOT = "vendor_system_native_boot"; 910 911 /** 912 * Namespace for memory safety related features (e.g. MTE) that need a reboot to be applied 913 * 914 * @hide 915 */ 916 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 917 public static final String NAMESPACE_MEMORY_SAFETY_NATIVE_BOOT = "memory_safety_native_boot"; 918 919 /** 920 * Namespace for memory safety related features (e.g. MTE) 921 * 922 * @hide 923 */ 924 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 925 public static final String NAMESPACE_MEMORY_SAFETY_NATIVE = "memory_safety_native"; 926 927 /** 928 * Namespace for wear OS platform features. 929 * 930 * @hide 931 */ 932 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 933 public static final String NAMESPACE_WEAR = "wear"; 934 935 /** 936 * Namespace for the input method manager platform features. 937 * 938 * @hide 939 */ 940 @SystemApi 941 public static final String NAMESPACE_INPUT_METHOD_MANAGER = "input_method_manager"; 942 943 /** 944 * Namespace for backup and restore service related features. 945 * 946 * @hide 947 */ 948 @SystemApi 949 public static final String NAMESPACE_BACKUP_AND_RESTORE = "backup_and_restore"; 950 951 /** 952 * Namespace for ARC App Compat related features. 953 * 954 * @hide 955 */ 956 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 957 public static final String NAMESPACE_ARC_APP_COMPAT = "arc_app_compat"; 958 959 /** 960 * Namespace for remote authentication features. 961 * 962 * @hide 963 */ 964 @SystemApi 965 public static final String NAMESPACE_REMOTE_AUTH = "remote_auth"; 966 967 968 /** 969 * Namespace for tethering module native features. 970 * Flags defined in this namespace are only usable on 971 * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and newer. 972 * On older Android releases, they will not be propagated to native code. 973 * 974 * @hide 975 */ 976 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 977 public static final String NAMESPACE_TETHERING_NATIVE = 978 "tethering_u_or_later_native"; 979 980 /** 981 * Namespace for all near field communication (nfc) related features. 982 * 983 * @hide 984 */ 985 @SystemApi 986 public static final String NAMESPACE_NFC = "nfc"; 987 988 /** 989 * The modes that can be used when disabling syncs to the 'config' settings. 990 * @hide 991 */ 992 @IntDef(prefix = "SYNC_DISABLED_MODE_", 993 value = { SYNC_DISABLED_MODE_NONE, SYNC_DISABLED_MODE_PERSISTENT, 994 SYNC_DISABLED_MODE_UNTIL_REBOOT }) 995 @Retention(RetentionPolicy.SOURCE) 996 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 997 public @interface SyncDisabledMode {} 998 999 /** 1000 * Sync is not disabled. 1001 * 1002 * @hide 1003 */ 1004 @SystemApi 1005 public static final int SYNC_DISABLED_MODE_NONE = 0; 1006 1007 /** 1008 * Disabling of Config bulk update / syncing is persistent, i.e. it survives a device 1009 * reboot. 1010 * 1011 * @hide 1012 */ 1013 @SystemApi 1014 public static final int SYNC_DISABLED_MODE_PERSISTENT = 1; 1015 1016 /** 1017 * Disabling of Config bulk update / syncing is not persistent, i.e. it will 1018 * not survive a device reboot. 1019 * 1020 * @hide 1021 */ 1022 @SystemApi 1023 public static final int SYNC_DISABLED_MODE_UNTIL_REBOOT = 2; 1024 1025 private static final Object sLock = new Object(); 1026 @GuardedBy("sLock") 1027 private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners = 1028 new ArrayMap<>(); 1029 @GuardedBy("sLock") 1030 private static Map<String, Pair<ContentObserver, Integer>> sNamespaces = new HashMap<>(); 1031 private static final String TAG = "DeviceConfig"; 1032 1033 private static final DeviceConfigDataStore sDataStore = new SettingsConfigDataStore(); 1034 1035 private static final String DEVICE_CONFIG_OVERRIDES_NAMESPACE = 1036 "device_config_overrides"; 1037 1038 /** 1039 * Interface for monitoring callback functions. 1040 * 1041 * @hide 1042 */ 1043 @SystemApi 1044 public interface MonitorCallback { 1045 /** 1046 * Callback for updating a namespace. 1047 * Reports that a config in the given namespace has changed. 1048 * Isn't called for {@link DeviceConfig#getPublicNamespaces() public namespaces}. 1049 * 1050 * @param updatedNamespace the namespace, within which at least one config has changed. 1051 * @hide 1052 */ 1053 @SystemApi onNamespaceUpdate(@onNull String updatedNamespace)1054 void onNamespaceUpdate(@NonNull String updatedNamespace); 1055 1056 /** 1057 * Callback for accessing device config. 1058 * Reports an access to a the given namespace and the given calling package. 1059 * Isn't called for {@link DeviceConfig#getPublicNamespaces() public namespaces}. 1060 * 1061 * @param callingPackage the calling package id. 1062 * @param namespace the namespace, within which one of its config has been accessed. 1063 * @hide 1064 */ 1065 @SystemApi onDeviceConfigAccess(@onNull String callingPackage, @NonNull String namespace)1066 void onDeviceConfigAccess(@NonNull String callingPackage, @NonNull String namespace); 1067 } 1068 1069 // Should never be invoked DeviceConfig()1070 private DeviceConfig() { 1071 } 1072 1073 /** 1074 * Look up the value of a property for a particular namespace. 1075 * 1076 * @param namespace The namespace containing the property to look up. 1077 * @param name The name of the property to look up. 1078 * @return the corresponding value, or null if not present. 1079 * @hide 1080 */ 1081 @SystemApi 1082 @Nullable getProperty(@onNull String namespace, @NonNull String name)1083 public static String getProperty(@NonNull String namespace, @NonNull String name) { 1084 // Fetch all properties for the namespace at once and cache them in the local process, so we 1085 // incur the cost of the IPC less often. Lookups happen much more frequently than updates, 1086 // and we want to optimize the former. 1087 return getProperties(namespace, name).getString(name, null); 1088 } 1089 1090 /** 1091 * Look up the values of multiple properties for a particular namespace. The lookup is atomic, 1092 * such that the values of these properties cannot change between the time when the first is 1093 * fetched and the time when the last is fetched. 1094 * <p> 1095 * Each call to {@link #setProperties(Properties)} is also atomic and ensures that either none 1096 * or all of the change is picked up here, but never only part of it. 1097 * 1098 * If there are any local overrides applied, they will take precedence over underlying values. 1099 * 1100 * @param namespace The namespace containing the properties to look up. 1101 * @param names The names of properties to look up, or empty to fetch all properties for the 1102 * given namespace. 1103 * @return {@link Properties} object containing the requested properties. This reflects the 1104 * state of these properties at the time of the lookup, and is not updated to reflect any 1105 * future changes. The keyset of this Properties object will contain only the intersection 1106 * of properties already set and properties requested via the names parameter. Properties 1107 * that are already set but were not requested will not be contained here. Properties that 1108 * are not set, but were requested will not be contained here either. 1109 * @hide 1110 */ 1111 @SystemApi 1112 @NonNull 1113 @RequiresPermission(READ_DEVICE_CONFIG) getProperties(@onNull String namespace, @NonNull String... names)1114 public static Properties getProperties(@NonNull String namespace, @NonNull String... names) { 1115 Properties properties = getPropertiesWithoutOverrides(namespace, names); 1116 if (SdkLevel.isAtLeastV()) { 1117 applyOverrides(properties); 1118 } 1119 return properties; 1120 } 1121 1122 @NonNull getPropertiesWithoutOverrides(@onNull String namespace, @NonNull String... names)1123 private static Properties getPropertiesWithoutOverrides(@NonNull String namespace, 1124 @NonNull String... names) { 1125 return sDataStore.getProperties(namespace, names); 1126 } 1127 applyOverrides(@onNull Properties properties)1128 private static void applyOverrides(@NonNull Properties properties) { 1129 Properties overrides = 1130 getPropertiesWithoutOverrides(DEVICE_CONFIG_OVERRIDES_NAMESPACE); 1131 1132 final String prefix = properties.getNamespace() + ':'; 1133 final int prefixLength = prefix.length(); 1134 1135 for (var override : overrides.getMap().entrySet()) { 1136 String fullKey = override.getKey(); 1137 String value = override.getValue(); 1138 if (value != null && fullKey.startsWith(prefix)) { 1139 properties.setString(fullKey.substring(prefixLength), value); 1140 } 1141 } 1142 } 1143 1144 /** 1145 * List all stored flags. 1146 * 1147 * The keys take the form {@code namespace/name}, and the values are the flag values. 1148 * 1149 * @hide 1150 */ 1151 @SystemApi 1152 @NonNull getAllProperties()1153 public static Set<Properties> getAllProperties() { 1154 Map<String, String> properties = sDataStore.getAllProperties(); 1155 Map<String, Map<String, String>> propertyMaps = new HashMap<>(); 1156 for (String flag : properties.keySet()) { 1157 String[] namespaceAndFlag = flag.split("/"); 1158 String namespace = namespaceAndFlag[0]; 1159 String flagName = namespaceAndFlag[1]; 1160 String override = 1161 getProperty(DEVICE_CONFIG_OVERRIDES_NAMESPACE, namespace + ":" + flagName); 1162 1163 String value = override != null ? override : properties.get(flag); 1164 1165 if (!propertyMaps.containsKey(namespace)) { 1166 propertyMaps.put(namespace, new HashMap<>()); 1167 } 1168 propertyMaps.get(namespace).put(flagName, value); 1169 } 1170 1171 HashSet<Properties> result = new HashSet<>(); 1172 for (Map.Entry<String, Map<String, String>> entry : propertyMaps.entrySet()) { 1173 result.add(new Properties(entry.getKey(), entry.getValue())); 1174 } 1175 return result; 1176 } 1177 1178 /** 1179 * Look up the String value of a property for a particular namespace. 1180 * 1181 * @param namespace The namespace containing the property to look up. 1182 * @param name The name of the property to look up. 1183 * @param defaultValue The value to return if the property does not exist or has no non-null 1184 * value. 1185 * @return the corresponding value, or defaultValue if none exists. 1186 * @hide 1187 */ 1188 @SystemApi 1189 @RequiresPermission(READ_DEVICE_CONFIG) 1190 @Nullable getString(@onNull String namespace, @NonNull String name, @Nullable String defaultValue)1191 public static String getString(@NonNull String namespace, @NonNull String name, 1192 @Nullable String defaultValue) { 1193 String value = getProperty(namespace, name); 1194 return value != null ? value : defaultValue; 1195 } 1196 1197 /** 1198 * Look up the boolean value of a property for a particular namespace. 1199 * 1200 * @param namespace The namespace containing the property to look up. 1201 * @param name The name of the property to look up. 1202 * @param defaultValue The value to return if the property does not exist or has no non-null 1203 * value. 1204 * @return the corresponding value, or defaultValue if none exists. 1205 * @hide 1206 */ 1207 @SystemApi getBoolean(@onNull String namespace, @NonNull String name, boolean defaultValue)1208 public static boolean getBoolean(@NonNull String namespace, @NonNull String name, 1209 boolean defaultValue) { 1210 String value = getProperty(namespace, name); 1211 return value != null ? Boolean.parseBoolean(value) : defaultValue; 1212 } 1213 1214 /** 1215 * Look up the int value of a property for a particular namespace. 1216 * 1217 * @param namespace The namespace containing the property to look up. 1218 * @param name The name of the property to look up. 1219 * @param defaultValue The value to return if the property does not exist, has no non-null 1220 * value, or fails to parse into an int. 1221 * @return the corresponding value, or defaultValue if either none exists or it does not parse. 1222 * @hide 1223 */ 1224 @SystemApi 1225 @RequiresPermission(READ_DEVICE_CONFIG) getInt(@onNull String namespace, @NonNull String name, int defaultValue)1226 public static int getInt(@NonNull String namespace, @NonNull String name, int defaultValue) { 1227 String value = getProperty(namespace, name); 1228 if (value == null) { 1229 return defaultValue; 1230 } 1231 try { 1232 return Integer.parseInt(value); 1233 } catch (NumberFormatException e) { 1234 Log.e(TAG, "Parsing integer failed for " + namespace + ":" + name); 1235 return defaultValue; 1236 } 1237 } 1238 1239 /** 1240 * Look up the long value of a property for a particular namespace. 1241 * 1242 * @param namespace The namespace containing the property to look up. 1243 * @param name The name of the property to look up. 1244 * @param defaultValue The value to return if the property does not exist, has no non-null 1245 * value, or fails to parse into a long. 1246 * @return the corresponding value, or defaultValue if either none exists or it does not parse. 1247 * @hide 1248 */ 1249 @SystemApi 1250 @RequiresPermission(READ_DEVICE_CONFIG) getLong(@onNull String namespace, @NonNull String name, long defaultValue)1251 public static long getLong(@NonNull String namespace, @NonNull String name, long defaultValue) { 1252 String value = getProperty(namespace, name); 1253 if (value == null) { 1254 return defaultValue; 1255 } 1256 try { 1257 return Long.parseLong(value); 1258 } catch (NumberFormatException e) { 1259 Log.e(TAG, "Parsing long failed for " + namespace + ":" + name); 1260 return defaultValue; 1261 } 1262 } 1263 1264 /** 1265 * Look up the float value of a property for a particular namespace. 1266 * 1267 * @param namespace The namespace containing the property to look up. 1268 * @param name The name of the property to look up. 1269 * @param defaultValue The value to return if the property does not exist, has no non-null 1270 * value, or fails to parse into a float. 1271 * @return the corresponding value, or defaultValue if either none exists or it does not parse. 1272 * @hide 1273 */ 1274 @SystemApi 1275 @RequiresPermission(READ_DEVICE_CONFIG) getFloat(@onNull String namespace, @NonNull String name, float defaultValue)1276 public static float getFloat(@NonNull String namespace, @NonNull String name, 1277 float defaultValue) { 1278 String value = getProperty(namespace, name); 1279 if (value == null) { 1280 return defaultValue; 1281 } 1282 try { 1283 return Float.parseFloat(value); 1284 } catch (NumberFormatException e) { 1285 Log.e(TAG, "Parsing float failed for " + namespace + ":" + name); 1286 return defaultValue; 1287 } 1288 } 1289 1290 /** 1291 * Set flag {@code namespace/name} to {@code value}, and ignores server-updates for this flag. 1292 * 1293 * Can still be called even if there is no underlying value set. 1294 * 1295 * Returns {@code true} if successful, or {@code false} if the storage implementation throws 1296 * errors. 1297 * 1298 * @hide 1299 */ 1300 @SystemApi 1301 @RequiresPermission(WRITE_DEVICE_CONFIG) setLocalOverride(@onNull String namespace, @NonNull String name, @NonNull String value)1302 public static boolean setLocalOverride(@NonNull String namespace, @NonNull String name, 1303 @NonNull String value) { 1304 return setProperty(DEVICE_CONFIG_OVERRIDES_NAMESPACE, namespace + ":" + name, value, false); 1305 } 1306 1307 /** 1308 * Clear all local sticky overrides. 1309 * 1310 * @hide 1311 */ 1312 @SystemApi 1313 @RequiresPermission(WRITE_DEVICE_CONFIG) clearAllLocalOverrides()1314 public static void clearAllLocalOverrides() { 1315 Properties overrides = getProperties(DEVICE_CONFIG_OVERRIDES_NAMESPACE); 1316 for (String overrideName : overrides.getKeyset()) { 1317 deleteProperty(DEVICE_CONFIG_OVERRIDES_NAMESPACE, overrideName); 1318 } 1319 } 1320 1321 /** 1322 * Clear local sticky override for flag {@code namespace/name}. 1323 * 1324 * @hide 1325 */ 1326 @SystemApi 1327 @RequiresPermission(WRITE_DEVICE_CONFIG) clearLocalOverride(@onNull String namespace, @NonNull String name)1328 public static void clearLocalOverride(@NonNull String namespace, 1329 @NonNull String name) { 1330 deleteProperty(DEVICE_CONFIG_OVERRIDES_NAMESPACE, namespace + ":" + name); 1331 } 1332 1333 /** 1334 * Return a map containing all flags that have been overridden. 1335 * 1336 * The keys of the outer map are namespaces. They keys of the inner maps are 1337 * flag names. The values of the inner maps are the underlying flag values 1338 * (not to be confused with their overridden values). 1339 * 1340 * @hide 1341 */ 1342 @NonNull 1343 @SystemApi getUnderlyingValuesForOverriddenFlags()1344 public static Map<String, Map<String, String>> getUnderlyingValuesForOverriddenFlags() { 1345 Properties overrides = getProperties(DEVICE_CONFIG_OVERRIDES_NAMESPACE); 1346 HashMap<String, Map<String, String>> result = new HashMap<>(); 1347 for (Map.Entry<String, String> entry : overrides.getPropertyValues().entrySet()) { 1348 String[] namespaceAndFlag = entry.getKey().split(":"); 1349 String namespace = namespaceAndFlag[0]; 1350 String flag = namespaceAndFlag[1]; 1351 1352 String actualValue = 1353 getPropertiesWithoutOverrides(namespace, flag) 1354 .getString(flag, null); 1355 if (result.get(namespace) != null) { 1356 result.get(namespace).put(flag, actualValue); 1357 } else { 1358 HashMap<String, String> innerMap = new HashMap<>(); 1359 innerMap.put(flag, actualValue); 1360 result.put(namespace, innerMap); 1361 } 1362 } 1363 return result; 1364 } 1365 1366 /** 1367 * Create a new property with the provided name and value in the provided namespace, or 1368 * update the value of such a property if it already exists. The same name can exist in multiple 1369 * namespaces and might have different values in any or all namespaces. 1370 * <p> 1371 * The method takes an argument indicating whether to make the value the default for this 1372 * property. 1373 * <p> 1374 * All properties stored for a particular scope can be reverted to their default values 1375 * by passing the namespace to {@link #resetToDefaults(int, String)}. 1376 * 1377 * @param namespace The namespace containing the property to create or update. 1378 * @param name The name of the property to create or update. 1379 * @param value The value to store for the property. 1380 * @param makeDefault Whether to make the new value the default one. 1381 * @return {@code true} if the value was set, {@code false} if the storage implementation throws 1382 * errors. 1383 * @hide 1384 * @see #resetToDefaults(int, String). 1385 */ 1386 @SystemApi 1387 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, WRITE_ALLOWLISTED_DEVICE_CONFIG}) setProperty(@onNull String namespace, @NonNull String name, @Nullable String value, boolean makeDefault)1388 public static boolean setProperty(@NonNull String namespace, @NonNull String name, 1389 @Nullable String value, boolean makeDefault) { 1390 return sDataStore.setProperty(namespace, name, value, makeDefault); 1391 } 1392 1393 /** 1394 * Set all of the properties for a specific namespace. Pre-existing properties will be updated 1395 * and new properties will be added if necessary. Any pre-existing properties for the specific 1396 * namespace which are not part of the provided {@link Properties} object will be deleted from 1397 * the namespace. These changes are all applied atomically, such that no calls to read or reset 1398 * these properties can happen in the middle of this update. 1399 * <p> 1400 * Each call to {@link #getProperties(String, String...)} is also atomic and ensures that either 1401 * none or all of this update is picked up, but never only part of it. 1402 * 1403 * @param properties the complete set of properties to set for a specific namespace. 1404 * @throws BadConfigException if the provided properties are banned by RescueParty. 1405 * @return {@code true} if the values were set, {@code false} otherwise. 1406 * @hide 1407 */ 1408 @SystemApi 1409 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, WRITE_ALLOWLISTED_DEVICE_CONFIG}) setProperties(@onNull Properties properties)1410 public static boolean setProperties(@NonNull Properties properties) throws BadConfigException { 1411 return sDataStore.setProperties(properties); 1412 } 1413 1414 /** 1415 * Delete a property with the provided name and value in the provided namespace 1416 * 1417 * @param namespace The namespace containing the property to delete. 1418 * @param name The name of the property to delete. 1419 * @return {@code true} if the property was deleted or it did not exist in the first place. 1420 * Return {@code false} if the storage implementation throws errors. 1421 * @hide 1422 */ 1423 @SystemApi 1424 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, WRITE_ALLOWLISTED_DEVICE_CONFIG}) deleteProperty(@onNull String namespace, @NonNull String name)1425 public static boolean deleteProperty(@NonNull String namespace, @NonNull String name) { 1426 return sDataStore.deleteProperty(namespace, name); 1427 } 1428 1429 /** 1430 * Reset properties to their default values by removing the underlying values. 1431 * <p> 1432 * The method accepts an optional namespace parameter. If provided, only properties set within 1433 * that namespace will be reset. Otherwise, all properties will be reset. 1434 * <p> 1435 * Note: This method should only be used by {@link com.android.server.RescueParty}. It was 1436 * designed to be used in the event of boot or crash loops caused by flag changes. It does not 1437 * revert flag values to defaults - instead it removes the property entirely which causes the 1438 * consumer of the flag to use hardcoded defaults upon retrieval. 1439 * <p> 1440 * To clear values for a namespace without removing the underlying properties, construct a 1441 * {@link Properties} object with the caller's namespace and either an empty flag map, or some 1442 * snapshot of flag values. Then use {@link #setProperties(Properties)} to remove all flags 1443 * under the namespace, or set them to the values in the snapshot. 1444 * <p> 1445 * To revert values for testing, one should mock DeviceConfig using 1446 * {@link com.android.server.testables.TestableDeviceConfig} where possible. Otherwise, fallback 1447 * to using {@link #setProperties(Properties)} as outlined above. 1448 * 1449 * @param resetMode The reset mode to use. 1450 * @param namespace Optionally, the specific namespace which resets will be limited to. 1451 * @hide 1452 * @see #setProperty(String, String, String, boolean) 1453 */ 1454 @SystemApi 1455 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, WRITE_ALLOWLISTED_DEVICE_CONFIG}) resetToDefaults(int resetMode, @Nullable String namespace)1456 public static void resetToDefaults(int resetMode, @Nullable String namespace) { 1457 sDataStore.resetToDefaults(resetMode, namespace); 1458 } 1459 1460 /** 1461 * Disables or re-enables bulk modifications ({@link #setProperties(Properties)}) to device 1462 * config values. This is intended for use during tests to prevent a sync operation clearing 1463 * config values which could influence the outcome of the tests, i.e. by changing behavior. 1464 * 1465 * @param syncDisabledMode the mode to use, see {@link Settings.Config#SYNC_DISABLED_MODE_NONE}, 1466 * {@link Settings.Config#SYNC_DISABLED_MODE_PERSISTENT} and {@link 1467 * Settings.Config#SYNC_DISABLED_MODE_UNTIL_REBOOT} 1468 * 1469 * @see #getSyncDisabledMode() 1470 * @hide 1471 */ 1472 @SystemApi 1473 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, READ_WRITE_SYNC_DISABLED_MODE_CONFIG}) setSyncDisabledMode(int syncDisabledMode)1474 public static void setSyncDisabledMode(int syncDisabledMode) { 1475 sDataStore.setSyncDisabledMode(syncDisabledMode); 1476 } 1477 1478 /** 1479 * Returns the current mode of sync disabling. 1480 * 1481 * @see #setSyncDisabledMode(int) 1482 * @hide 1483 */ 1484 @SystemApi 1485 @RequiresPermission(anyOf = {WRITE_DEVICE_CONFIG, READ_WRITE_SYNC_DISABLED_MODE_CONFIG}) getSyncDisabledMode()1486 public static int getSyncDisabledMode() { 1487 return sDataStore.getSyncDisabledMode(); 1488 } 1489 1490 /** 1491 * Add a listener for property changes. 1492 * <p> 1493 * This listener will be called whenever properties in the specified namespace change. Callbacks 1494 * will be made on the specified executor. Future calls to this method with the same listener 1495 * will replace the old namespace and executor. Remove the listener entirely by calling 1496 * {@link #removeOnPropertiesChangedListener(OnPropertiesChangedListener)}. 1497 * 1498 * @param namespace The namespace containing properties to monitor. 1499 * @param executor The executor which will be used to run callbacks. 1500 * @param onPropertiesChangedListener The listener to add. 1501 * @hide 1502 * @see #removeOnPropertiesChangedListener(OnPropertiesChangedListener) 1503 */ 1504 @SystemApi addOnPropertiesChangedListener( @onNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertiesChangedListener onPropertiesChangedListener)1505 public static void addOnPropertiesChangedListener( 1506 @NonNull String namespace, 1507 @NonNull @CallbackExecutor Executor executor, 1508 @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { 1509 synchronized (sLock) { 1510 Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener); 1511 if (oldNamespace == null) { 1512 // Brand new listener, add it to the list. 1513 sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor)); 1514 incrementNamespace(namespace); 1515 } else if (namespace.equals(oldNamespace.first)) { 1516 // Listener is already registered for this namespace, update executor just in case. 1517 sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor)); 1518 } else { 1519 // Update this listener from an old namespace to the new one. 1520 decrementNamespace(sListeners.get(onPropertiesChangedListener).first); 1521 sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor)); 1522 incrementNamespace(namespace); 1523 } 1524 } 1525 } 1526 1527 /** 1528 * Remove a listener for property changes. The listener will receive no further notification of 1529 * property changes. 1530 * 1531 * @param onPropertiesChangedListener The listener to remove. 1532 * @hide 1533 * @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener) 1534 */ 1535 @SystemApi removeOnPropertiesChangedListener( @onNull OnPropertiesChangedListener onPropertiesChangedListener)1536 public static void removeOnPropertiesChangedListener( 1537 @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { 1538 Objects.requireNonNull(onPropertiesChangedListener); 1539 synchronized (sLock) { 1540 if (sListeners.containsKey(onPropertiesChangedListener)) { 1541 decrementNamespace(sListeners.get(onPropertiesChangedListener).first); 1542 sListeners.remove(onPropertiesChangedListener); 1543 } 1544 } 1545 } 1546 1547 /** 1548 * Setter callback for monitoring Config table. 1549 * 1550 * @param executor the {@link Executor} on which to invoke the callback 1551 * @param callback callback to set 1552 * 1553 * @hide 1554 */ 1555 @SystemApi 1556 @RequiresPermission(Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) setMonitorCallback( @onNull ContentResolver resolver, @NonNull @CallbackExecutor Executor executor, @NonNull MonitorCallback callback)1557 public static void setMonitorCallback( 1558 @NonNull ContentResolver resolver, 1559 @NonNull @CallbackExecutor Executor executor, 1560 @NonNull MonitorCallback callback) { 1561 sDataStore.setMonitorCallback(resolver, executor, callback); 1562 } 1563 1564 /** 1565 * Clear callback for monitoring Config table. 1566 * this may only be used to clear callback function registered by 1567 * {@link DeviceConfig#setMonitorCallback} 1568 * @hide 1569 */ 1570 @SystemApi 1571 @RequiresPermission(Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) clearMonitorCallback(@onNull ContentResolver resolver)1572 public static void clearMonitorCallback(@NonNull ContentResolver resolver) { 1573 sDataStore.clearMonitorCallback(resolver); 1574 } 1575 1576 /** 1577 * Increment the count used to represent the number of listeners subscribed to the given 1578 * namespace. If this is the first (i.e. incrementing from 0 to 1) for the given namespace, a 1579 * ContentObserver is registered. 1580 * 1581 * @param namespace The namespace to increment the count for. 1582 */ 1583 @GuardedBy("sLock") incrementNamespace(@onNull String namespace)1584 private static void incrementNamespace(@NonNull String namespace) { 1585 Objects.requireNonNull(namespace); 1586 Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace); 1587 if (namespaceCount != null) { 1588 sNamespaces.put(namespace, new Pair<>(namespaceCount.first, namespaceCount.second + 1)); 1589 } else { 1590 // This is a new namespace, register a ContentObserver for it. 1591 ContentObserver contentObserver = new ContentObserver(null) { 1592 @Override 1593 public void onChange(boolean selfChange, Uri uri) { 1594 if (uri != null) { 1595 handleChange(uri); 1596 } 1597 } 1598 }; 1599 sDataStore 1600 .registerContentObserver(namespace, true, contentObserver); 1601 sNamespaces.put(namespace, new Pair<>(contentObserver, 1)); 1602 } 1603 } 1604 1605 /** 1606 * Decrement the count used to represent the number of listeners subscribed to the given 1607 * namespace. If this is the final decrement call (i.e. decrementing from 1 to 0) for the given 1608 * namespace, the ContentObserver that had been tracking it will be removed. 1609 * 1610 * @param namespace The namespace to decrement the count for. 1611 */ 1612 @GuardedBy("sLock") decrementNamespace(@onNull String namespace)1613 private static void decrementNamespace(@NonNull String namespace) { 1614 Objects.requireNonNull(namespace); 1615 Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace); 1616 if (namespaceCount == null) { 1617 // This namespace is not registered and does not need to be decremented 1618 return; 1619 } else if (namespaceCount.second > 1) { 1620 sNamespaces.put(namespace, new Pair<>(namespaceCount.first, namespaceCount.second - 1)); 1621 } else { 1622 // Decrementing a namespace to zero means we no longer need its ContentObserver. 1623 sDataStore.unregisterContentObserver(namespaceCount.first); 1624 sNamespaces.remove(namespace); 1625 } 1626 } 1627 handleChange(@onNull Uri uri)1628 private static void handleChange(@NonNull Uri uri) { 1629 Objects.requireNonNull(uri); 1630 List<String> pathSegments = uri.getPathSegments(); 1631 // pathSegments(0) is "config" 1632 final String namespace = pathSegments.get(1); 1633 final Properties properties; 1634 if (pathSegments.size() > 2) { 1635 String[] keys = new String[pathSegments.size() - 2]; 1636 for (int i = 2; i < pathSegments.size(); ++i) { 1637 keys[i - 2] = pathSegments.get(i); 1638 } 1639 1640 try { 1641 properties = getProperties(namespace, keys); 1642 } catch (SecurityException e) { 1643 // Silently failing to not crash binder or listener threads. 1644 Log.e(TAG, "OnPropertyChangedListener update failed: permission violation."); 1645 return; 1646 } 1647 1648 // Make sure all keys are present. 1649 for (String key : keys) { 1650 properties.setString(key, properties.getString(key, null)); 1651 } 1652 } else { 1653 properties = new Properties.Builder(namespace).build(); 1654 } 1655 1656 synchronized (sLock) { 1657 for (int i = 0; i < sListeners.size(); i++) { 1658 if (namespace.equals(sListeners.valueAt(i).first)) { 1659 final OnPropertiesChangedListener listener = sListeners.keyAt(i); 1660 sListeners.valueAt(i).second.execute(() -> { 1661 listener.onPropertiesChanged(properties); 1662 }); 1663 } 1664 } 1665 } 1666 } 1667 1668 /** 1669 * Returns list of namespaces that can be read without READ_DEVICE_CONFIG_PERMISSION; 1670 * @hide 1671 */ 1672 @SystemApi getPublicNamespaces()1673 public static @NonNull List<String> getPublicNamespaces() { 1674 return PUBLIC_NAMESPACES; 1675 } 1676 1677 /** 1678 * Returns list of flags that can be written with adb as non-root. 1679 * @hide 1680 */ 1681 @SystemApi getAdbWritableFlags()1682 public static @NonNull Set<String> getAdbWritableFlags() { 1683 return WritableFlags.ALLOWLIST; 1684 } 1685 1686 /** 1687 * Interface for monitoring changes to properties. Implementations will receive callbacks when 1688 * properties change, including a {@link Properties} object which contains a single namespace 1689 * and all of the properties which changed for that namespace. This includes properties which 1690 * were added, updated, or deleted. This is not necessarily a complete list of all properties 1691 * belonging to the namespace, as properties which don't change are omitted. 1692 * <p> 1693 * Override {@link #onPropertiesChanged(Properties)} to handle callbacks for changes. 1694 * 1695 * @hide 1696 */ 1697 @SystemApi 1698 public interface OnPropertiesChangedListener { 1699 /** 1700 * Called when one or more properties have changed, providing a Properties object with all 1701 * of the changed properties. This object will contain only properties which have changed, 1702 * not the complete set of all properties belonging to the namespace. 1703 * 1704 * @param properties Contains the complete collection of properties which have changed for a 1705 * single namespace. This includes only those which were added, updated, 1706 * or deleted. 1707 */ onPropertiesChanged(@onNull Properties properties)1708 void onPropertiesChanged(@NonNull Properties properties); 1709 } 1710 1711 /** 1712 * Thrown by {@link #setProperties(Properties)} when a configuration is rejected. This 1713 * happens if RescueParty has identified a bad configuration and reset the namespace. 1714 * 1715 * @hide 1716 */ 1717 @SystemApi 1718 public static class BadConfigException extends Exception {} 1719 1720 /** 1721 * A mapping of properties to values, as well as a single namespace which they all belong to. 1722 * 1723 * @hide 1724 */ 1725 @SystemApi 1726 public static class Properties { 1727 private final String mNamespace; 1728 private final HashMap<String, String> mMap; 1729 private Set<String> mKeyset; 1730 1731 /** 1732 * Create a mapping of properties to values and the namespace they belong to. 1733 * 1734 * @param namespace The namespace these properties belong to. 1735 * @param keyValueMap A map between property names and property values. 1736 * @hide 1737 */ 1738 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) Properties(@onNull String namespace, @Nullable Map<String, String> keyValueMap)1739 public Properties(@NonNull String namespace, @Nullable Map<String, String> keyValueMap) { 1740 Objects.requireNonNull(namespace); 1741 mNamespace = namespace; 1742 mMap = new HashMap(); 1743 if (keyValueMap != null) { 1744 mMap.putAll(keyValueMap); 1745 } 1746 } 1747 1748 /** 1749 * @return the namespace all properties within this instance belong to. 1750 */ 1751 @NonNull getNamespace()1752 public String getNamespace() { 1753 return mNamespace; 1754 } 1755 1756 /** 1757 * @return the non-null set of property names. 1758 */ 1759 @NonNull getKeyset()1760 public Set<String> getKeyset() { 1761 if (mKeyset == null) { 1762 mKeyset = Collections.unmodifiableSet(mMap.keySet()); 1763 } 1764 return mKeyset; 1765 } 1766 1767 /** 1768 * Look up the String value of a property. 1769 * 1770 * @param name The name of the property to look up. 1771 * @param defaultValue The value to return if the property has not been defined. 1772 * @return the corresponding value, or defaultValue if none exists. 1773 */ 1774 @Nullable getString(@onNull String name, @Nullable String defaultValue)1775 public String getString(@NonNull String name, @Nullable String defaultValue) { 1776 Objects.requireNonNull(name); 1777 String value = mMap.get(name); 1778 return value != null ? value : defaultValue; 1779 } 1780 1781 @Nullable setString(@onNull String name, @Nullable String value)1782 private String setString(@NonNull String name, @Nullable String value) { 1783 Objects.requireNonNull(name); 1784 mKeyset = null; 1785 return mMap.put(name, value); 1786 } 1787 1788 @NonNull getMap()1789 private Map<String, String> getMap() { 1790 return mMap; 1791 } 1792 1793 /** 1794 * Look up the boolean value of a property. 1795 * 1796 * @param name The name of the property to look up. 1797 * @param defaultValue The value to return if the property has not been defined. 1798 * @return the corresponding value, or defaultValue if none exists. 1799 */ getBoolean(@onNull String name, boolean defaultValue)1800 public boolean getBoolean(@NonNull String name, boolean defaultValue) { 1801 Objects.requireNonNull(name); 1802 String value = mMap.get(name); 1803 return value != null ? Boolean.parseBoolean(value) : defaultValue; 1804 } 1805 1806 /** 1807 * Look up the int value of a property. 1808 * 1809 * @param name The name of the property to look up. 1810 * @param defaultValue The value to return if the property has not been defined or fails to 1811 * parse into an int. 1812 * @return the corresponding value, or defaultValue if no valid int is available. 1813 */ getInt(@onNull String name, int defaultValue)1814 public int getInt(@NonNull String name, int defaultValue) { 1815 Objects.requireNonNull(name); 1816 String value = mMap.get(name); 1817 if (value == null) { 1818 return defaultValue; 1819 } 1820 try { 1821 return Integer.parseInt(value); 1822 } catch (NumberFormatException e) { 1823 Log.e(TAG, "Parsing int failed for " + name); 1824 return defaultValue; 1825 } 1826 } 1827 1828 /** 1829 * Look up the long value of a property. 1830 * 1831 * @param name The name of the property to look up. 1832 * @param defaultValue The value to return if the property has not been defined. or fails to 1833 * parse into a long. 1834 * @return the corresponding value, or defaultValue if no valid long is available. 1835 */ getLong(@onNull String name, long defaultValue)1836 public long getLong(@NonNull String name, long defaultValue) { 1837 Objects.requireNonNull(name); 1838 String value = mMap.get(name); 1839 if (value == null) { 1840 return defaultValue; 1841 } 1842 try { 1843 return Long.parseLong(value); 1844 } catch (NumberFormatException e) { 1845 Log.e(TAG, "Parsing long failed for " + name); 1846 return defaultValue; 1847 } 1848 } 1849 1850 /** 1851 * Look up the int value of a property. 1852 * 1853 * @param name The name of the property to look up. 1854 * @param defaultValue The value to return if the property has not been defined. or fails to 1855 * parse into a float. 1856 * @return the corresponding value, or defaultValue if no valid float is available. 1857 */ getFloat(@onNull String name, float defaultValue)1858 public float getFloat(@NonNull String name, float defaultValue) { 1859 Objects.requireNonNull(name); 1860 String value = mMap.get(name); 1861 if (value == null) { 1862 return defaultValue; 1863 } 1864 try { 1865 return Float.parseFloat(value); 1866 } catch (NumberFormatException e) { 1867 Log.e(TAG, "Parsing float failed for " + name); 1868 return defaultValue; 1869 } 1870 } 1871 1872 /** 1873 * Returns a map with the underlying property values defined by this object 1874 * 1875 * @hide 1876 */ getPropertyValues()1877 public @NonNull Map<String, String> getPropertyValues() { 1878 return Collections.unmodifiableMap(mMap); 1879 } 1880 1881 /** 1882 * Builder class for the construction of {@link Properties} objects. 1883 */ 1884 public static final class Builder { 1885 @NonNull 1886 private final String mNamespace; 1887 @NonNull 1888 private final Map<String, String> mKeyValues = new HashMap<>(); 1889 1890 /** 1891 * Create a new Builders for the specified namespace. 1892 * @param namespace non null namespace. 1893 */ Builder(@onNull String namespace)1894 public Builder(@NonNull String namespace) { 1895 mNamespace = namespace; 1896 } 1897 1898 /** 1899 * Add a new property with the specified key and value. 1900 * @param name non null name of the property. 1901 * @param value nullable string value of the property. 1902 * @return this Builder object 1903 */ 1904 @NonNull setString(@onNull String name, @Nullable String value)1905 public Builder setString(@NonNull String name, @Nullable String value) { 1906 mKeyValues.put(name, value); 1907 return this; 1908 } 1909 1910 /** 1911 * Add a new property with the specified key and value. 1912 * @param name non null name of the property. 1913 * @param value nullable string value of the property. 1914 * @return this Builder object 1915 */ 1916 @NonNull setBoolean(@onNull String name, boolean value)1917 public Builder setBoolean(@NonNull String name, boolean value) { 1918 mKeyValues.put(name, Boolean.toString(value)); 1919 return this; 1920 } 1921 1922 /** 1923 * Add a new property with the specified key and value. 1924 * @param name non null name of the property. 1925 * @param value int value of the property. 1926 * @return this Builder object 1927 */ 1928 @NonNull setInt(@onNull String name, int value)1929 public Builder setInt(@NonNull String name, int value) { 1930 mKeyValues.put(name, Integer.toString(value)); 1931 return this; 1932 } 1933 1934 /** 1935 * Add a new property with the specified key and value. 1936 * @param name non null name of the property. 1937 * @param value long value of the property. 1938 * @return this Builder object 1939 */ 1940 @NonNull setLong(@onNull String name, long value)1941 public Builder setLong(@NonNull String name, long value) { 1942 mKeyValues.put(name, Long.toString(value)); 1943 return this; 1944 } 1945 1946 /** 1947 * Add a new property with the specified key and value. 1948 * @param name non null name of the property. 1949 * @param value float value of the property. 1950 * @return this Builder object 1951 */ 1952 @NonNull setFloat(@onNull String name, float value)1953 public Builder setFloat(@NonNull String name, float value) { 1954 mKeyValues.put(name, Float.toString(value)); 1955 return this; 1956 } 1957 1958 /** 1959 * Create a new {@link Properties} object. 1960 * @return non null Properties. 1961 */ 1962 @NonNull build()1963 public Properties build() { 1964 return new Properties(mNamespace, mKeyValues); 1965 } 1966 } 1967 } 1968 1969 } 1970