Merge "Allow setting some build_broken out of boardconfig" into main
diff --git a/core/Makefile b/core/Makefile
index 3bd6ae1..3013b78 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -16,53 +16,93 @@
 ODM_DLKM_NOTICE_DEPS :=
 SYSTEM_DLKM_NOTICE_DEPS :=
 
-# -----------------------------------------------------------------
-# Release Config Flags
 
-# Create a summary file of build flags for each partition
-# $(1): build flags json file
-# $(2): flag names
-define generate-partition-build-flag-file
-$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
-$(eval $(strip $(1)): PRIVATE_FLAG_NAMES := $(strip $(2)))
-$(strip $(1)):
-	mkdir -p $$(dir $$(PRIVATE_OUT))
-	echo '{' > $$(PRIVATE_OUT)
-	echo '"flags": [' >> $$(PRIVATE_OUT)
-	$$(foreach flag, $$(PRIVATE_FLAG_NAMES), \
-		( \
-			printf '  { "name": "%s", "value": "%s", ' \
-					'$$(flag)' \
-					'$$(_ALL_RELEASE_FLAGS.$$(flag).VALUE)' \
-					; \
-			printf '"set": "%s", "default": "%s", "declared": "%s" }' \
-					'$$(_ALL_RELEASE_FLAGS.$$(flag).SET_IN)' \
-					'$$(_ALL_RELEASE_FLAGS.$$(flag).DEFAULT)' \
-					'$$(_ALL_RELEASE_FLAGS.$$(flag).DECLARED_IN)' \
-					; \
-			printf '$$(if $$(filter $$(lastword $$(PRIVATE_FLAG_NAMES)),$$(flag)),,$$(comma))\n' ; \
-		) >> $$(PRIVATE_OUT) \
-	)
-	echo "]" >> $$(PRIVATE_OUT)
-	echo "}" >> $$(PRIVATE_OUT)
+# IMAGES_TO_BUILD is a list of the partition .img files that will be created.
+IMAGES_TO_BUILD:=
+ifneq ($(BUILDING_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += boot
+endif
+ifneq ($(BUILDING_CACHE_IMAGE),)
+  IMAGES_TO_BUILD += cache
+endif
+ifneq ($(BUILDING_DEBUG_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += debug_boot
+endif
+ifneq ($(BUILDING_DEBUG_VENDOR_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += debug_vendor_boot
+endif
+ifneq ($(BUILDING_INIT_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += init_boot
+endif
+ifneq ($(BUILDING_ODM_DLKM_IMAGE),)
+  IMAGES_TO_BUILD += odm_dlkm
+endif
+ifneq ($(BUILDING_ODM_IMAGE),)
+  IMAGES_TO_BUILD += odm
+endif
+ifneq ($(BUILDING_PRODUCT_IMAGE),)
+  IMAGES_TO_BUILD += product
+endif
+ifneq ($(BUILDING_RAMDISK_IMAGE),)
+  IMAGES_TO_BUILD += ramdisk
+endif
+ifneq ($(BUILDING_RECOVERY_IMAGE),)
+  IMAGES_TO_BUILD += recovery
+endif
+ifneq ($(BUILDING_SUPER_EMPTY_IMAGE),)
+  IMAGES_TO_BUILD += super_empty
+endif
+ifneq ($(BUILDING_SYSTEM_DLKM_IMAGE),)
+  IMAGES_TO_BUILD += system_dlkm
+endif
+ifneq ($(BUILDING_SYSTEM_EXT_IMAGE),)
+  IMAGES_TO_BUILD += system_ext
+endif
+ifneq ($(BUILDING_SYSTEM_IMAGE),)
+  IMAGES_TO_BUILD += system
+endif
+ifneq ($(BUILDING_SYSTEM_OTHER_IMAGE),)
+  IMAGES_TO_BUILD += system_other
+endif
+ifneq ($(BUILDING_USERDATA_IMAGE),)
+  IMAGES_TO_BUILD += userdata
+endif
+ifneq ($(BUILDING_VBMETA_IMAGE),)
+  IMAGES_TO_BUILD += vbmeta
+endif
+ifneq ($(BUILDING_VENDOR_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += vendor_boot
+endif
+ifneq ($(BUILDING_VENDOR_DLKM_IMAGE),)
+  IMAGES_TO_BUILD += vendor_dlkm
+endif
+ifneq ($(BUILDING_VENDOR_IMAGE),)
+  IMAGES_TO_BUILD += vendor
+endif
+ifneq ($(BUILDING_VENDOR_KERNEL_BOOT_IMAGE),)
+  IMAGES_TO_BUILD += vendor_kernel_boot
+endif
+
+
+###########################################################
+# Get the module names suitable for ALL_MODULES.* variables that are installed
+# for a given partition
+#
+# $(1): Partition
+###########################################################
+define register-names-for-partition
+$(sort $(foreach m,$(product_MODULES),\
+	$(if $(filter $(PRODUCT_OUT)/$(strip $(1))/%, $(ALL_MODULES.$(m).INSTALLED)), \
+		$(m)
+	) \
+))
 endef
 
-_FLAG_PARTITIONS := product system system_ext vendor
 
-$(foreach partition, $(_FLAG_PARTITIONS), \
-	$(eval BUILD_FLAG_SUMMARIES.$(partition) \
-			:= $(TARGET_OUT_FLAGS)/$(partition)/etc/build_flags.json) \
-	$(eval $(call generate-partition-build-flag-file, \
-				$(BUILD_FLAG_SUMMARIES.$(partition)), \
-				$(_ALL_RELEASE_FLAGS.PARTITIONS.$(partition)) \
-            ) \
-    ) \
-)
+# Release & Aconfig Flags
+# -----------------------------------------------------------------
+include $(BUILD_SYSTEM)/packaging/flags.mk
 
-# TODO: Remove
-.PHONY: flag-files
-flag-files: $(foreach partition, $(_FLAG_PARTITIONS), \
-		$(TARGET_OUT_FLAGS)/$(partition)/etc/build_flags.json)
 
 # -----------------------------------------------------------------
 # Define rules to copy PRODUCT_COPY_FILES defined by the product.
@@ -7388,6 +7428,9 @@
 haiku-rust: $(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_RUST_FUZZ_TARGETS)
 $(call dist-for-goals,haiku-rust,$(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES))
 $(call dist-for-goals,haiku-rust,$(PRODUCT_OUT)/module-info.json)
+.PHONY: haiku-presubmit
+haiku-presubmit: $(SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_PRESUBMIT_FUZZ_TARGETS)
+$(call dist-for-goals,haiku-presubmit,$(SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES))
 
 # -----------------------------------------------------------------
 # Extract platform fonts used in Layoutlib
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 998cb0d..e7c28ec 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -1058,6 +1058,10 @@
   $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS) \
   $(filter-out $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS),$(my_supported_variant))
 
+ALL_MODULES.$(my_register_name).ACONFIG_FILES := \
+    $(ALL_MODULES.$(my_register_name).ACONFIG_FILES) $(LOCAL_ACONFIG_FILES)
+
+
 ##########################################################################
 ## When compiling against API imported module, use API import stub
 ## libraries.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index bb7ba1b..25b26cc 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -9,6 +9,7 @@
 LOCAL_AAPT_FLAGS:=
 LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
 LOCAL_AAPT_NAMESPACES:=
+LOCAL_ACONFIG_FILES:=
 LOCAL_ADDITIONAL_CERTIFICATES:=
 LOCAL_ADDITIONAL_CHECKED_MODULE:=
 LOCAL_ADDITIONAL_DEPENDENCIES:=
diff --git a/core/config.mk b/core/config.mk
index 0c6653a..55ff6ba 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -649,6 +649,7 @@
 FILESLIST_UTIL :=$= build/make/tools/fileslist_util.py
 HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier
 XMLLINT := $(HOST_OUT_EXECUTABLES)/xmllint
+ACONFIG := $(HOST_OUT_EXECUTABLES)/aconfig
 
 # SOONG_ZIP is exported by Soong, but needs to be defined early for
 # $OUT/dexpreopt.global.  It will be verified against the Soong version.
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 7fa190f..82b17be 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -413,7 +413,6 @@
     my_cflags += -fvisibility=default
   endif
   my_ldflags += $(CFI_EXTRA_LDFLAGS)
-  my_arflags += --plugin $(LLVM_PREBUILTS_PATH)/../lib64/LLVMgold.so
 
   ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
         my_ldflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_ldflags))
diff --git a/core/main.mk b/core/main.mk
index cbdb680..48b4b5e 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1364,6 +1364,7 @@
   product_host_FILES := $(call host-installed-files,$(INTERNAL_PRODUCT))
   product_target_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
   # WARNING: The product_MODULES variable is depended on by external files.
+  # It contains the list of register names that will be installed on the device
   product_MODULES := $(_pif_modules)
 
   # Verify the artifact path requirements made by included products.
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
new file mode 100644
index 0000000..4b692be
--- /dev/null
+++ b/core/packaging/flags.mk
@@ -0,0 +1,122 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# This file is included by build/make/core/Makefile, and contains the logic for
+# the combined flags files.
+#
+
+# TODO: Should we do all of the images in $(IMAGES_TO_BUILD)?
+_FLAG_PARTITIONS := product system system_ext vendor
+
+
+# -----------------------------------------------------------------
+# Release Config Flags
+
+# Create a summary file of build flags for each partition
+# $(1): built build flags json file
+# $(2): installed build flags json file
+# $(3): flag names
+define generate-partition-build-flag-file
+$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
+$(eval $(strip $(1)): PRIVATE_FLAG_NAMES := $(strip $(3)))
+$(strip $(1)):
+	mkdir -p $$(dir $$(PRIVATE_OUT))
+	echo '{' > $$(PRIVATE_OUT)
+	echo '"flags": [' >> $$(PRIVATE_OUT)
+	$$(foreach flag, $$(PRIVATE_FLAG_NAMES), \
+		( \
+			printf '  { "name": "%s", "value": "%s", ' \
+					'$$(flag)' \
+					'$$(_ALL_RELEASE_FLAGS.$$(flag).VALUE)' \
+					; \
+			printf '"set": "%s", "default": "%s", "declared": "%s" }' \
+					'$$(_ALL_RELEASE_FLAGS.$$(flag).SET_IN)' \
+					'$$(_ALL_RELEASE_FLAGS.$$(flag).DEFAULT)' \
+					'$$(_ALL_RELEASE_FLAGS.$$(flag).DECLARED_IN)' \
+					; \
+			printf '$$(if $$(filter $$(lastword $$(PRIVATE_FLAG_NAMES)),$$(flag)),,$$(comma))\n' ; \
+		) >> $$(PRIVATE_OUT) ; \
+	)
+	echo "]" >> $$(PRIVATE_OUT)
+	echo "}" >> $$(PRIVATE_OUT)
+$(call copy-one-file, $(1), $(2))
+endef
+
+$(foreach partition, $(_FLAG_PARTITIONS), \
+	$(eval build_flag_summaries.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/build_flags.json) \
+	$(eval $(call generate-partition-build-flag-file, \
+				$(TARGET_OUT_FLAGS)/$(partition)/build_flags.json, \
+				$(build_flag_summaries.$(partition)), \
+				$(_ALL_RELEASE_FLAGS.PARTITIONS.$(partition)) \
+			) \
+	) \
+)
+
+
+# -----------------------------------------------------------------
+# Aconfig Flags
+
+# Create a summary file of build flags for each partition
+# $(1): built aconfig flags textprot file (out)
+# $(2): installed aconfig flags textprot file (out)
+# $(3): input aconfig files for the partition (in)
+define generate-partition-aconfig-flag-file
+$(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
+$(eval $(strip $(1)): PRIVATE_IN := $(strip $(3)))
+$(strip $(1)): $(ACONFIG)
+	mkdir -p $$(dir $$(PRIVATE_OUT))
+	$$(if $$(PRIVATE_IN), \
+		$$(ACONFIG) dump --format textproto --out $$(PRIVATE_OUT) \
+			$$(addprefix --cache ,$$(PRIVATE_IN)), \
+		echo "# No aconfig flags" > $$(PRIVATE_OUT) \
+	)
+$(call copy-one-file, $(1), $(2))
+endef
+
+
+$(foreach partition, $(_FLAG_PARTITIONS), \
+	$(eval aconfig_flag_summaries.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig_flags.textproto) \
+	$(eval $(call generate-partition-aconfig-flag-file, \
+				$(TARGET_OUT_FLAGS)/$(partition)/aconfig_flags.textproto, \
+				$(aconfig_flag_summaries.$(partition)), \
+				$(sort $(foreach m,$(call register-names-for-partition, $(partition)), \
+					$(ALL_MODULES.$(m).ACONFIG_FILES) \
+				)) \
+	)) \
+)
+
+
+# -----------------------------------------------------------------
+# Install the ones we need for the configured product
+required_flags_files := \
+		$(sort $(foreach partition, $(filter $(IMAGES_TO_BUILD), $(_FLAG_PARTITIONS)), \
+			$(build_flag_summaries.$(partition)) \
+			$(aconfig_flag_summaries.$(partition)) \
+		))
+
+ALL_DEFAULT_INSTALLED_MODULES += $(required_flags_files)
+
+# TODO: Remove
+.PHONY: flag-files
+flag-files: $(required_flags_files)
+
+
+# Clean up
+required_flags_files:=
+$(foreach partition, $(_FLAG_PARTITIONS), \
+	$(eval build_flag_summaries.$(partition):=) \
+	$(eval aconfig_flag_summaries.$(partition):=) \
+)
+
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index c349907..a4ea7f4 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -67,7 +67,7 @@
     ],
 }
 
-// integration tests: java
+// integration tests: general
 
 aconfig_declarations {
     name: "aconfig.test.flags",
@@ -91,8 +91,10 @@
     ],
 }
 
+// integration tests: java
+
 java_aconfig_library {
-    name: "aconfig_test_java",
+    name: "aconfig_test_java_library",
     aconfig_declarations: "aconfig.test.flags",
 }
 
@@ -104,9 +106,30 @@
     manifest: "tests/AndroidManifest.xml",
     certificate: "platform",
     static_libs: [
+        "aconfig_test_java_library",
         "androidx.test.rules",
         "testng",
-        "aconfig_test_java",
     ],
     test_suites: ["device-tests"],
 }
+
+// integration tests: C++
+
+cc_aconfig_library {
+    name: "aconfig_test_cpp_library",
+    aconfig_declarations: "aconfig.test.flags",
+}
+
+cc_test {
+    name: "aconfig.test.cpp",
+    srcs: [
+        "tests/aconfig_test.cpp",
+    ],
+    static_libs: [
+        "aconfig_test_cpp_library",
+        "libgmock",
+    ],
+    shared_libs: [
+        "server_configurable_flags",
+    ],
+}
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index c17af1f..530af49 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -57,26 +57,6 @@
             template: include_str!("../templates/cpp_source_file.template"),
             dir: "",
         },
-        FileSpec {
-            name: &format!("{}_flag_provider.h", header),
-            template: match codegen_mode {
-                CodegenMode::Production => {
-                    include_str!("../templates/cpp_prod_flag_provider.template")
-                }
-                CodegenMode::Test => include_str!("../templates/cpp_test_flag_provider.template"),
-            },
-            dir: "",
-        },
-        FileSpec {
-            name: &format!("{}_c.h", header),
-            template: include_str!("../templates/c_exported_header.template"),
-            dir: "include",
-        },
-        FileSpec {
-            name: &format!("{}_c.cc", header),
-            template: include_str!("../templates/c_source_file.template"),
-            dir: "",
-        },
     ];
     files.iter().map(|file| generate_file(file, &context)).collect()
 }
