Merge "fix typo" into main
diff --git a/core/Makefile b/core/Makefile
index 591f937..5cfd736 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -84,21 +84,6 @@
 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
-
-
 # Release & Aconfig Flags
 # -----------------------------------------------------------------
 include $(BUILD_SYSTEM)/packaging/flags.mk
@@ -5228,7 +5213,9 @@
 # apexd_host scans/activates APEX files and writes /apex/apex-info-list.xml
 # Note that `@echo $(PRIVATE_APEX_FILES)` line is added to trigger the rule when the APEX list is changed.
 $(APEX_INFO_FILE): PRIVATE_APEX_FILES := $(apex_files)
-$(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/apexd_host $(apex_files)
+$(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/apexd_host \
+    $(HOST_OUT_EXECUTABLES)/deapexer $(HOST_OUT_EXECUTABLES)/debugfs $(HOST_OUT_EXECUTABLES)/fsck.erofs \
+    $(apex_files)
 	@echo "Extracting apexes..."
 	@echo $(PRIVATE_APEX_FILES) > /dev/null
 	@rm -rf $(APEX_OUT)
@@ -5343,7 +5330,7 @@
     lz4:$(HOST_OUT_EXECUTABLES)/lz4 \
 
 
-# BOARD_KERNEL_CONFIG_FILE and BOARD_KERNEL_VERSION can be used to override the values extracted
+# BOARD_KERNEL_VERSION can be used to override the values extracted
 # from INSTALLED_KERNEL_TARGET.
 ifdef BOARD_KERNEL_VERSION
 $(BUILT_KERNEL_VERSION_FILE): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools)
@@ -5355,15 +5342,8 @@
     echo "Specified kernel version '$(BOARD_KERNEL_VERSION)' does not match actual kernel version '$$KERNEL_RELEASE' " ; exit 1; fi;
 	echo '$(BOARD_KERNEL_VERSION)' > $@
 
-ifdef BOARD_KERNEL_CONFIG_FILE
-$(BUILT_KERNEL_CONFIGS_FILE): $(BOARD_KERNEL_CONFIG_FILE)
-	cp $< $@
-
-$(call declare-license-metadata,$(BUILT_KERNEL_CONFIGS_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel)
 $(call declare-license-metadata,$(BUILT_KERNEL_VERSION_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel)
 
-my_board_extracted_kernel := true
-endif # BOARD_KERNEL_CONFIG_FILE
 endif # BOARD_KERNEL_VERSION
 
 
@@ -7170,22 +7150,6 @@
 	$(hide) find $(PRODUCT_OUT)/appcompat | sort >$(PRIVATE_LIST_FILE)
 	$(hide) $(SOONG_ZIP) -d -o $@ -C $(PRODUCT_OUT)/appcompat -l $(PRIVATE_LIST_FILE)
 
-# The mac build doesn't build dex2oat, so create the zip file only if the build OS is linux.
-ifeq ($(BUILD_OS),linux)
-ifneq ($(DEX2OAT),)
-dexpreopt_tools_deps := $(DEXPREOPT_GEN_DEPS) $(DEXPREOPT_GEN)
-dexpreopt_tools_deps += $(HOST_OUT_EXECUTABLES)/dexdump
-dexpreopt_tools_deps += $(HOST_OUT_EXECUTABLES)/oatdump
-DEXPREOPT_TOOLS_ZIP := $(PRODUCT_OUT)/dexpreopt_tools.zip
-$(DEXPREOPT_TOOLS_ZIP): $(dexpreopt_tools_deps)
-$(DEXPREOPT_TOOLS_ZIP): PRIVATE_DEXPREOPT_TOOLS_DEPS := $(dexpreopt_tools_deps)
-$(DEXPREOPT_TOOLS_ZIP): $(SOONG_ZIP)
-	$(hide) mkdir -p $(dir $@)
-	$(hide) $(SOONG_ZIP) -d -o $@ -j $(addprefix -f ,$(PRIVATE_DEXPREOPT_TOOLS_DEPS)) -f $$(realpath $(DEX2OAT))
-$(call declare-1p-target,$(DEXPREOPT_TOOLS_ZIP),)
-endif # DEX2OAT is set
-endif # BUILD_OS == linux
-
 DEXPREOPT_CONFIG_ZIP := $(PRODUCT_OUT)/dexpreopt_config.zip
 
 $(DEXPREOPT_CONFIG_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index c0f2c68..ab2d5c1 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -284,9 +284,9 @@
 ifneq ($(filter memtag_stack,$(my_sanitize)),)
   my_cflags += -fsanitize=memtag-stack
   my_ldflags += -fsanitize=memtag-stack
-  my_cflags += -Xclang -target-feature -Xclang +mte
-  my_ldflags += -Xclang -target-feature -Xclang +mte
-  my_asflags += -Xclang -target-feature -Xclang +mte
+  my_cflags += -march=armv8a+memtag
+  my_ldflags += -march=armv8a+memtag
+  my_asflags += -march=armv8a+memtag
   my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
 endif
 
diff --git a/core/main.mk b/core/main.mk
index 9710dc8..b9edfc1 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1555,7 +1555,6 @@
   $(call dist-for-goals, droidcore, \
     $(BUILT_OTATOOLS_PACKAGE) \
     $(APPCOMPAT_ZIP) \
-    $(DEXPREOPT_TOOLS_ZIP) \
   )
 
   # We dist the following targets for droidcore-unbundled (and droidcore since
@@ -1602,12 +1601,7 @@
     $(INSTALLED_FILES_JSON_SYSTEMOTHER) \
     $(INSTALLED_FILES_FILE_RECOVERY) \
     $(INSTALLED_FILES_JSON_RECOVERY) \
-    $(if $(BUILDING_SYSTEM_IMAGE), $(INSTALLED_BUILD_PROP_TARGET):build.prop) \
     $(if $(BUILDING_VENDOR_IMAGE), $(INSTALLED_VENDOR_BUILD_PROP_TARGET):build.prop-vendor) \
-    $(if $(BUILDING_PRODUCT_IMAGE), $(INSTALLED_PRODUCT_BUILD_PROP_TARGET):build.prop-product) \
-    $(if $(BUILDING_ODM_IMAGE), $(INSTALLED_ODM_BUILD_PROP_TARGET):build.prop-odm) \
-    $(if $(BUILDING_SYSTEM_EXT_IMAGE), $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET):build.prop-system_ext) \
-    $(if $(BUILDING_RAMDISK_IMAGE), $(INSTALLED_RAMDISK_BUILD_PROP_TARGET):build.prop-ramdisk) \
     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
     $(INSTALLED_MISC_INFO_TARGET) \
     $(INSTALLED_RAMDISK_TARGET) \
@@ -1701,7 +1695,6 @@
 ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
 sdk: $(ALL_SDK_TARGETS)
 $(call dist-for-goals-with-filenametag,sdk,$(ALL_SDK_TARGETS))
-$(call dist-for-goals,sdk,$(INSTALLED_BUILD_PROP_TARGET))
 endif
 
 # umbrella targets to assit engineers in verifying builds
@@ -1896,7 +1889,7 @@
 	  $(eval _is_partition_compat_symlink := $(if $(findstring $f,$(PARTITION_COMPAT_SYMLINKS)),Y)) \
 	  $(eval _is_flags_file := $(if $(findstring $f, $(ALL_FLAGS_FILES)),Y)) \
 	  $(eval _is_rootdir_symlink := $(if $(findstring $f, $(ALL_ROOTDIR_SYMLINKS)),Y)) \
-	  $(eval _is_platform_generated := $(_is_build_prop)$(_is_notice_file)$(_is_product_system_other_avbkey)$(_is_event_log_tags_file)$(_is_system_other_odex_marker)$(_is_kernel_modules_blocklist)$(_is_fsverity_build_manifest_apk)$(_is_linker_config)$(_is_partition_compat_symlink)$(_is_flags_file)$(_is_rootdir_symlink)) \
+	  $(eval _is_platform_generated := $(if $(_is_soong_module),,$(_is_build_prop)$(_is_notice_file)$(_is_product_system_other_avbkey)$(_is_event_log_tags_file)$(_is_system_other_odex_marker)$(_is_kernel_modules_blocklist)$(_is_fsverity_build_manifest_apk)$(_is_linker_config)$(_is_partition_compat_symlink)$(_is_flags_file)$(_is_rootdir_symlink))) \
 	  $(eval _static_libs := $(if $(_is_soong_module),,$(ALL_INSTALLED_FILES.$f.STATIC_LIBRARIES))) \
 	  $(eval _whole_static_libs := $(if $(_is_soong_module),,$(ALL_INSTALLED_FILES.$f.WHOLE_STATIC_LIBRARIES))) \
 	  $(eval _license_text := $(if $(filter $(_build_output_path),$(ALL_NON_MODULES)),$(ALL_NON_MODULES.$(_build_output_path).NOTICES),\
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
index a371a00..19068f4 100644
--- a/core/packaging/flags.mk
+++ b/core/packaging/flags.mk
@@ -17,9 +17,8 @@
 # the combined flags files.
 #
 
-# TODO: Should we do all of the images in $(IMAGES_TO_BUILD)?
-_FLAG_PARTITIONS := product system vendor
-
+# TODO: Should we do all of the images?
+_FLAG_PARTITIONS := product system system_ext vendor
 
 # -----------------------------------------------------------------
 # Aconfig Flags
@@ -62,28 +61,38 @@
 $(call copy-one-file, $(1), $(2))
 endef
 
+define out-dir-for-partition
+$(TARGET_COPY_OUT_$(call to-upper,$(1)))
+endef
+
+# Get the module names suitable for ALL_MODULES.* variables that are installed
+# for a given container
+# $(1): container
+define register-names-for-container
+$(sort $(foreach m,$(product_MODULES),\
+	$(if $(filter $(PRODUCT_OUT)/$(call out-dir-for-partition,$(strip $(1)))/%, $(ALL_MODULES.$(m).INSTALLED)), \
+		$(m)
+	) \
+))
+endef
+
 $(foreach partition, $(_FLAG_PARTITIONS), \
-	$(eval aconfig_flag_summaries_protobuf.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig_flags.pb) \
+	$(eval aconfig_flag_summaries_protobuf.$(partition) := $(PRODUCT_OUT)/$(call out-dir-for-partition,$(partition))/etc/aconfig_flags.pb) \
 	$(eval $(call generate-partition-aconfig-flag-file, \
 			$(TARGET_OUT_FLAGS)/$(partition)/aconfig_flags.pb, \
 			$(aconfig_flag_summaries_protobuf.$(partition)), \
 			$(partition), \
 			$(sort \
-				$(foreach m, $(call register-names-for-partition, $(partition)), \
+				$(foreach m, $(call register-names-for-container, $(partition)), \
 					$(ALL_MODULES.$(m).ACONFIG_FILES) \
 				) \
-				$(if $(filter system, $(partition)), \
-					$(foreach m, $(call register-names-for-partition, system_ext), \
-						$(ALL_MODULES.$(m).ACONFIG_FILES) \
-					) \
-				) \
 			) \
 	)) \
 )
 
 # Collect the on-device flags into a single file, similar to all_aconfig_declarations.
 required_aconfig_flags_files := \
-		$(sort $(foreach partition, $(filter $(IMAGES_TO_BUILD), $(_FLAG_PARTITIONS)), \
+		$(sort $(foreach partition, $(_FLAG_PARTITIONS), \
 			$(aconfig_flag_summaries_protobuf.$(partition)) \
 		))
 
@@ -158,10 +167,10 @@
 
 ifeq ($(RELEASE_CREATE_ACONFIG_STORAGE_FILE),true)
 $(foreach partition, $(_FLAG_PARTITIONS), \
-	$(eval aconfig_storage_package_map.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig/package.map) \
-	$(eval aconfig_storage_flag_map.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig/flag.map) \
-	$(eval aconfig_storage_flag_val.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig/flag.val) \
-	$(eval aconfig_storage_flag_info.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig/flag.info) \
+	$(eval aconfig_storage_package_map.$(partition) := $(PRODUCT_OUT)/$(call out-dir-for-partition,$(partition))/etc/aconfig/package.map) \
+	$(eval aconfig_storage_flag_map.$(partition) := $(PRODUCT_OUT)/$(call out-dir-for-partition,$(partition))/etc/aconfig/flag.map) \
+	$(eval aconfig_storage_flag_val.$(partition) := $(PRODUCT_OUT)/$(call out-dir-for-partition,$(partition))/etc/aconfig/flag.val) \
+	$(eval aconfig_storage_flag_info.$(partition) := $(PRODUCT_OUT)/$(call out-dir-for-partition,$(partition))/etc/aconfig/flag.info) \
 	$(eval $(call generate-partition-aconfig-storage-file, \
 				$(TARGET_OUT_FLAGS)/$(partition)/package.map, \
 				$(TARGET_OUT_FLAGS)/$(partition)/flag.map, \
@@ -180,7 +189,7 @@
 # -----------------------------------------------------------------
 # Install the ones we need for the configured product
 required_flags_files := \
-		$(sort $(foreach partition, $(filter $(IMAGES_TO_BUILD), $(_FLAG_PARTITIONS)), \
+		$(sort $(foreach partition, $(_FLAG_PARTITIONS), \
 			$(build_flag_summaries.$(partition)) \
 			$(aconfig_flag_summaries_protobuf.$(partition)) \
 			$(aconfig_storage_package_map.$(partition)) \
@@ -198,6 +207,8 @@
 
 
 # Clean up
+out-dir-for-partition:=
+register-names-for-container:=
 required_flags_files:=
 required_aconfig_flags_files:=
 $(foreach partition, $(_FLAG_PARTITIONS), \
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 40e2aa1..ef70fce 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -254,7 +254,6 @@
     preinstalled-packages-asl-files.xml \
     preinstalled-packages-platform.xml \
     preinstalled-packages-strict-signature.xml \
-    printflags \
     privapp-permissions-platform.xml \
     prng_seeder \
     recovery-persist \
diff --git a/target/product/build_variables.mk b/target/product/build_variables.mk
index e99ab06..8e1de8f 100644
--- a/target/product/build_variables.mk
+++ b/target/product/build_variables.mk
@@ -31,3 +31,6 @@
 
 # Use the configured MessageQueue implementation
 $(call soong_config_set, messagequeue, release_package_messagequeue_implementation, $(RELEASE_PACKAGE_MESSAGEQUEUE_IMPLEMENTATION))
+
+# Use the configured version of Cronet
+$(call soong_config_set,cronet,enable_cronet_tot,$(RELEASE_ENABLE_TOT_CRONET))
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index 5bfff66..38fa688 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -640,7 +640,6 @@
         "preinstalled-packages-platform.xml", // base_system
         "preinstalled-packages-strict-signature.xml", // base_system
         "preloaded-classes", // ok
-        "printflags", // base_system
         "privapp-permissions-platform.xml", // base_system
         "prng_seeder", // base_system
         "public.libraries.android.txt",
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 550ab5f..61802f2 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -641,7 +641,6 @@
         package com.android.aconfig.test;
         // TODO(b/303773055): Remove the annotation after access issue is resolved.
         import android.compat.annotation.UnsupportedAppUsage;
-        import android.os.Build;
         import android.os.flagging.PlatformAconfigPackageInternal;
         import android.util.Log;
         /** @hide */
@@ -1379,6 +1378,56 @@
         assert!(file_set.is_empty());
     }
 
+    // Test that the SDK check isn't added unless the library is exported (even
+    // if the flag is present in finalized_flags).
+    #[test]
+    fn test_generate_java_code_flags_with_sdk_check() {
+        let parsed_flags = crate::test::parse_test_flags();
+        let mode = CodegenMode::Production;
+        let modified_parsed_flags =
+            crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
+        let flag_ids =
+            assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+        let mut finalized_flags = FinalizedFlagMap::new();
+        finalized_flags.insert_if_new(
+            ApiLevel(36),
+            FinalizedFlag {
+                flag_name: "disabled_rw".to_string(),
+                package_name: "com.android.aconfig.test".to_string(),
+            },
+        );
+        let config = JavaCodegenConfig {
+            codegen_mode: mode,
+            flag_ids,
+            allow_instrumentation: true,
+            package_fingerprint: 5801144784618221668,
+            new_exported: true,
+            single_exported_file: false,
+            finalized_flags,
+        };
+        let generated_files = generate_java_code(
+            crate::test::TEST_PACKAGE,
+            modified_parsed_flags.into_iter(),
+            config,
+        )
+        .unwrap();
+
+        let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
+            + r#"
+        private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
+        }"#;
+
+        let file = generated_files.iter().find(|f| f.path.ends_with("Flags.java")).unwrap();
+        assert_eq!(
+            None,
+            crate::test::first_significant_code_diff(
+                &expect_flags_content,
+                &String::from_utf8(file.contents.clone()).unwrap()
+            ),
+            "Flags content is not correct"
+        );
+    }
+
     #[test]
     fn test_generate_java_code_test() {
         let parsed_flags = crate::test::parse_test_flags();
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index 0c80d3b..14a98f0 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -81,18 +81,8 @@
             .read_to_string(&mut contents)
             .with_context(|| format!("failed to read {}", input.source))?;
 
-        let mut flag_declarations =
-            aconfig_protos::flag_declarations::try_from_text_proto(&contents)
-                .with_context(|| input.error_context())?;
-
-        // system_ext flags should be treated as system flags as we are combining /system_ext
-        // and /system as one container
-        // TODO: remove this logic when we start enforcing that system_ext cannot be set as
-        // container in aconfig declaration files.
-        if flag_declarations.container() == "system_ext" {
-            flag_declarations.set_container(String::from("system"));
-        }
-
+        let flag_declarations = aconfig_protos::flag_declarations::try_from_text_proto(&contents)
+            .with_context(|| input.error_context())?;
         ensure!(
             package == flag_declarations.package(),
             "failed to parse {}: expected package {}, got {}",
@@ -462,6 +452,7 @@
 pub fn should_include_flag(pf: &ProtoParsedFlag) -> bool {
     let should_filter_container = pf.container == Some("vendor".to_string())
         || pf.container == Some("system".to_string())
+        || pf.container == Some("system_ext".to_string())
         || pf.container == Some("product".to_string());
 
     let disabled_ro = pf.state == Some(ProtoFlagState::DISABLED.into())
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template
index 9492a83..8dc7581 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template
@@ -2,7 +2,6 @@
 // TODO(b/303773055): Remove the annotation after access issue is resolved.
 import android.compat.annotation.UnsupportedAppUsage;
 {{ -if runtime_lookup_required }}
-import android.os.Build;
 {{ if is_platform_container }}
 import android.os.flagging.PlatformAconfigPackageInternal;
 {{ -else }} {#- else is_platform_container #}
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index 6fa2701..0cdc269 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -4,7 +4,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 {{ else }}
 import android.os.Build;
-{{ -endif }}
+{{ -endif }} {#- end not library_exported#}
 {{ -if single_exported_file }}
 {{ -if library_exported }}
 /**
@@ -33,11 +33,13 @@
     @UnsupportedAppUsage
 {{ -endif }}
     public static boolean {item.method_name}() \{
+        {{ if library_exported- }}
         {{ -if item.finalized_sdk_present }}
         if (Build.VERSION.SDK_INT >= {item.finalized_sdk_value}) \{
           return true;
         }
         {{ -endif}}  {#- end finalized_sdk_present#}
+        {{ -endif}}  {#- end library_exported#}
         return FEATURE_FLAGS.{item.method_name}();
     }
 {{ -endfor }}
diff --git a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
index e997e3d..140cd21 100644
--- a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
+++ b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
@@ -1,3 +1,4 @@
 "/system/etc/aconfig_flags.pb",
+"/system_ext/etc/aconfig_flags.pb",
 "/product/etc/aconfig_flags.pb",
 "/vendor/etc/aconfig_flags.pb",
diff --git a/tools/aconfig/aconfig_device_paths/src/lib.rs b/tools/aconfig/aconfig_device_paths/src/lib.rs
index 8871b4f..9ab9cea 100644
--- a/tools/aconfig/aconfig_device_paths/src/lib.rs
+++ b/tools/aconfig/aconfig_device_paths/src/lib.rs
@@ -62,12 +62,13 @@
 
     #[test]
     fn test_read_partition_paths() {
-        assert_eq!(read_partition_paths().len(), 3);
+        assert_eq!(read_partition_paths().len(), 4);
 
         assert_eq!(
             read_partition_paths(),
             vec![
                 PathBuf::from("/system/etc/aconfig_flags.pb"),
+                PathBuf::from("/system_ext/etc/aconfig_flags.pb"),
                 PathBuf::from("/product/etc/aconfig_flags.pb"),
                 PathBuf::from("/vendor/etc/aconfig_flags.pb")
             ]
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java
index dc465b6..213f158 100644
--- a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java
@@ -26,6 +26,9 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.Objects;
+import java.util.concurrent.CyclicBarrier;
+
 @RunWith(JUnit4.class)
 public class FlagTableTest {
 
@@ -100,4 +103,53 @@
         assertEquals(-1, node7.getNextOffset());
         assertEquals(-1, node8.getNextOffset());
     }
+
+    @Test
+    public void testFlagTable_multithreadsRead() throws Exception {
+        FlagTable flagTable = FlagTable.fromBytes(TestDataUtils.getTestFlagMapByteBuffer(2));
+
+        int numberOfThreads = 8;
+        Thread[] threads = new Thread[numberOfThreads];
+        final CyclicBarrier gate = new CyclicBarrier(numberOfThreads + 1);
+        String[] expects = {
+            "enabled_ro",
+            "enabled_rw",
+            "enabled_rw",
+            "disabled_rw",
+            "enabled_fixed_ro",
+            "enabled_ro",
+            "enabled_fixed_ro",
+            "disabled_rw"
+        };
+        int[] packageIds = {0, 0, 2, 1, 1, 1, 2, 0};
+
+        for (int i = 0; i < numberOfThreads; i++) {
+            String expectRet = expects[i];
+            int packageId = packageIds[i];
+            threads[i] =
+                    new Thread() {
+                        @Override
+                        public void run() {
+                            try {
+                                gate.await();
+                            } catch (Exception e) {
+                            }
+                            for (int j = 0; j < 10; j++) {
+                                if (!Objects.equals(
+                                        expectRet,
+                                        flagTable.get(packageId, expectRet).getFlagName())) {
+                                    throw new RuntimeException();
+                                }
+                            }
+                        }
+                    };
+            threads[i].start();
+        }
+
+        gate.await();
+
+        for (int i = 0; i < numberOfThreads; i++) {
+            threads[i].join();
+        }
+    }
 }
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java
index 306df7d..6311c19 100644
--- a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java
@@ -28,6 +28,9 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.Objects;
+import java.util.concurrent.CyclicBarrier;
+
 @RunWith(JUnit4.class)
 public class FlagValueListTest {
 
@@ -74,4 +77,43 @@
         fNode = flagTable.get(pNode.getPackageId(), "enabled_fixed_ro");
         assertTrue(flagValueList.getBoolean(pNode.getBooleanStartIndex() + fNode.getFlagIndex()));
     }
+
+    @Test
+    public void testFlagValueList_multithreadsRead() throws Exception {
+        FlagValueList flagValueList =
+                FlagValueList.fromBytes(TestDataUtils.getTestFlagValByteBuffer(2));
+
+        int numberOfThreads = 8;
+        Thread[] threads = new Thread[numberOfThreads];
+        final CyclicBarrier gate = new CyclicBarrier(numberOfThreads + 1);
+        boolean[] expects = {false, true, true, false, true, true, true, true};
+
+        for (int i = 0; i < numberOfThreads; i++) {
+            boolean expectRet = expects[i];
+            int position = i;
+            threads[i] =
+                    new Thread() {
+                        @Override
+                        public void run() {
+                            try {
+                                gate.await();
+                            } catch (Exception e) {
+                            }
+                            for (int j = 0; j < 10; j++) {
+                                if (!Objects.equals(
+                                        expectRet, flagValueList.getBoolean(position))) {
+                                    throw new RuntimeException();
+                                }
+                            }
+                        }
+                    };
+            threads[i].start();
+        }
+
+        gate.await();
+
+        for (int i = 0; i < numberOfThreads; i++) {
+            threads[i].join();
+        }
+    }
 }
diff --git a/tools/aconfig/printflags/Android.bp b/tools/aconfig/printflags/Android.bp
deleted file mode 100644
index 6f7bca3..0000000
--- a/tools/aconfig/printflags/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_defaults {
-    name: "printflags.defaults",
-    edition: "2021",
-    clippy_lints: "android",
-    lints: "android",
-    srcs: ["src/main.rs"],
-    rustlibs: [
-        "libaconfig_protos",
-        "libanyhow",
-        "libprotobuf",
-        "libregex",
-    ],
-}
-
-rust_binary {
-    name: "printflags",
-    defaults: ["printflags.defaults"],
-    apex_available: [
-        "//apex_available:platform",
-    ],
-}
-
-rust_test_host {
-    name: "printflags.test",
-    defaults: ["printflags.defaults"],
-    test_suites: ["general-tests"],
-}
diff --git a/tools/aconfig/printflags/Cargo.toml b/tools/aconfig/printflags/Cargo.toml
deleted file mode 100644
index 7313f5d..0000000
--- a/tools/aconfig/printflags/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "printflags"
-version = "0.1.0"
-edition = "2021"
-
-[features]
-default = ["cargo"]
-cargo = []
-
-[dependencies]
-anyhow = "1.0.69"
-paste = "1.0.11"
-protobuf = "3.2.0"
-regex = "1.10.3"
-aconfig_protos = { path = "../aconfig_protos" }
diff --git a/tools/aconfig/printflags/src/main.rs b/tools/aconfig/printflags/src/main.rs
deleted file mode 100644
index 7838b51..0000000
--- a/tools/aconfig/printflags/src/main.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.
- */
-
-//! `printflags` is a device binary to print feature flags.
-
-use aconfig_protos::ProtoFlagState as State;
-use aconfig_protos::ProtoParsedFlags;
-use anyhow::{bail, Context, Result};
-use regex::Regex;
-use std::collections::BTreeMap;
-use std::collections::HashMap;
-use std::process::Command;
-use std::{fs, str};
-
-fn parse_device_config(raw: &str) -> HashMap<String, String> {
-    let mut flags = HashMap::new();
-    let regex = Regex::new(r"(?m)^([[[:alnum:]]_]+/[[[:alnum:]]_\.]+)=(true|false)$").unwrap();
-    for capture in regex.captures_iter(raw) {
-        let key = capture.get(1).unwrap().as_str().to_string();
-        let value = match capture.get(2).unwrap().as_str() {
-            "true" => format!("{:?} (device_config)", State::ENABLED),
-            "false" => format!("{:?} (device_config)", State::DISABLED),
-            _ => panic!(),
-        };
-        flags.insert(key, value);
-    }
-    flags
-}
-
-fn xxd(bytes: &[u8]) -> String {
-    let n = 8.min(bytes.len());
-    let mut v = Vec::with_capacity(n);
-    for byte in bytes.iter().take(n) {
-        v.push(format!("{:02x}", byte));
-    }
-    let trailer = match bytes.len() {
-        0..=8 => "",
-        _ => " ..",
-    };
-    format!("[{}{}]", v.join(" "), trailer)
-}
-
-fn main() -> Result<()> {
-    // read device_config
-    let output = Command::new("/system/bin/device_config").arg("list").output()?;
-    if !output.status.success() {
-        let reason = match output.status.code() {
-            Some(code) => format!("exit code {}", code),
-            None => "terminated by signal".to_string(),
-        };
-        bail!("failed to execute device_config: {}", reason);
-    }
-    let dc_stdout = str::from_utf8(&output.stdout)?;
-    let device_config_flags = parse_device_config(dc_stdout);
-
-    // read aconfig_flags.pb files
-    let apex_pattern = Regex::new(r"^/apex/[^@]+\.[^@]+$").unwrap();
-    let mut mount_points = vec![
-        "system".to_string(),
-        "system_ext".to_string(),
-        "product".to_string(),
-        "vendor".to_string(),
-    ];
-    for apex in fs::read_dir("/apex")? {
-        let path_name = apex?.path().display().to_string();
-        if let Some(canonical_path) = apex_pattern.captures(&path_name) {
-            mount_points.push(canonical_path.get(0).unwrap().as_str().to_owned());
-        }
-    }
-
-    let mut flags: BTreeMap<String, Vec<String>> = BTreeMap::new();
-    for mount_point in mount_points {
-        let path = format!("/{}/etc/aconfig_flags.pb", mount_point);
-        let Ok(bytes) = fs::read(&path) else {
-            eprintln!("warning: failed to read {}", path);
-            continue;
-        };
-        let parsed_flags: ProtoParsedFlags = protobuf::Message::parse_from_bytes(&bytes)
-            .with_context(|| {
-                format!("failed to parse {} ({}, {} byte(s))", path, xxd(&bytes), bytes.len())
-            })?;
-        for flag in parsed_flags.parsed_flag {
-            let key = format!("{}/{}.{}", flag.namespace(), flag.package(), flag.name());
-            let value = format!("{:?} + {:?} ({})", flag.permission(), flag.state(), mount_point);
-            flags.entry(key).or_default().push(value);
-        }
-    }
-
-    // print flags
-    for (key, mut value) in flags {
-        if let Some(dc_value) = device_config_flags.get(&key) {
-            value.push(dc_value.to_string());
-        }
-        println!("{}: {}", key, value.join(", "));
-    }
-
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_parse_device_config() {
-        let input = r#"
-namespace_one/com.foo.bar.flag_one=true
-namespace_one/com.foo.bar.flag_two=false
-random_noise;
-namespace_two/android.flag_one=true
-namespace_two/android.flag_two=nonsense
-"#;
-        let expected = HashMap::from([
-            (
-                "namespace_one/com.foo.bar.flag_one".to_string(),
-                "ENABLED (device_config)".to_string(),
-            ),
-            (
-                "namespace_one/com.foo.bar.flag_two".to_string(),
-                "DISABLED (device_config)".to_string(),
-            ),
-            ("namespace_two/android.flag_one".to_string(), "ENABLED (device_config)".to_string()),
-        ]);
-        let actual = parse_device_config(input);
-        assert_eq!(expected, actual);
-    }
-
-    #[test]
-    fn test_xxd() {
-        let input = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9];
-        assert_eq!("[]", &xxd(&input[0..0]));
-        assert_eq!("[00]", &xxd(&input[0..1]));
-        assert_eq!("[00 01]", &xxd(&input[0..2]));
-        assert_eq!("[00 01 02 03 04 05 06]", &xxd(&input[0..7]));
-        assert_eq!("[00 01 02 03 04 05 06 07]", &xxd(&input[0..8]));
-        assert_eq!("[00 01 02 03 04 05 06 07 ..]", &xxd(&input[0..9]));
-        assert_eq!("[00 01 02 03 04 05 06 07 ..]", &xxd(&input));
-    }
-}
diff --git a/tools/sbom/compliance_metadata.py b/tools/sbom/compliance_metadata.py
index 502c110..2f0b180 100644
--- a/tools/sbom/compliance_metadata.py
+++ b/tools/sbom/compliance_metadata.py
@@ -123,7 +123,7 @@
 
   def get_installed_files(self):
     # Get all records from table make_metadata, which contains all installed files and corresponding make modules' metadata
-    cursor = self.conn.execute('select installed_file, module_path, is_prebuilt_make_module, product_copy_files, kernel_module_copy_files, is_platform_generated, license_text from make_metadata')
+    cursor = self.conn.execute('select installed_file, module_path, is_soong_module, is_prebuilt_make_module, product_copy_files, kernel_module_copy_files, is_platform_generated, license_text from make_metadata')
     rows = cursor.fetchall()
     cursor.close()
     installed_files_metadata = []
@@ -135,7 +135,7 @@
   def get_installed_file_in_dir(self, dir):
     dir = dir.removesuffix('/')
     cursor = self.conn.execute(
-        'select installed_file, module_path, is_prebuilt_make_module, product_copy_files, '
+        'select installed_file, module_path, is_soong_module, is_prebuilt_make_module, product_copy_files, '
         '       kernel_module_copy_files, is_platform_generated, license_text '
         'from make_metadata '
         'where installed_file like ?', (dir + '/%',))
diff --git a/tools/sbom/gen_sbom.py b/tools/sbom/gen_sbom.py
index 77bccbb..e875ddb 100644
--- a/tools/sbom/gen_sbom.py
+++ b/tools/sbom/gen_sbom.py
@@ -415,11 +415,13 @@
 def installed_file_has_metadata(installed_file_metadata, report):
   installed_file = installed_file_metadata['installed_file']
   module_path = installed_file_metadata['module_path']
+  is_soong_module = installed_file_metadata['is_soong_module']
   product_copy_files = installed_file_metadata['product_copy_files']
   kernel_module_copy_files = installed_file_metadata['kernel_module_copy_files']
   is_platform_generated = installed_file_metadata['is_platform_generated']
 
   if (not module_path and
+      not is_soong_module and
       not product_copy_files and
       not kernel_module_copy_files and
       not is_platform_generated and