Adds DeviceConfig.getProperties method for atomic reading.

This fetches multiple flags atomically, either the entire contents of
the namespace, or just a list of flags specified by the caller. This
update also enables the local Settings class to fetch and cache the entire namespace
whenever any flags from that namespace are read so that we only incur the cost of the
IPC once.

Test: atest FrameworksCoreTests:DeviceConfigTest
      atest FrameworksCoreTests:SettingsProviderTest
      atest SettingsProviderTest:DeviceConfigServiceTest
Bug: 136135417
Change-Id: I0be7c4b51c37590f5001e53b074b06246851a198
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 16c96e6..a9c466e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -439,10 +439,8 @@
 
             case Settings.CALL_METHOD_LIST_CONFIG: {
                 String prefix = getSettingPrefix(args);
-                Bundle result = new Bundle();
-                result.putSerializable(
-                        Settings.NameValueTable.VALUE, (HashMap) getAllConfigFlags(prefix));
-                return result;
+                return packageValuesForCallResult(getAllConfigFlags(prefix),
+                        isTrackingGeneration(args));
             }
 
             case Settings.CALL_METHOD_LIST_GLOBAL: {
@@ -1076,7 +1074,7 @@
         return false;
     }
 
-    private Map<String, String> getAllConfigFlags(@Nullable String prefix) {
+    private HashMap<String, String> getAllConfigFlags(@Nullable String prefix) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
         }
@@ -1085,12 +1083,11 @@
             // Get the settings.
             SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
                     SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
-
             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_CONFIG,
                     UserHandle.USER_SYSTEM);
 
             final int nameCount = names.size();
-            Map<String, String> flagsToValues = new HashMap<>(names.size());
+            HashMap<String, String> flagsToValues = new HashMap<>(names.size());
 
             for (int i = 0; i < nameCount; i++) {
                 String name = names.get(i);
@@ -2057,8 +2054,7 @@
                 "get/set setting for user", null);
     }
 
-    private Bundle packageValueForCallResult(Setting setting,
-            boolean trackingGeneration) {
+    private Bundle packageValueForCallResult(Setting setting, boolean trackingGeneration) {
         if (!trackingGeneration) {
             if (setting == null || setting.isNull()) {
                 return NULL_SETTING_BUNDLE;
@@ -2073,6 +2069,21 @@
         return result;
     }
 
+    private Bundle packageValuesForCallResult(HashMap<String, String> keyValues,
+            boolean trackingGeneration) {
+        Bundle result = new Bundle();
+        result.putSerializable(Settings.NameValueTable.VALUE, keyValues);
+        if (trackingGeneration) {
+            synchronized (mLock) {
+                mSettingsRegistry.mGenerationRegistry.addGenerationData(result,
+                        mSettingsRegistry.getSettingsLocked(
+                                SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM).mKey);
+            }
+        }
+
+        return result;
+    }
+
     private static int getRequestingUserId(Bundle args) {
         final int callingUserId = UserHandle.getCallingUserId();
         return (args != null) ? args.getInt(Settings.CALL_METHOD_USER_KEY, callingUserId)