@@ -138,12 +118,13 @@
     const EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
 #pragma once
 
+#ifdef __cplusplus
+
 #include <memory>
 
 namespace com::android::aconfig::test {
 class flag_provider_interface {
 public:
-
     virtual ~flag_provider_interface() = default;
 
     virtual bool disabled_ro() = 0;
@@ -174,14 +155,32 @@
 }
 
 }
+
+extern "C" {
+#endif // __cplusplus
+
+bool com_android_aconfig_test_disabled_ro();
+
+bool com_android_aconfig_test_disabled_rw();
+
+bool com_android_aconfig_test_enabled_ro();
+
+bool com_android_aconfig_test_enabled_rw();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
 "#;
 
     const EXPORTED_TEST_HEADER_EXPECTED: &str = r#"
 #pragma once
 
+#ifdef __cplusplus
+
 #include <memory>
 
 namespace com::android::aconfig::test {
+
 class flag_provider_interface {
 public:
 
@@ -245,164 +244,9 @@
 }
 
 }
-"#;
 
-    const PROD_FLAG_PROVIDER_HEADER_EXPECTED: &str = r#"
-#pragma once
-
-#include "com_android_aconfig_test.h"
-#include <server_configurable_flags/get_flags.h>
-
-namespace com::android::aconfig::test {
-class flag_provider : public flag_provider_interface {
-public:
-
-    virtual bool disabled_ro() override {
-        return false;
-    }
-
-    virtual bool disabled_rw() override {
-        return server_configurable_flags::GetServerConfigurableFlag(
-            "aconfig_test",
-            "com.android.aconfig.test.disabled_rw",
-            "false") == "true";
-    }
-
-    virtual bool enabled_ro() override {
-        return true;
-    }
-
-    virtual bool enabled_rw() override {
-        return server_configurable_flags::GetServerConfigurableFlag(
-            "aconfig_test",
-            "com.android.aconfig.test.enabled_rw",
-            "true") == "true";
-    }
-};
-}
-"#;
-
-    const TEST_FLAG_PROVIDER_HEADER_EXPECTED: &str = r#"
-#pragma once
-
-#include "com_android_aconfig_test.h"
-#include <server_configurable_flags/get_flags.h>
-
-#include <unordered_map>
-#include <string>
-
-namespace com::android::aconfig::test {
-class flag_provider : public flag_provider_interface {
-private:
-    std::unordered_map<std::string, bool> overrides_;
-
-public:
-
-    flag_provider()
-        : overrides_()
-    {}
-
-    virtual bool disabled_ro() override {
-        auto it = overrides_.find("disabled_ro");
-        if (it != overrides_.end()) {
-            return it->second;
-        } else {
-            return false;
-        }
-    }
-
-    virtual void disabled_ro(bool val) override {
-        overrides_["disabled_ro"] = val;
-    }
-
-    virtual bool disabled_rw() override {
-        auto it = overrides_.find("disabled_rw");
-        if (it != overrides_.end()) {
-            return it->second;
-        } else {
-            return server_configurable_flags::GetServerConfigurableFlag(
-                "aconfig_test",
-                "com.android.aconfig.test.disabled_rw",
-                "false") == "true";
-        }
-    }
-
-    virtual void disabled_rw(bool val) override {
-        overrides_["disabled_rw"] = val;
-    }
-
-    virtual bool enabled_ro() override {
-        auto it = overrides_.find("enabled_ro");
-        if (it != overrides_.end()) {
-            return it->second;
-        } else {
-            return true;
-        }
-    }
-
-    virtual void enabled_ro(bool val) override {
-        overrides_["enabled_ro"] = val;
-    }
-
-    virtual bool enabled_rw() override {
-        auto it = overrides_.find("enabled_rw");
-        if (it != overrides_.end()) {
-            return it->second;
-        } else {
-            return server_configurable_flags::GetServerConfigurableFlag(
-                "aconfig_test",
-                "com.android.aconfig.test.enabled_rw",
-                "true") == "true";
-        }
-    }
-
-    virtual void enabled_rw(bool val) override {
-        overrides_["enabled_rw"] = val;
-    }
-
-    virtual void reset_flags() override {
-        overrides_.clear();
-    }
-};
-}
-"#;
-
-    const SOURCE_FILE_EXPECTED: &str = r#"
-#include "com_android_aconfig_test.h"
-#include "com_android_aconfig_test_flag_provider.h"
-
-namespace com::android::aconfig::test {
-    std::unique_ptr<flag_provider_interface> provider_ =
-        std::make_unique<flag_provider>();
-}
-"#;
-
-    const C_EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
-#pragma once
-
-#ifdef __cplusplus
 extern "C" {
-#endif
-
-bool com_android_aconfig_test_disabled_ro();
-
-bool com_android_aconfig_test_disabled_rw();
-
-bool com_android_aconfig_test_enabled_ro();
-
-bool com_android_aconfig_test_enabled_rw();
-
-#ifdef __cplusplus
-}
-#endif
-"#;
-
-    const C_EXPORTED_TEST_HEADER_EXPECTED: &str = r#"
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#endif // __cplusplus
 
 bool com_android_aconfig_test_disabled_ro();
 
@@ -422,14 +266,50 @@
 
 void com_android_aconfig_test_reset_flags();
 
+
 #ifdef __cplusplus
-}
+} // extern "C"
 #endif
