Revert^2 "Cache Java codegen'd flags in static member variables."

This reverts commit efda207c09de55f133b22d397a78add7673fd560.

Reason for revert: this unrevert contains the fix for b/311187402

Test: cargo test
Change-Id: I210aebd30edd864a7c141ede336c12aebf4f1fcd
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index 1ad9053..e2fadb0 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -58,6 +58,7 @@
         "libaconfig_protos",
         "libanyhow",
         "libclap",
+        "libitertools",
         "libprotobuf",
         "libserde",
         "libserde_json",
diff --git a/tools/aconfig/Cargo.toml b/tools/aconfig/Cargo.toml
index 941b30d..2edf4b8 100644
--- a/tools/aconfig/Cargo.toml
+++ b/tools/aconfig/Cargo.toml
@@ -11,6 +11,7 @@
 [dependencies]
 anyhow = "1.0.69"
 clap = { version = "4.1.8", features = ["derive"] }
+itertools = "0.10.5"
 paste = "1.0.11"
 protobuf = "3.2.0"
 serde = { version = "1.0.152", features = ["derive"] }
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index 9e77b45..33e54a1 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -32,8 +32,9 @@
     I: Iterator<Item = &'a ProtoParsedFlag>,
 {
     let mut readwrite_count = 0;
-    let class_elements: Vec<ClassElement> =
-        parsed_flags_iter.map(|pf| create_class_element(package, pf, &mut readwrite_count)).collect();
+    let class_elements: Vec<ClassElement> = parsed_flags_iter
+        .map(|pf| create_class_element(package, pf, &mut readwrite_count))
+        .collect();
     let readwrite = readwrite_count > 0;
     let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
     let header = package.replace('.', "_");
@@ -110,7 +111,9 @@
 fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement {
     ClassElement {
         readwrite_idx: if pf.permission() == ProtoFlagPermission::READ_WRITE {
-            let index = *rw_count; *rw_count += 1; index
+            let index = *rw_count;
+            *rw_count += 1;
+            index
         } else {
             -1
         },
@@ -162,6 +165,8 @@
 
     virtual bool disabled_rw() = 0;
 
+    virtual bool disabled_rw_2() = 0;
+
     virtual bool enabled_fixed_ro() = 0;
 
     virtual bool enabled_ro() = 0;
@@ -179,6 +184,10 @@
     return provider_->disabled_rw();
 }
 
+inline bool disabled_rw_2() {
+    return provider_->disabled_rw_2();
+}
+
 inline bool enabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
@@ -200,6 +209,8 @@
 
 bool com_android_aconfig_test_disabled_rw();
 
+bool com_android_aconfig_test_disabled_rw_2();
+
 bool com_android_aconfig_test_enabled_fixed_ro();
 
 bool com_android_aconfig_test_enabled_ro();
@@ -233,6 +244,10 @@
 
     virtual void disabled_rw(bool val) = 0;
 
+    virtual bool disabled_rw_2() = 0;
+
+    virtual void disabled_rw_2(bool val) = 0;
+
     virtual bool enabled_fixed_ro() = 0;
 
     virtual void enabled_fixed_ro(bool val) = 0;
@@ -266,6 +281,14 @@
     provider_->disabled_rw(val);
 }
 
+inline bool disabled_rw_2() {
+    return provider_->disabled_rw_2();
+}
+
+inline void disabled_rw_2(bool val) {
+    provider_->disabled_rw_2(val);
+}
+
 inline bool enabled_fixed_ro() {
     return provider_->enabled_fixed_ro();
 }
@@ -307,6 +330,10 @@
 
 void set_com_android_aconfig_test_disabled_rw(bool val);
 
+bool com_android_aconfig_test_disabled_rw_2();
+
+void set_com_android_aconfig_test_disabled_rw_2(bool val);
+
 bool com_android_aconfig_test_enabled_fixed_ro();
 
 void set_com_android_aconfig_test_enabled_fixed_ro(bool val);
@@ -352,6 +379,16 @@
                 return cache_[0];
             }
 
