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