+
+
 "#;
 
-    const C_PROD_SOURCE_FILE_EXPECTED: &str = r#"
-#include "com_android_aconfig_test_c.h"
+    const PROD_SOURCE_FILE_EXPECTED: &str = r#"
 #include "com_android_aconfig_test.h"
+#include <server_configurable_flags/get_flags.h>
+
+namespace com::android::aconfig::test {
+
+    class flag_provider : public flag_provider_interface {
+        public:
+
+            virtual bool disabled_ro() override {
+                return false;
+            }
+
+            virtual bool disabled_rw() override {
+                return server_configurable_flags::GetServerConfigurableFlag(
+                    "aconfig_test",
+                    "com.android.aconfig.test.disabled_rw",
+                    "false") == "true";
+            }
+
+            virtual bool enabled_ro() override {
+                return true;
+            }
+
+            virtual bool enabled_rw() override {
+                return server_configurable_flags::GetServerConfigurableFlag(
+                    "aconfig_test",
+                    "com.android.aconfig.test.enabled_rw",
+                    "true") == "true";
+            }
+
+    };
+
+    std::unique_ptr<flag_provider_interface> provider_ =
+        std::make_unique<flag_provider>();
+}
 
 bool com_android_aconfig_test_disabled_ro() {
     return false;
@@ -446,16 +326,97 @@
 bool com_android_aconfig_test_enabled_rw() {
     return com::android::aconfig::test::enabled_rw();
 }
+
 "#;
 
-    const C_TEST_SOURCE_FILE_EXPECTED: &str = r#"
-#include "com_android_aconfig_test_c.h"
+    const TEST_SOURCE_FILE_EXPECTED: &str = r#"
 #include "com_android_aconfig_test.h"
+#include <server_configurable_flags/get_flags.h>
+
+namespace com::android::aconfig::test {
+
+    class flag_provider : public flag_provider_interface {
+        private:
+            std::unordered_map<std::string, bool> overrides_;
+
+        public:
+            flag_provider()
+                : overrides_()
+            {}
+
+            virtual bool disabled_ro() override {
+                auto it = overrides_.find("disabled_ro");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return false;
+                }
+            }
+
+            virtual void disabled_ro(bool val) override {
+                overrides_["disabled_ro"] = val;
+            }
+
+            virtual bool disabled_rw() override {
+                auto it = overrides_.find("disabled_rw");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return server_configurable_flags::GetServerConfigurableFlag(
+                      "aconfig_test",
+                      "com.android.aconfig.test.disabled_rw",
+                      "false") == "true";
+                }
+            }
+
+            virtual void disabled_rw(bool val) override {
+                overrides_["disabled_rw"] = val;
+            }
+
+            virtual bool enabled_ro() override {
+                auto it = overrides_.find("enabled_ro");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return true;
+                }
+            }
+
+            virtual void enabled_ro(bool val) override {
+                overrides_["enabled_ro"] = val;
+            }
+
+            virtual bool enabled_rw() override {
+                auto it = overrides_.find("enabled_rw");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return server_configurable_flags::GetServerConfigurableFlag(
+                      "aconfig_test",
+                      "com.android.aconfig.test.enabled_rw",
+                      "true") == "true";
+                }
+            }
+
+            virtual void enabled_rw(bool val) override {
+                overrides_["enabled_rw"] = val;
+            }
+
+
+            virtual void reset_flags() override {
+                overrides_.clear();
+            }
+    };
+
+    std::unique_ptr<flag_provider_interface> provider_ =
+        std::make_unique<flag_provider>();
+}
 
 bool com_android_aconfig_test_disabled_ro() {
     return com::android::aconfig::test::disabled_ro();
 }
 
