Support GNSS configuration overlay from resource

Add GNSS configuration overlay from resource to override carrier config.

Bug: 317734846
Test: on device

Change-Id: I2125ae8fd06953304e1d2280071ee79e865d22c1
diff --git a/location/java/android/location/flags/gnss.aconfig b/location/java/android/location/flags/gnss.aconfig
index 8a6a034..8c7c871 100644
--- a/location/java/android/location/flags/gnss.aconfig
+++ b/location/java/android/location/flags/gnss.aconfig
@@ -41,3 +41,10 @@
     description: "Flag for replacing future elapsedRealtime in JNI"
     bug: "314328533"
 }
+
+flag {
+    name: "gnss_configuration_from_resource"
+    namespace: "location"
+    description: "Flag for GNSS configuration from resource"
+    bug: "317734846"
+}
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 5ef89ad..a5939e9 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -17,6 +17,7 @@
 package com.android.server.location.gnss;
 
 import android.content.Context;
+import android.location.flags.Flags;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
 import android.telephony.CarrierConfigManager;
@@ -36,6 +37,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -275,6 +277,11 @@
         }
         loadPropertiesFromCarrierConfig(inEmergency, activeSubId);
 
+        if (Flags.gnssConfigurationFromResource()) {
+            // Overlay carrier properties from resources.
+            loadPropertiesFromResource(mContext, mProperties);
+        }
+
         if (isSimAbsent(mContext)) {
             // Use the default SIM's LPP profile when SIM is absent.
             String lpp_prof = SystemProperties.get(LPP_PROFILE);
@@ -382,7 +389,7 @@
             if (configKey.startsWith(CarrierConfigManager.Gps.KEY_PREFIX)) {
                 String key = configKey
                         .substring(CarrierConfigManager.Gps.KEY_PREFIX.length())
-                        .toUpperCase();
+                        .toUpperCase(Locale.ROOT);
                 Object value = configs.get(configKey);
                 if (DEBUG) Log.d(TAG, "Gps config: " + key + " = " + value);
                 if (value instanceof String) {
@@ -410,6 +417,24 @@
         }
     }
 
+    private void loadPropertiesFromResource(Context context,
+            Properties properties) {
+        String[] configValues = context.getResources().getStringArray(
+                com.android.internal.R.array.config_gnssParameters);
+        for (String item : configValues) {
+            if (DEBUG) Log.d(TAG, "GnssParamsResource: " + item);
+            // We need to support "KEY =", but not "=VALUE".
+            int index = item.indexOf("=");
+            if (index > 0 && index + 1 < item.length()) {
+                String key = item.substring(0, index);
+                String value = item.substring(index + 1);
+                properties.setProperty(key.trim().toUpperCase(Locale.ROOT), value);
+            } else {
+                Log.w(TAG, "malformed contents: " + item);
+            }
+        }
+    }
+
     private int getRangeCheckedConfigEsExtensionSec() {
         int emergencyExtensionSeconds = getIntConfig(CONFIG_ES_EXTENSION_SEC, 0);
         if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) {