Prevent local overrides and error for RO flags

Bug: 342636474
Test: overrode a RO flag and saw error message
Change-Id: I2df9db152fdf9942812b61d32bee1bd16c2bf709
Flag: EXEMPT test only
diff --git a/Android.bp b/Android.bp
index f0aa62c..9933940 100644
--- a/Android.bp
+++ b/Android.bp
@@ -427,6 +427,7 @@
         "modules-utils-expresslog",
         "perfetto_trace_javastream_protos_jarjar",
         "libaconfig_java_proto_nano",
+        "aconfig_device_paths_java",
     ],
 }
 
diff --git a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
index f306b0b..086fcc8 100644
--- a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
+++ b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.pm.pkg.parsing.ParsingUtils.ANDROID_RES_NAMESPACE;
 
+import android.aconfig.DevicePaths;
 import android.aconfig.nano.Aconfig;
 import android.aconfig.nano.Aconfig.parsed_flag;
 import android.aconfig.nano.Aconfig.parsed_flags;
@@ -40,7 +41,6 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -54,20 +54,20 @@
 public class AconfigFlags {
     private static final String LOG_TAG = "AconfigFlags";
 
-    private static final List<String> sTextProtoFilesOnDevice = List.of(
-            "/system/etc/aconfig_flags.pb",
-            "/system_ext/etc/aconfig_flags.pb",
-            "/product/etc/aconfig_flags.pb",
-            "/vendor/etc/aconfig_flags.pb");
+    public enum Permission {
+        READ_WRITE,
+        READ_ONLY
+    }
 
     private final ArrayMap<String, Boolean> mFlagValues = new ArrayMap<>();
+    private final ArrayMap<String, Permission> mFlagPermissions = new ArrayMap<>();
 
     public AconfigFlags() {
         if (!Flags.manifestFlagging()) {
             Slog.v(LOG_TAG, "Feature disabled, skipped all loading");
             return;
         }
-        for (String fileName : sTextProtoFilesOnDevice) {
+        for (String fileName : DevicePaths.parsedFlagsProtoPaths()) {
             try (var inputStream = new FileInputStream(fileName)) {
                 loadAconfigDefaultValues(inputStream.readAllBytes());
             } catch (IOException e) {
@@ -184,6 +184,12 @@
             Slog.v(LOG_TAG, "Read Aconfig default flag value "
                     + flagPackageAndName + " = " + flagValue);
             mFlagValues.put(flagPackageAndName, flagValue);
+
+            Permission permission = flag.permission == Aconfig.READ_ONLY
+                    ? Permission.READ_ONLY
+                    : Permission.READ_WRITE;
+
+            mFlagPermissions.put(flagPackageAndName, permission);
         }
     }
 
@@ -200,6 +206,17 @@
     }
 
     /**
+     * Get the flag permission, or null if the flag doesn't exist.
+     * @param flagPackageAndName Full flag name formatted as 'package.flag'
+     * @return the current permission of the given Aconfig flag, or null if there is no such flag
+     */
+    @Nullable
+    public Permission getFlagPermission(@NonNull String flagPackageAndName) {
+        Permission permission = mFlagPermissions.get(flagPackageAndName);
+        return permission;
+    }
+
+    /**
      * Check if the element in {@code parser} should be skipped because of the feature flag.
      * @param parser XML parser object currently parsing an element
      * @return true if the element is disabled because of its feature flag
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index e77cf2f..62cc103 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -42,6 +42,7 @@
 import android.provider.UpdatableDeviceConfigServiceReadiness;
 import android.util.Slog;
 
+import com.android.internal.pm.pkg.component.AconfigFlags;
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.File;
@@ -425,7 +426,13 @@
                     DeviceConfig.setProperty(namespace, key, value, makeDefault);
                     break;
                 case OVERRIDE:
-                    DeviceConfig.setLocalOverride(namespace, key, value);
+                    AconfigFlags.Permission permission =
+                            (new AconfigFlags()).getFlagPermission(key);
+                    if (permission == AconfigFlags.Permission.READ_ONLY) {
+                        pout.println("cannot override read-only flag " + key);
+                    } else {
+                        DeviceConfig.setLocalOverride(namespace, key, value);
+                    }
                     break;
                 case CLEAR_OVERRIDE:
                     DeviceConfig.clearLocalOverride(namespace, key);