+
 void set_com_android_aconfig_test_disabled_ro(bool val) {
     com::android::aconfig::test::disabled_ro(val);
 }
@@ -464,6 +425,7 @@
     return com::android::aconfig::test::disabled_rw();
 }
 
+
 void set_com_android_aconfig_test_disabled_rw(bool val) {
     com::android::aconfig::test::disabled_rw(val);
 }
@@ -472,6 +434,7 @@
     return com::android::aconfig::test::enabled_ro();
 }
 
+
 void set_com_android_aconfig_test_enabled_ro(bool val) {
     com::android::aconfig::test::enabled_ro(val);
 }
@@ -480,14 +443,17 @@
     return com::android::aconfig::test::enabled_rw();
 }
 
+
 void set_com_android_aconfig_test_enabled_rw(bool val) {
     com::android::aconfig::test::enabled_rw(val);
 }
 
 void com_android_aconfig_test_reset_flags() {
-    com::android::aconfig::test::reset_flags();
+     com::android::aconfig::test::reset_flags();
 }
+
 "#;
+
     fn test_generate_cpp_code(mode: CodegenMode) {
         let parsed_flags = crate::test::parse_test_flags();
         let generated =
@@ -514,50 +480,14 @@
             )
         );
 
-        target_file_path = String::from("com_android_aconfig_test_flag_provider.h");
-        assert!(generated_files_map.contains_key(&target_file_path));
-        assert_eq!(
-            None,
-            crate::test::first_significant_code_diff(
-                match mode {
-                    CodegenMode::Production => PROD_FLAG_PROVIDER_HEADER_EXPECTED,
-                    CodegenMode::Test => TEST_FLAG_PROVIDER_HEADER_EXPECTED,
-                },
-                generated_files_map.get(&target_file_path).unwrap()
-            )
-        );
-
         target_file_path = String::from("com_android_aconfig_test.cc");
         assert!(generated_files_map.contains_key(&target_file_path));
         assert_eq!(
             None,
             crate::test::first_significant_code_diff(
-                SOURCE_FILE_EXPECTED,
-                generated_files_map.get(&target_file_path).unwrap()
-            )
-        );
-
-        target_file_path = String::from("include/com_android_aconfig_test_c.h");
-        assert!(generated_files_map.contains_key(&target_file_path));
-        assert_eq!(
-            None,
-            crate::test::first_significant_code_diff(
                 match mode {
-                    CodegenMode::Production => C_EXPORTED_PROD_HEADER_EXPECTED,
-                    CodegenMode::Test => C_EXPORTED_TEST_HEADER_EXPECTED,
-                },
-                generated_files_map.get(&target_file_path).unwrap()
-            )
-        );
-
-        target_file_path = String::from("com_android_aconfig_test_c.cc");
-        assert!(generated_files_map.contains_key(&target_file_path));
-        assert_eq!(
-            None,
-            crate::test::first_significant_code_diff(
-                match mode {
-                    CodegenMode::Production => C_PROD_SOURCE_FILE_EXPECTED,
-                    CodegenMode::Test => C_TEST_SOURCE_FILE_EXPECTED,
+                    CodegenMode::Production => PROD_SOURCE_FILE_EXPECTED,
+                    CodegenMode::Test => TEST_SOURCE_FILE_EXPECTED,
                 },
                 generated_files_map.get(&target_file_path).unwrap()
             )
diff --git a/tools/aconfig/src/codegen_rust.rs b/tools/aconfig/src/codegen_rust.rs
index 45303ce..053cebc 100644
--- a/tools/aconfig/src/codegen_rust.rs
+++ b/tools/aconfig/src/codegen_rust.rs
@@ -92,7 +92,7 @@
 //! codegenerated rust flag lib
 
 /// flag provider
-pub struct FlagProvider
+pub struct FlagProvider;
 
 impl FlagProvider {
     /// query flag disabled_ro
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 0ac84b2..4f0a706 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -127,6 +127,8 @@
         }
     }
 