+            virtual bool disabled_rw_2() override {
+                if (cache_[1] == -1) {
+                    cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
+                        "aconfig_flags.other_namespace",
+                        "com.android.aconfig.test.disabled_rw_2",
+                        "false") == "true";
+                }
+                return cache_[1];
+            }
+
             virtual bool enabled_fixed_ro() override {
                 return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
             }
@@ -361,18 +398,18 @@
             }
 
             virtual bool enabled_rw() override {
-                if (cache_[1] == -1) {
-                    cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
+                if (cache_[2] == -1) {
+                    cache_[2] = server_configurable_flags::GetServerConfigurableFlag(
                         "aconfig_flags.aconfig_test",
                         "com.android.aconfig.test.enabled_rw",
                         "true") == "true";
                 }
-                return cache_[1];
+                return cache_[2];
             }
 
     };
 
-    std::vector<int8_t> cache_ = std::vector<int8_t>(2, -1);
+    std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1);
 
     std::unique_ptr<flag_provider_interface> provider_ =
         std::make_unique<flag_provider>();
@@ -386,6 +423,10 @@
     return com::android::aconfig::test::disabled_rw();
 }
 
+bool com_android_aconfig_test_disabled_rw_2() {
+    return com::android::aconfig::test::disabled_rw_2();
+}
+
 bool com_android_aconfig_test_enabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
@@ -446,6 +487,22 @@
                 overrides_["disabled_rw"] = val;
             }
 
