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