Merge "Fix test failures in releasetools" into main
diff --git a/Changes.md b/Changes.md
index fc6701d..6836528 100644
--- a/Changes.md
+++ b/Changes.md
@@ -10,8 +10,9 @@
 build team via email android-building@googlegroups.com (external) for any
 questions, or see [go/soong](http://go/soong) (internal).
 
-To omit the validation, `BUILD_BROKEN_PLUGIN_VALIDATION` expects a list of
-plugins to omit from the validation.
+To omit the validation, `BUILD_BROKEN_PLUGIN_VALIDATION` expects a
+space-separated list of plugins to omit from the validation. This must be set
+within a product configuration .mk file, board config .mk file, or buildspec.mk.
 
 ## Python 2 to 3 migration
 
diff --git a/core/Makefile b/core/Makefile
index 3bd6ae1..dcec2e5 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.
@@ -5693,11 +5733,11 @@
 
 # $(1): Directory to copy
 # $(2): Location to copy it to
-# The "ls -A" is to prevent "acp s/* d" from failing if s is empty.
+# The "ls -A" is to skip if $(1) is empty.
 define package_files-copy-root
   if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \
     mkdir -p $(2) && \
-    $(ACP) -rd $(strip $(1))/* $(2); \
+    $(ACP) -rd $(strip $(1))/. $(strip $(2))/; \
   fi
 endef
 
@@ -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/aapt2.mk b/core/aapt2.mk
index 7b17df4..0e23477 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -68,6 +68,8 @@
 # support for it.
 my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
+my_static_library_transitive_resource_packages_lists := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
+  $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/transitive-res-packages)
 my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/extra_packages)
 my_shared_library_resources := $(foreach l, $(LOCAL_SHARED_ANDROID_LIBRARIES),\
@@ -95,6 +97,7 @@
 $(my_res_package): PRIVATE_JAVA_GEN_DIR := $(intermediates.COMMON)/aapt2
 $(my_res_package): PRIVATE_SRCJAR := $(my_srcjar)
 $(my_res_package): PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES := $(my_static_library_extra_packages)
+$(my_res_package): PRIVATE_STATIC_LIBRARY_TRANSITIVE_RES_PACKAGES_LISTS := $(my_static_library_transitive_resource_packages_lists)
 $(my_res_package): PRIVATE_AAPT_EXTRA_PACKAGES := $(aapt_extra_packages)
 $(my_res_package): .KATI_IMPLICIT_OUTPUTS := $(my_srcjar) $(aapt_extra_packages)
 
@@ -117,7 +120,7 @@
 $(my_res_package): .KATI_IMPLICIT_OUTPUTS += $(proguard_options_file)
 endif
 
-$(my_res_package): $(full_android_manifest) $(my_static_library_resources) $(my_shared_library_resources)
+$(my_res_package): $(full_android_manifest) $(my_static_library_resources) $(my_static_library_transitive_resource_packages_lists) $(my_shared_library_resources)
 $(my_res_package): $(my_full_asset_paths)
 $(my_res_package): $(my_res_resources_flat) $(my_overlay_resources_flat) \
   $(my_resources_flata) $(my_static_library_resources) $(my_static_library_extra_packages) \
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/board_config.mk b/core/board_config.mk
index 856fde2..c3a6864 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -171,7 +171,6 @@
 
 
 _build_broken_var_list := \
-  BUILD_BROKEN_PLUGIN_VALIDATION \
   BUILD_BROKEN_CLANG_PROPERTY \
   BUILD_BROKEN_CLANG_ASFLAGS \
   BUILD_BROKEN_CLANG_CFLAGS \
@@ -186,7 +185,6 @@
   BUILD_BROKEN_PREBUILT_ELF_FILES \
   BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW \
   BUILD_BROKEN_USES_NETWORK \
-  BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES \
   BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE \
   BUILD_BROKEN_VINTF_PRODUCT_COPY_FILES \
 
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index bb7ba1b..409e559 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:=
@@ -297,6 +298,7 @@
 LOCAL_SOONG_PROGUARD_DICT :=
 LOCAL_SOONG_PROGUARD_USAGE_ZIP :=
 LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
+LOCAL_SOONG_TRANSITIVE_RES_PACKAGES :=
 LOCAL_SOONG_DEVICE_RRO_DIRS :=
 LOCAL_SOONG_PRODUCT_RRO_DIRS :=
 LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
diff --git a/core/config.mk b/core/config.mk
index 5de5504..e919be3 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -342,6 +342,23 @@
 JAVA_TMPDIR_ARG :=
 endif
 
+# These build broken variables are intended to be set in a buildspec file,
+# while other build broken flags are expected to be set in a board config.
+# These are build broken variables that are expected to apply across board
+# configs, generally for cross-cutting features.
+
+# Build broken variables that should be treated as booleans
+_build_broken_bool_vars := \
+  BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES \
+
+# Build broken variables that should be treated as lists
+_build_broken_list_vars := \
+  BUILD_BROKEN_PLUGIN_VALIDATION \
+
+_build_broken_var_names := $(_build_broken_bool_vars)
+_build_broken_var_names += $(_build_broken_list_vars)
+$(foreach v,$(_build_broken_var_names),$(eval $(v) :=))
+
 # ###############################################################
 # Include sub-configuration files
 # ###############################################################
@@ -371,6 +388,13 @@
 # are specific to the user's build configuration.
 include $(BUILD_SYSTEM)/envsetup.mk
 
+
+$(foreach var,$(_build_broken_bool_vars), \
+  $(if $(filter-out true false,$($(var))), \
+    $(error Valid values of $(var) are "true", "false", and "". Not "$($(var))")))
+
+.KATI_READONLY := $(_build_broken_var_names)
+
 # Returns true if it is a low memory device, otherwise it returns false.
 define is-low-mem-device
 $(if $(findstring ro.config.low_ram=true,$(PRODUCT_PROPERTY_OVERRIDES)),true,\
@@ -401,6 +425,7 @@
 endif
 
 # Set TARGET_MAX_PAGE_SIZE_SUPPORTED.
+# TARGET_MAX_PAGE_SIZE_SUPPORTED indicates the alignment of the ELF segments.
 ifdef PRODUCT_MAX_PAGE_SIZE_SUPPORTED
   TARGET_MAX_PAGE_SIZE_SUPPORTED := $(PRODUCT_MAX_PAGE_SIZE_SUPPORTED)
 else ifeq ($(strip $(call is-low-mem-device)),true)
@@ -411,11 +436,38 @@
   TARGET_MAX_PAGE_SIZE_SUPPORTED := 4096
   # When VSR vendor API level >= 34, binary alignment will be 65536.
   ifeq ($(call math_gt_or_eq,$(vsr_vendor_api_level),34),true)
+    ifeq ($(TARGET_ARCH),arm64)
       TARGET_MAX_PAGE_SIZE_SUPPORTED := 65536
+    endif
+    ifeq ($(TARGET_ARCH),arm)
+      TARGET_MAX_PAGE_SIZE_SUPPORTED := 65536
+    endif
   endif
 endif
 .KATI_READONLY := TARGET_MAX_PAGE_SIZE_SUPPORTED
 
+# Check that TARGET_MAX_PAGE_SIZE_SUPPORTED is greater than 4096 only for ARM arch.
+ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),4096)
+  ifneq ($(TARGET_ARCH),arm64)
+    ifneq ($(TARGET_ARCH),arm)
+      $(error TARGET_MAX_PAGE_SIZE_SUPPORTED=$(TARGET_MAX_PAGE_SIZE_SUPPORTED) is greater than 4096. Only supported in ARM arch)
+    endif
+  endif
+endif
+
+# Boolean variable determining if AOSP is page size agnostic. This means
+# that AOSP can use a kernel configured with 4k/16k/64k PAGE SIZES.
+TARGET_PAGE_SIZE_AGNOSTIC := false
+ifdef PRODUCT_PAGE_SIZE_AGNOSTIC
+  TARGET_PAGE_SIZE_AGNOSTIC := $(PRODUCT_PAGE_SIZE_AGNOSTIC)
+  ifeq ($(TARGET_PAGE_SIZE_AGNOSTIC),true)
+      ifneq ($(TARGET_MAX_PAGE_SIZE_SUPPORTED),65536)
+          $(error TARGET_MAX_PAGE_SIZE_SUPPORTED has to be 65536 to support page size agnostic)
+      endif
+  endif
+endif
+.KATI_READONLY := TARGET_PAGE_SIZE_AGNOSTIC
+
 # Pruned directory options used when using findleaves.py
 # See envsetup.mk for a description of SCAN_EXCLUDE_DIRS
 FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(SCAN_EXCLUDE_DIRS) .repo .git)
@@ -625,6 +677,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/definitions.mk b/core/definitions.mk
index 2484f1e..462c968 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2377,6 +2377,7 @@
 mkdir -p $(PRIVATE_JAVA_GEN_DIR)
 $(call dump-words-to-file,$(PRIVATE_RES_FLAT),$(dir $@)aapt2-flat-list)
 $(call dump-words-to-file,$(PRIVATE_OVERLAY_FLAT),$(dir $@)aapt2-flat-overlay-list)
+cat $(PRIVATE_STATIC_LIBRARY_TRANSITIVE_RES_PACKAGES_LISTS) | sort -u | tr '\n' ' ' > $(dir $@)aapt2-transitive-overlay-list
 $(hide) $(AAPT2) link -o $@ \
   $(PRIVATE_AAPT_FLAGS) \
   $(if $(PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES),$$(cat $(PRIVATE_STATIC_LIBRARY_EXTRA_PACKAGES))) \
@@ -2396,6 +2397,7 @@
   $(addprefix --rename-manifest-package ,$(PRIVATE_MANIFEST_PACKAGE_NAME)) \
   $(addprefix --rename-instrumentation-target-package ,$(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
   -R \@$(dir $@)aapt2-flat-overlay-list \
+  -R \@$(dir $@)aapt2-transitive-overlay-list \
   \@$(dir $@)aapt2-flat-list
 $(SOONG_ZIP) -o $(PRIVATE_SRCJAR) -C $(PRIVATE_JAVA_GEN_DIR) -D $(PRIVATE_JAVA_GEN_DIR)
 $(EXTRACT_JAR_PACKAGES) -i $(PRIVATE_SRCJAR) -o $(PRIVATE_AAPT_EXTRA_PACKAGES) --prefix '--extra-packages '
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/core/product.mk b/core/product.mk
index 99b3dea..b66f1e2 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -33,6 +33,10 @@
 # 4096, 16384 and 65536.
 _product_single_value_vars += PRODUCT_MAX_PAGE_SIZE_SUPPORTED
 
+# Indicates that AOSP can use a kernel configured with 4k/16k/64k page sizes.
+# The possible values are true or false.
+_product_single_value_vars += PRODUCT_PAGE_SIZE_AGNOSTIC
+
 # The resource configuration options to use for this product.
 _product_list_vars += PRODUCT_LOCALES
 _product_list_vars += PRODUCT_AAPT_CONFIG
diff --git a/core/soong_config.mk b/core/soong_config.mk
index d8b18e7..bd6cfbb 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -40,6 +40,7 @@
 $(call add_json_str,  Platform_base_os,                  $(PLATFORM_BASE_OS))
 $(call add_json_str,  Platform_version_last_stable,      $(PLATFORM_VERSION_LAST_STABLE))
 $(call add_json_str,  Platform_version_known_codenames,  $(PLATFORM_VERSION_KNOWN_CODENAMES))
+$(call add_json_bool, Release_aidl_use_unfrozen,         $(RELEASE_AIDL_USE_UNFROZEN))
 
 $(call add_json_str,  Platform_min_supported_target_sdk_version, $(PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION))
 
@@ -150,6 +151,7 @@
 $(call add_json_bool, Malloc_pattern_fill_contents,      $(MALLOC_PATTERN_FILL_CONTENTS))
 $(call add_json_str,  Override_rs_driver,                $(OVERRIDE_RS_DRIVER))
 $(call add_json_str,  DeviceMaxPageSizeSupported,        $(TARGET_MAX_PAGE_SIZE_SUPPORTED))
+$(call add_json_bool, Device_page_size_agnostic,         $(filter true,$(TARGET_PAGE_SIZE_AGNOSTIC)))
 
 $(call add_json_bool, UncompressPrivAppDex,              $(call invert_bool,$(filter true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS))))
 $(call add_json_list, ModulesLoadedByPrivilegedModules,  $(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index a8f475f..c7c6a11 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -99,6 +99,17 @@
 
   $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_res_package))
 
+  my_transitive_res_packages := $(intermediates.COMMON)/transitive-res-packages
+  $(my_transitive_res_packages): PRIVATE_TRANSITIVE_RES_PACKAGES := $(filter-out $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE),$(LOCAL_SOONG_TRANSITIVE_RES_PACKAGES))
+  $(my_transitive_res_packages):
+	@echo Write transitive resource package list $@
+	rm -f $@
+	touch $@
+	$(foreach f,$(PRIVATE_TRANSITIVE_RES_PACKAGES),\
+	  echo "$f" >> $@; )
+
+  $(call add-dependency,$(my_res_package),$(my_transitive_res_packages))
+
   my_proguard_flags := $(intermediates.COMMON)/export_proguard_flags
   $(my_proguard_flags): $(LOCAL_SOONG_EXPORT_PROGUARD_FLAGS)
 	@echo "Export proguard flags: $@"
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 4053985..4a72a1f 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -127,6 +127,12 @@
 endif
 endif
 
+# transitive-res-packages is only populated for Soong modules for now, but needs
+# to exist so that other Make modules can depend on it.  Create an empty file.
+my_transitive_res_packages := $(intermediates.COMMON)/transitive-res-packages
+$(my_transitive_res_packages):
+	touch $@
+
 import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
     $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags))
 $(intermediates.COMMON)/export_proguard_flags: $(import_proguard_flag_files) $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 81e037d..f82d177 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -40,8 +40,11 @@
 
 # List of jars to be included in the ART boot image for testing.
 # DO NOT reorder this list. The order must match the one described above.
+# Note: We use the host variant of "core-icu4j" and "conscrypt" for testing.
 PRODUCT_TEST_ONLY_ART_BOOT_IMAGE_JARS := \
-    $(ART_APEX_JARS)
+    $(ART_APEX_JARS) \
+    platform:core-icu4j-host \
+    platform:conscrypt-host \
 
 # /system and /system_ext boot jars.
 PRODUCT_BOOT_JARS += \
@@ -116,6 +119,8 @@
 # <old_apex>:<old_jar>:<new_apex>:<new_jar>
 PRODUCT_CONFIGURED_JAR_LOCATION_OVERRIDES := \
     platform:framework-minus-apex:platform:framework \
+    platform:core-icu4j-host:com.android.i18n:core-icu4j \
+    platform:conscrypt-host:com.android.conscrypt:conscrypt \
 
 # Minimal configuration for running dex2oat (default argument values).
 # PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
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"
+}