+    // Create a sorted parsed_flags
+    crate::protos::parsed_flags::sort_parsed_flags(&mut parsed_flags);
     crate::protos::parsed_flags::verify_fields(&parsed_flags)?;
     let mut output = Vec::new();
     parsed_flags.write_to_vec(&mut output)?;
@@ -211,7 +213,7 @@
 #[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
 pub enum DumpFormat {
     Text,
-    Debug,
+    Verbose,
     Protobuf,
     Textproto,
 }
@@ -227,18 +229,27 @@
         DumpFormat::Text => {
             for parsed_flag in parsed_flags.parsed_flag.into_iter() {
                 let line = format!(
-                    "{}/{}: {:?} {:?}\n",
+                    "{}/{}: {:?} + {:?}\n",
                     parsed_flag.package(),
                     parsed_flag.name(),
-                    parsed_flag.state(),
-                    parsed_flag.permission()
+                    parsed_flag.permission(),
+                    parsed_flag.state()
                 );
                 output.extend_from_slice(line.as_bytes());
             }
         }
-        DumpFormat::Debug => {
+        DumpFormat::Verbose => {
             for parsed_flag in parsed_flags.parsed_flag.into_iter() {
-                let line = format!("{:#?}\n", parsed_flag);
+                let sources: Vec<_> =
+                    parsed_flag.trace.iter().map(|tracepoint| tracepoint.source()).collect();
+                let line = format!(
+                    "{}/{}: {:?} + {:?} ({})\n",
+                    parsed_flag.package(),
+                    parsed_flag.name(),
+                    parsed_flag.permission(),
+                    parsed_flag.state(),
+                    sources.join(", ")
+                );
                 output.extend_from_slice(line.as_bytes());
             }
         }
@@ -324,7 +335,7 @@
         let input = parse_test_flags_as_input();
         let bytes = dump_parsed_flags(vec![input], DumpFormat::Text).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert!(text.contains("com.android.aconfig.test/disabled_ro: DISABLED READ_ONLY"));
+        assert!(text.contains("com.android.aconfig.test/disabled_ro: READ_ONLY + DISABLED"));
     }
 
     #[test]