+            virtual bool disabled_rw_2() override {
+                auto it = overrides_.find("disabled_rw_2");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return server_configurable_flags::GetServerConfigurableFlag(
+                      "aconfig_flags.other_namespace",
+                      "com.android.aconfig.test.disabled_rw_2",
+                      "false") == "true";
+                }
+            }
+
+            virtual void disabled_rw_2(bool val) override {
+                overrides_["disabled_rw_2"] = val;
+            }
+
             virtual bool enabled_fixed_ro() override {
                 auto it = overrides_.find("enabled_fixed_ro");
                   if (it != overrides_.end()) {
@@ -515,6 +572,15 @@
     com::android::aconfig::test::disabled_rw(val);
 }
 
+bool com_android_aconfig_test_disabled_rw_2() {
+    return com::android::aconfig::test::disabled_rw_2();
+}
+
+
+void set_com_android_aconfig_test_disabled_rw_2(bool val) {
+    com::android::aconfig::test::disabled_rw_2(val);
+}
+
 
 bool com_android_aconfig_test_enabled_fixed_ro() {
     return com::android::aconfig::test::enabled_fixed_ro();
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index 05ee0d7..5470cb3 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -16,7 +16,7 @@
 
 use anyhow::Result;
 use serde::Serialize;
-use std::collections::BTreeSet;
+use std::collections::{BTreeMap, BTreeSet};
 use std::path::PathBuf;
 use tinytemplate::TinyTemplate;
 
@@ -34,12 +34,14 @@
 {
     let flag_elements: Vec<FlagElement> =
         parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect();
+    let namespace_flags = gen_flags_by_namespace(&flag_elements);
     let properties_set: BTreeSet<String> =
         flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect();
     let is_read_write = flag_elements.iter().any(|elem| elem.is_read_write);
     let is_test_mode = codegen_mode == CodegenMode::Test;
     let context = Context {
         flag_elements,
+        namespace_flags,
         is_test_mode,
         is_read_write,
         properties_set,
@@ -72,16 +74,44 @@
         .collect::<Result<Vec<OutputFile>>>()
 }
 
+fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> {
+    let mut namespace_to_flag: BTreeMap<String, Vec<FlagElement>> = BTreeMap::new();
+
+    for flag in flags {
+        match namespace_to_flag.get_mut(&flag.device_config_namespace) {
+            Some(flag_list) => flag_list.push(flag.clone()),
+            None => {
+                namespace_to_flag.insert(flag.device_config_namespace.clone(), vec![flag.clone()]);
+            }
+        }
+    }
+
+    namespace_to_flag
+        .iter()
+        .map(|(namespace, flags)| NamespaceFlags {
+            namespace: namespace.to_string(),
+            flags: flags.clone(),
+        })
+        .collect()
+}
+
 #[derive(Serialize)]
 struct Context {
     pub flag_elements: Vec<FlagElement>,
+    pub namespace_flags: Vec<NamespaceFlags>,
     pub is_test_mode: bool,
     pub is_read_write: bool,
     pub properties_set: BTreeSet<String>,
     pub package_name: String,
 }
 
-#[derive(Serialize)]
+#[derive(Serialize, Debug)]
+struct NamespaceFlags {
+    pub namespace: String,
+    pub flags: Vec<FlagElement>,
+}
+
+#[derive(Serialize, Clone, Debug)]
 struct FlagElement {
     pub default_value: bool,
     pub device_config_namespace: String,
@@ -148,6 +178,8 @@
         boolean disabledRo();
         @UnsupportedAppUsage
         boolean disabledRw();
+        @UnsupportedAppUsage
+        boolean disabledRw2();
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledFixedRo();
@@ -170,6 +202,8 @@
         /** @hide */
         public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
         /** @hide */
+        public static final String FLAG_DISABLED_RW_2 = "com.android.aconfig.test.disabled_rw_2";
+        /** @hide */
         public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
         /** @hide */
         public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
@@ -185,6 +219,10 @@
         public static boolean disabledRw() {
             return FEATURE_FLAGS.disabledRw();
         }
+        @UnsupportedAppUsage
+        public static boolean disabledRw2() {
+            return FEATURE_FLAGS.disabledRw2();
+        }
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         public static boolean enabledFixedRo() {
@@ -224,6 +262,11 @@
         }
         @Override
         @UnsupportedAppUsage
+        public boolean disabledRw2() {
+            return getValue(Flags.FLAG_DISABLED_RW_2);
+        }
+        @Override
+        @UnsupportedAppUsage
         public boolean enabledFixedRo() {
             return getValue(Flags.FLAG_ENABLED_FIXED_RO);
         }
@@ -259,6 +302,7 @@
             Map.ofEntries(
                 Map.entry(Flags.FLAG_DISABLED_RO, false),
                 Map.entry(Flags.FLAG_DISABLED_RW, false),
+                Map.entry(Flags.FLAG_DISABLED_RW_2, false),
                 Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
                 Map.entry(Flags.FLAG_ENABLED_RO, false),
                 Map.entry(Flags.FLAG_ENABLED_RW, false)
@@ -289,7 +333,52 @@
         import android.provider.DeviceConfig.Properties;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
-            private Properties mPropertiesAconfigTest;
+            private static boolean aconfig_test_is_cached = false;
+            private static boolean other_namespace_is_cached = false;
+            private static boolean disabledRw = false;
+            private static boolean disabledRw2 = false;
+            private static boolean enabledRw = true;
+
+
+            private void load_overrides_aconfig_test() {
+                try {
+                    Properties properties = DeviceConfig.getProperties("aconfig_test");
+                    disabledRw =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw", false);
+                    enabledRw =
+                        properties.getBoolean("com.android.aconfig.test.enabled_rw", true);
+                } catch (NullPointerException e) {
+                    throw new RuntimeException(
+                        "Cannot read value from namespace aconfig_test "
+                        + "from DeviceConfig. It could be that the code using flag "
+                        + "executed before SettingsProvider initialization. Please use "
+                        + "fixed read-only flag by adding is_fixed_read_only: true in "
+                        + "flag declaration.",
+                        e
+                    );
+                }
+                aconfig_test_is_cached = true;
+            }
+
+            private void load_overrides_other_namespace() {
+                try {
+                    Properties properties = DeviceConfig.getProperties("other_namespace");
+                    disabledRw2 =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw_2", false);
+                } catch (NullPointerException e) {
+                    throw new RuntimeException(
+                        "Cannot read value from namespace other_namespace "
+                        + "from DeviceConfig. It could be that the code using flag "
+                        + "executed before SettingsProvider initialization. Please use "
+                        + "fixed read-only flag by adding is_fixed_read_only: true in "
+                        + "flag declaration.",
+                        e
+                    );
+                }
+                other_namespace_is_cached = true;
+            }
+
+
             @Override
             @UnsupportedAppUsage
             public boolean disabledRo() {
@@ -298,18 +387,18 @@
             @Override
             @UnsupportedAppUsage
             public boolean disabledRw() {
-                if (mPropertiesAconfigTest == null) {
-                    mPropertiesAconfigTest =
-                        getProperties(
-                            "aconfig_test",
-                            "com.android.aconfig.test.disabled_rw"
-                        );
+                if (!aconfig_test_is_cached) {
+                    load_overrides_aconfig_test();
                 }
-                return mPropertiesAconfigTest
-                    .getBoolean(
-                        "com.android.aconfig.test.disabled_rw",
-                        false
-                    );
+                return disabledRw;
+            }
+            @Override
+            @UnsupportedAppUsage
+            public boolean disabledRw2() {
+                if (!other_namespace_is_cached) {
+                    load_overrides_other_namespace();
+                }
+                return disabledRw2;
             }
             @Override
             @UnsupportedAppUsage
@@ -324,36 +413,10 @@
             @Override
             @UnsupportedAppUsage
             public boolean enabledRw() {
-                if (mPropertiesAconfigTest == null) {
-                    mPropertiesAconfigTest =
-                        getProperties(
-                            "aconfig_test",
-                            "com.android.aconfig.test.enabled_rw"
-                        );
+                if (!aconfig_test_is_cached) {
+                    load_overrides_aconfig_test();
                 }
-                return mPropertiesAconfigTest
-                    .getBoolean(
-                        "com.android.aconfig.test.enabled_rw",
-                        true
-                    );
-            }
-            private Properties getProperties(
-                String namespace,
-                String flagName) {
-                Properties properties = null;
-                try {
-                    properties = DeviceConfig.getProperties(namespace);
-                } catch (NullPointerException e) {
-                    throw new RuntimeException(
-                        "Cannot read value of flag " + flagName + " from DeviceConfig. "
-                        + "It could be that the code using flag executed "
-                        + "before SettingsProvider initialization. "
-                        + "Please use fixed read-only flag by adding "
-                        + "is_fixed_read_only: true in flag declaration.",
-                        e
-                    );
-                }
-                return properties;
+                return enabledRw;
             }
         }
         "#;
@@ -426,6 +489,12 @@
             }
             @Override
             @UnsupportedAppUsage
+            public boolean disabledRw2() {
+                throw new UnsupportedOperationException(
+                    "Method is not implemented.");
+            }
+            @Override
+            @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
diff --git a/tools/aconfig/src/codegen_rust.rs b/tools/aconfig/src/codegen_rust.rs
index 78e62ba..fb4f981 100644
--- a/tools/aconfig/src/codegen_rust.rs
+++ b/tools/aconfig/src/codegen_rust.rs
@@ -104,6 +104,12 @@
         "com.android.aconfig.test.disabled_rw",
         "false") == "true";
 
+    /// flag value cache for disabled_rw_2
+    static ref CACHED_disabled_rw_2: bool = flags_rust::GetServerConfigurableFlag(
+        "aconfig_flags.other_namespace",
+        "com.android.aconfig.test.disabled_rw_2",
+        "false") == "true";
+
     /// flag value cache for enabled_rw
     static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag(
         "aconfig_flags.aconfig_test",
@@ -122,6 +128,11 @@
         *CACHED_disabled_rw
     }
 
+    /// query flag disabled_rw_2
+    pub fn disabled_rw_2(&self) -> bool {
+        *CACHED_disabled_rw_2
+    }
+
     /// query flag enabled_fixed_ro
     pub fn enabled_fixed_ro(&self) -> bool {
         true
@@ -153,6 +164,12 @@
     PROVIDER.disabled_rw()
 }
 
+/// query flag disabled_rw_2
+#[inline(always)]
+pub fn disabled_rw_2() -> bool {
+    PROVIDER.disabled_rw_2()
+}
+
 /// query flag enabled_fixed_ro
 #[inline(always)]
 pub fn enabled_fixed_ro() -> bool {
@@ -211,6 +228,21 @@
         self.overrides.insert("disabled_rw", val);
     }
 
+    /// query flag disabled_rw_2
+    pub fn disabled_rw_2(&self) -> bool {
+        self.overrides.get("disabled_rw_2").copied().unwrap_or(
+            flags_rust::GetServerConfigurableFlag(
+                "aconfig_flags.other_namespace",
+                "com.android.aconfig.test.disabled_rw_2",
+                "false") == "true"
+        )
+    }
+
+    /// set flag disabled_rw_2
+    pub fn set_disabled_rw_2(&mut self, val: bool) {
+        self.overrides.insert("disabled_rw_2", val);
+    }
+
     /// query flag enabled_fixed_ro
     pub fn enabled_fixed_ro(&self) -> bool {
         self.overrides.get("enabled_fixed_ro").copied().unwrap_or(
@@ -285,6 +317,18 @@
     PROVIDER.lock().unwrap().set_disabled_rw(val);
 }
 
+/// query flag disabled_rw_2
+#[inline(always)]
+pub fn disabled_rw_2() -> bool {
+    PROVIDER.lock().unwrap().disabled_rw_2()
+}
+
+/// set flag disabled_rw_2
+#[inline(always)]
+pub fn set_disabled_rw_2(val: bool) {
+    PROVIDER.lock().unwrap().set_disabled_rw_2(val);
+}
+
 /// query flag enabled_fixed_ro
 #[inline(always)]
 pub fn enabled_fixed_ro() -> bool {
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 7b05147..63aef29 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -334,7 +334,7 @@
         assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
         assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission());
 
-        assert_eq!(5, parsed_flags.parsed_flag.len());
+        assert_eq!(6, parsed_flags.parsed_flag.len());
         for pf in parsed_flags.parsed_flag.iter() {
             if pf.name() == "enabled_fixed_ro" {
                 continue;
@@ -433,7 +433,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_defaults(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
+        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_2=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
     }
 
     #[test]
@@ -441,7 +441,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_sysprops(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
+        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_2=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
     }
 
     #[test]
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index 9034704..922d4c6 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -60,6 +60,26 @@
 }
 parsed_flag {
   package: "com.android.aconfig.test"
+  name: "disabled_rw_2"
+  namespace: "other_namespace"
+  description: "This flag is DISABLED + READ_WRITE"
+  bug: "999"
+  state: DISABLED
+  permission: READ_WRITE
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/first.values"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  is_fixed_read_only: false
+}
+parsed_flag {
+  package: "com.android.aconfig.test"
   name: "enabled_fixed_ro"
   namespace: "aconfig_test"
   description: "This flag is fixed READ_ONLY + ENABLED"
diff --git a/tools/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/templates/FeatureFlagsImpl.java.template
index ff089df..ec8822c 100644
--- a/tools/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/templates/FeatureFlagsImpl.java.template
@@ -8,10 +8,41 @@
 {{ endif }}
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ if is_read_write- }}
-{{ for properties in properties_set }}
-    private Properties {properties};
+{{- if is_read_write }}
+{{- for namespace_with_flags in namespace_flags }}
+    private static boolean {namespace_with_flags.namespace}_is_cached = false;
+{{- endfor- }}
+
+{{ for flag in flag_elements }}
+{{- if flag.is_read_write }}
+    private static boolean {flag.method_name} = {flag.default_value};
+{{- endif- }}
 {{ endfor }}
+
+{{ for namespace_with_flags in namespace_flags }}
+    private void load_overrides_{namespace_with_flags.namespace}() \{
+        try \{
+            Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
+
+            {{- for flag in namespace_with_flags.flags }}
+            {{- if flag.is_read_write }}
+            {flag.method_name} =
+                properties.getBoolean("{flag.device_config_flag}", {flag.default_value});
+            {{- endif- }}
+            {{ endfor }}
+        } catch (NullPointerException e) \{
+            throw new RuntimeException(
+                "Cannot read value from namespace {namespace_with_flags.namespace} "
+                + "from DeviceConfig. It could be that the code using flag "
+                + "executed before SettingsProvider initialization. Please use "
+                + "fixed read-only flag by adding is_fixed_read_only: true in "
+                + "flag declaration.",
+                e
+            );
+        }
+        {namespace_with_flags.namespace}_is_cached = true;
+    }
+{{ endfor- }}
 {{ endif- }}
 
 {{ for flag in flag_elements }}
@@ -19,45 +50,15 @@
     @UnsupportedAppUsage
     public boolean {flag.method_name}() \{
     {{ -if flag.is_read_write }}
-        if ({flag.properties} == null) \{
-            {flag.properties} =
-                getProperties(
-                    "{flag.device_config_namespace}",
-                    "{flag.device_config_flag}"
-                );
+        if (!{flag.device_config_namespace}_is_cached) \{
+            load_overrides_{flag.device_config_namespace}();
         }
-        return {flag.properties}
-                .getBoolean(
-                    "{flag.device_config_flag}",
-                    {flag.default_value}
-                );
+        return {flag.method_name};
     {{ else }}
         return {flag.default_value};
     {{ endif- }}
     }
 {{ endfor }}
-
-{{ -if is_read_write }}
-    private Properties getProperties(
-            String namespace,
-            String flagName) \{
-        Properties properties = null;
-        try \{
-            properties = DeviceConfig.getProperties(namespace);
-        } catch (NullPointerException e) \{
-            throw new RuntimeException(
-                "Cannot read value of flag " + flagName + " from DeviceConfig. "
-                + "It could be that the code using flag executed "
-                + "before SettingsProvider initialization. "
-                + "Please use fixed read-only flag by adding "
-                + "is_fixed_read_only: true in flag declaration.",
-                e
-            );
-        }
-
-        return properties;
-    }
-{{ endif- }}
 }
 {{ else }}
 {#- Generate only stub if in test mode #}
@@ -70,6 +71,6 @@
         throw new UnsupportedOperationException(
             "Method is not implemented.");
     }
-{{ endfor }}
+{{ endfor- }}
 }
 {{ endif }}
diff --git a/tools/aconfig/tests/first.values b/tools/aconfig/tests/first.values
index a450f78..448fb3a 100644
--- a/tools/aconfig/tests/first.values
+++ b/tools/aconfig/tests/first.values
@@ -18,6 +18,12 @@
 }
 flag_value {
     package: "com.android.aconfig.test"
+    name: "disabled_rw_2"
+    state: DISABLED
+    permission: READ_WRITE
+}
+flag_value {
+    package: "com.android.aconfig.test"
     name: "enabled_fixed_ro"
     state: ENABLED
     permission: READ_ONLY
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index aaa6df5..3076f5e 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -51,3 +51,10 @@
     bug: ""
     is_fixed_read_only: true
 }
+
+flag {
+    name: "disabled_rw_2"
+    namespace: "other_namespace"
+    description: "This flag is DISABLED + READ_WRITE"
+    bug: "999"
+}