diff --git a/tools/aconfig/src/protos.rs b/tools/aconfig/src/protos.rs
index a621b87..4ddada7 100644
--- a/tools/aconfig/src/protos.rs
+++ b/tools/aconfig/src/protos.rs
@@ -255,6 +255,10 @@
         Ok(merged)
     }
 
+    pub fn sort_parsed_flags(pf: &mut ProtoParsedFlags) {
+        pf.parsed_flag.sort_by_key(create_sorting_key);
+    }
+
     fn create_sorting_key(pf: &ProtoParsedFlag) -> String {
         format!("{}.{}", pf.package(), pf.name())
     }
diff --git a/tools/aconfig/templates/c_exported_header.template b/tools/aconfig/templates/c_exported_header.template
deleted file mode 100644
index ca812a7..0000000
--- a/tools/aconfig/templates/c_exported_header.template
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" \{
-#endif
-
-{{ for item in class_elements }}
-bool {header}_{item.flag_name}();
-
-{{ if for_test }}
-void set_{header}_{item.flag_name}(bool val);
-{{ -endif }}
-{{ endfor - }}
-
-{{ if for_test }}
-void {header}_reset_flags();
-{{ -endif }}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tools/aconfig/templates/c_source_file.template b/tools/aconfig/templates/c_source_file.template
deleted file mode 100644
index 384221d..0000000
--- a/tools/aconfig/templates/c_source_file.template
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "{header}_c.h"
-#include "{header}.h"
-
-{{ for item in class_elements}}
-bool {header}_{item.flag_name}() \{
-    {{ if for_test }}
-    return {cpp_namespace}::{item.flag_name}();
-    {{ -else- }}
-    {{ if not item.readwrite- }}
-    return {item.default_value};
-    {{ -else- }}
-    return {cpp_namespace}::{item.flag_name}();
-    {{ -endif }}
-    {{ -endif }}
-}
-
-{{ if for_test }}
-void set_{header}_{item.flag_name}(bool val) \{
-    {cpp_namespace}::{item.flag_name}(val);
-}
-{{ -endif }}
-{{ endfor -}}
-
-{{ if for_test }}
-void {header}_reset_flags() \{
-     {cpp_namespace}::reset_flags();
-}
-{{ -endif }}
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index cd01853..4d56dbc 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -1,5 +1,7 @@
 #pragma once
 
+#ifdef __cplusplus
+
 #include <memory>
 
 namespace {cpp_namespace} \{
@@ -47,4 +49,25 @@
     return provider_->reset_flags();
 }
 {{ -endif }}
+
 }
+
+extern "C" \{
+#endif // __cplusplus
+
+{{ for item in class_elements }}
+bool {header}_{item.flag_name}();
+
+{{ if for_test }}
+void set_{header}_{item.flag_name}(bool val);
+{{ -endif }}
+{{ endfor - }}
+
+{{ if for_test }}
+void {header}_reset_flags();
+{{ -endif }}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
diff --git a/tools/aconfig/templates/cpp_prod_flag_provider.template b/tools/aconfig/templates/cpp_prod_flag_provider.template
deleted file mode 100644
index f908f12..0000000
--- a/tools/aconfig/templates/cpp_prod_flag_provider.template
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include "{header}.h"
-{{ if readwrite }}
-#include <server_configurable_flags/get_flags.h>
-{{ endif }}
-
-namespace {cpp_namespace} \{
-class flag_provider : public flag_provider_interface \{
-public:
-    {{ for item in class_elements}}
-    virtual bool {item.flag_name}() override \{
-        {{ if item.readwrite- }}
-        return server_configurable_flags::GetServerConfigurableFlag(
-            "{item.device_config_namespace}",
-            "{item.device_config_flag}",
-            "{item.default_value}") == "true";
-        {{ -else- }}
-            return {item.default_value};
-        {{ -endif }}
-    }
-    {{ endfor }}
-};
-}
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index d267f03..289e299 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -1,8 +1,98 @@
-
 #include "{header}.h"
-#include "{header}_flag_provider.h"
+{{ if readwrite }}
+#include <server_configurable_flags/get_flags.h>
+{{ endif }}
 
 namespace {cpp_namespace} \{
+
+{{ if for_test }}
+    class flag_provider : public flag_provider_interface \{
+    private:
+        std::unordered_map<std::string, bool> overrides_;
+
+    public:
+        flag_provider()
+            : overrides_()
+        \{}
+
+        {{ for item in class_elements}}
+        virtual bool {item.flag_name}() override \{
+            auto it = overrides_.find("{item.flag_name}");
+              if (it != overrides_.end()) \{
+                  return it->second;
+            } else \{
+              {{ if item.readwrite- }}
+              return server_configurable_flags::GetServerConfigurableFlag(
+                  "{item.device_config_namespace}",
+                  "{item.device_config_flag}",
+                  "{item.default_value}") == "true";
+              {{ -else- }}
+                  return {item.default_value};
+              {{ -endif }}
+            }
+        }
+
+        virtual void {item.flag_name}(bool val) override \{
+            overrides_["{item.flag_name}"] = val;
+        }
+        {{ endfor }}
+
+        virtual void reset_flags() override \{
+            overrides_.clear();
+        }
+    };
+
+{{ -else- }}
+
+    class flag_provider : public flag_provider_interface \{
+    public:
+        {{ for item in class_elements}}
+        virtual bool {item.flag_name}() override \{
+            {{ if item.readwrite- }}
+            return server_configurable_flags::GetServerConfigurableFlag(
+                "{item.device_config_namespace}",
+                "{item.device_config_flag}",
+                "{item.default_value}") == "true";
+            {{ -else- }}
+                return {item.default_value};
+            {{ -endif }}
+        }
+        {{ endfor }}
+    };
+
+
+{{ -endif }}
+
+
 std::unique_ptr<flag_provider_interface> provider_ =
     std::make_unique<flag_provider>();
+
 }
+
+
+{{ for item in class_elements}}
+bool {header}_{item.flag_name}() \{
+    {{ if for_test }}
+    return {cpp_namespace}::{item.flag_name}();
+    {{ -else- }}
+    {{ if not item.readwrite- }}
+    return {item.default_value};
+    {{ -else- }}
+    return {cpp_namespace}::{item.flag_name}();
+    {{ -endif }}
+    {{ -endif }}
+}
+
+{{ if for_test }}
+void set_{header}_{item.flag_name}(bool val) \{
+    {cpp_namespace}::{item.flag_name}(val);
+}
+{{ -endif }}
+{{ endfor -}}
+
+{{ if for_test }}
+void {header}_reset_flags() \{
+     {cpp_namespace}::reset_flags();
+}
+{{ -endif }}
+
diff --git a/tools/aconfig/templates/cpp_test_flag_provider.template b/tools/aconfig/templates/cpp_test_flag_provider.template
deleted file mode 100644
index 03f10a5..0000000
--- a/tools/aconfig/templates/cpp_test_flag_provider.template
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include "{header}.h"
-
-{{ if readwrite }}
-#include <server_configurable_flags/get_flags.h>
-{{ endif }}
-
-#include <unordered_map>
-#include <string>
-
-namespace {cpp_namespace} \{
-class flag_provider : public flag_provider_interface \{
-private:
-    std::unordered_map<std::string, bool> overrides_;
-
-public:
-    flag_provider()
-        : overrides_()
-    \{}
-
-    {{ for item in class_elements}}
-    virtual bool {item.flag_name}() override \{
-        auto it = overrides_.find("{item.flag_name}");
-	      if (it != overrides_.end()) \{
-	          return it->second;
-        } else \{
-          {{ if item.readwrite- }}
-          return server_configurable_flags::GetServerConfigurableFlag(
-              "{item.device_config_namespace}",
-              "{item.device_config_flag}",
-              "{item.default_value}") == "true";
-          {{ -else- }}
-              return {item.default_value};
-          {{ -endif }}
-        }
-    }
-
-    virtual void {item.flag_name}(bool val) override \{
-        overrides_["{item.flag_name}"] = val;
-    }
-    {{ endfor }}
-
-    virtual void reset_flags() override \{
-        overrides_.clear();
-    }
-};
-}
diff --git a/tools/aconfig/templates/rust_prod.template b/tools/aconfig/templates/rust_prod.template
index 543107e..d518694 100644
--- a/tools/aconfig/templates/rust_prod.template
+++ b/tools/aconfig/templates/rust_prod.template
@@ -1,7 +1,7 @@
 //! codegenerated rust flag lib
 
 /// flag provider
-pub struct FlagProvider
+pub struct FlagProvider;
 
 impl FlagProvider \{
 
diff --git a/tools/aconfig/tests/AconfigTest.java b/tools/aconfig/tests/AconfigTest.java
index 778a4c6..6681f32 100644
--- a/tools/aconfig/tests/AconfigTest.java
+++ b/tools/aconfig/tests/AconfigTest.java
@@ -1,7 +1,12 @@
+import static com.android.aconfig.test.Flags.FLAG_DISABLED_RO;
+import static com.android.aconfig.test.Flags.FLAG_DISABLED_RW;
+import static com.android.aconfig.test.Flags.FLAG_ENABLED_RO;
+import static com.android.aconfig.test.Flags.FLAG_ENABLED_RW;
 import static com.android.aconfig.test.Flags.disabledRo;
 import static com.android.aconfig.test.Flags.disabledRw;
 import static com.android.aconfig.test.Flags.enabledRo;
 import static com.android.aconfig.test.Flags.enabledRw;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -13,11 +18,13 @@
 public final class AconfigTest {
     @Test
     public void testDisabledReadOnlyFlag() {
+        assertEquals("com.android.aconfig.test.disabled_ro", FLAG_DISABLED_RO);
         assertFalse(disabledRo());
     }
 
     @Test
     public void testEnabledReadOnlyFlag() {
+        assertEquals("com.android.aconfig.test.disabled_rw", FLAG_DISABLED_RW);
         // TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
         // (currently all flags are assigned the default READ_ONLY + DISABLED)
         assertFalse(enabledRo());
@@ -25,11 +32,13 @@
 
     @Test
     public void testDisabledReadWriteFlag() {
+        assertEquals("com.android.aconfig.test.enabled_ro", FLAG_ENABLED_RO);
         assertFalse(disabledRw());
     }
 
     @Test
     public void testEnabledReadWriteFlag() {
+        assertEquals("com.android.aconfig.test.enabled_rw", FLAG_ENABLED_RW);
         // TODO: change to assertTrue(enabledRw()) when the build supports reading tests/*.values
         // (currently all flags are assigned the default READ_ONLY + DISABLED)
         assertFalse(enabledRw());
diff --git a/tools/aconfig/tests/aconfig_test.cpp b/tools/aconfig/tests/aconfig_test.cpp
new file mode 100644
index 0000000..10de347
--- /dev/null
+++ b/tools/aconfig/tests/aconfig_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "com_android_aconfig_test.h"
+#include "gtest/gtest.h"
+
+TEST(AconfigTest, TestDisabledReadOnlyFlag) {
+  ASSERT_FALSE(com_android_aconfig_test_disabled_ro());
+}
+
+TEST(AconfigTest, TestEnabledReadOnlyFlag) {
+  // TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
+  // (currently all flags are assigned the default READ_ONLY + DISABLED)
+  ASSERT_FALSE(com_android_aconfig_test_enabled_ro());
+}
+
+TEST(AconfigTest, TestDisabledReadWriteFlag) {
+  ASSERT_FALSE(com_android_aconfig_test_disabled_rw());
+}
+
+TEST(AconfigTest, TestEnabledReadWriteFlag) {
+  // TODO: change to assertTrue(enabledRo()) when the build supports reading tests/*.values
+  // (currently all flags are assigned the default READ_ONLY + DISABLED)
+  ASSERT_FALSE(com_android_aconfig_test_enabled_rw());
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index a8f6652..d7ac919 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -2,25 +2,6 @@
 
 # This flag's final value is calculated from:
 # - test.aconfig: DISABLED + READ_WRITE (default)
-# - first.values: DISABLED + READ_ONLY
-flag {
-    name: "disabled_ro"
-    namespace: "aconfig_test"
-    description: "This flag is DISABLED + READ_ONLY"
-    bug: "123"
-}
-
-# This flag's final value is calculated from:
-# - test.aconfig: DISABLED + READ_WRITE (default)
-flag {
-    name: "disabled_rw"
-    namespace: "aconfig_test"
-    description: "This flag is DISABLED + READ_WRITE"
-    bug: "456"
-}
-
-# This flag's final value is calculated from:
-# - test.aconfig: DISABLED + READ_WRITE (default)
 # - first.values: DISABLED + READ_WRITE
 # - second.values: ENABLED + READ_ONLY
 flag {
@@ -40,3 +21,22 @@
     description: "This flag is ENABLED + READ_WRITE"
     # no bug field: bug is not mandatory
 }
+
+# This flag's final value is calculated from:
+# - test.aconfig: DISABLED + READ_WRITE (default)
+# - first.values: DISABLED + READ_ONLY
+flag {
+    name: "disabled_ro"
+    namespace: "aconfig_test"
+    description: "This flag is DISABLED + READ_ONLY"
+    bug: "123"
+}
+
+# This flag's final value is calculated from:
+# - test.aconfig: DISABLED + READ_WRITE (default)
+flag {
+    name: "disabled_rw"
+    namespace: "aconfig_test"
+    description: "This flag is DISABLED + READ_WRITE"
+    bug: "456"
+}