Merge "Don't store notice files for Soong modules" into main
diff --git a/core/Makefile b/core/Makefile
index 09c815e..18f2c39 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1306,11 +1306,8 @@
 INTERNAL_BOOTIMAGE_ARGS := \
 	$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET))
 
-# TODO(b/229701033): clean up BOARD_BUILD_GKI_BOOT_IMAGE_WITHOUT_RAMDISK.
-ifneq ($(BOARD_BUILD_GKI_BOOT_IMAGE_WITHOUT_RAMDISK),true)
-  ifneq ($(BUILDING_INIT_BOOT_IMAGE),true)
-    INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
-  endif
+ifneq ($(BUILDING_INIT_BOOT_IMAGE),true)
+  INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
 endif
 
 ifndef BUILDING_VENDOR_BOOT_IMAGE
@@ -2348,8 +2345,6 @@
 )
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
-$(if $(filter true,$(BOARD_BUILD_GKI_BOOT_IMAGE_WITHOUT_RAMDISK)),\
-    $(hide) echo "gki_boot_image_without_ramdisk=true" >> $(1))
 $(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1)
 $(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITION_SIZE)),\
     $(hide) echo "use_dynamic_partition_size=true" >> $(1))
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 6d64f97..c74aa49 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -31,6 +31,7 @@
 $(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
 $(call add_soong_config_var,ANDROID,BOARD_USES_ODMIMAGE)
 $(call add_soong_config_var,ANDROID,BOARD_USES_RECOVERY_AS_BOOT)
+$(call add_soong_config_var,ANDROID,CHECK_DEV_TYPE_VIOLATIONS)
 $(call add_soong_config_var,ANDROID,PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT)
 
 # Default behavior for the tree wrt building modules or using prebuilts. This
@@ -180,7 +181,13 @@
 else
   SYSTEM_OPTIMIZE_JAVA ?= true
 endif
+
+ifeq (true,$(FULL_SYSTEM_OPTIMIZE_JAVA))
+  SYSTEM_OPTIMIZE_JAVA := true
+endif
+
 $(call add_soong_config_var,ANDROID,SYSTEM_OPTIMIZE_JAVA)
+$(call add_soong_config_var,ANDROID,FULL_SYSTEM_OPTIMIZE_JAVA)
 
 # Check for SupplementalApi module.
 ifeq ($(wildcard packages/modules/SupplementalApi),)
diff --git a/core/config.mk b/core/config.mk
index 90cc33c..eefd268 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -1313,3 +1313,9 @@
 .KATI_READONLY := DEFAULT_DATA_OUT_MODULES
 
 include $(BUILD_SYSTEM)/dumpvar.mk
+
+ifeq (true,$(FULL_SYSTEM_OPTIMIZE_JAVA))
+ifeq (,$(SYSTEM_OPTIMIZE_JAVA))
+$(error SYSTEM_OPTIMIZE_JAVA must be enabled when FULL_SYSTEM_OPTIMIZE_JAVA is enabled)
+endif
+endif
diff --git a/core/main.mk b/core/main.mk
index 367b5bf..348a964 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -182,6 +182,12 @@
 $(KATI_obsolete_var PRODUCT_FULL_TREBLE,\
 	Code should be written to work regardless of a device being Treble)
 
+# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK in
+# the system partition supports.
+ifdef RELEASE_BOARD_API_LEVEL
+ADDITIONAL_SYSTEM_PROPERTIES += ro.llndk.api_level=$(RELEASE_BOARD_API_LEVEL)
+endif
+
 # Sets ro.actionable_compatible_property.enabled to know on runtime whether the
 # allowed list of actionable compatible properties is enabled or not.
 ADDITIONAL_SYSTEM_PROPERTIES += ro.actionable_compatible_property.enabled=true
@@ -1271,6 +1277,11 @@
     $(if $(filter asan,$(tags_to_install)),$(call get-product-var,$(1),PRODUCT_PACKAGES_DEBUG_ASAN)) \
     $(if $(filter java_coverage,$(tags_to_install)),$(call get-product-var,$(1),PRODUCT_PACKAGES_DEBUG_JAVA_COVERAGE)) \
     $(if $(filter arm64,$(TARGET_ARCH) $(TARGET_2ND_ARCH)),$(call get-product-var,$(1),PRODUCT_PACKAGES_ARM64)) \
+    $(if $(PRODUCT_SHIPPING_API_LEVEL), \
+      $(if $(call math_gt_or_eq,29,$(PRODUCT_SHIPPING_API_LEVEL)),$(call get-product-var,$(1),PRODUCT_PACKAGES_SHIPPING_API_LEVEL_29)) \
+      $(if $(call math_gt_or_eq,33,$(PRODUCT_SHIPPING_API_LEVEL)),$(call get-product-var,$(1),PRODUCT_PACKAGES_SHIPPING_API_LEVEL_33)) \
+      $(if $(call math_gt_or_eq,34,$(PRODUCT_SHIPPING_API_LEVEL)),$(call get-product-var,$(1),PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34)) \
+    ) \
     $(call auto-included-modules) \
   ) \
   $(eval ### Filter out the overridden packages and executables before doing expansion) \
diff --git a/core/product.mk b/core/product.mk
index 3667bb1..be5ec47 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -443,6 +443,9 @@
 # If set, determines whether the build system checks vendor seapp contexts violations.
 _product_single_value_vars += PRODUCT_CHECK_VENDOR_SEAPP_VIOLATIONS
 
+# If set, determines whether the build system checks dev type violations.
+_product_single_value_vars += PRODUCT_CHECK_DEV_TYPE_VIOLATIONS
+
 _product_list_vars += PRODUCT_AFDO_PROFILES
 
 _product_single_value_vars += PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API
diff --git a/core/product_config.mk b/core/product_config.mk
index 3ee9654..500735e 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -500,18 +500,6 @@
   endif
 endif
 
-ifdef PRODUCT_SHIPPING_API_LEVEL
-  ifneq (,$(call math_gt_or_eq,29,$(PRODUCT_SHIPPING_API_LEVEL)))
-    PRODUCT_PACKAGES += $(PRODUCT_PACKAGES_SHIPPING_API_LEVEL_29)
-  endif
-  ifneq (,$(call math_gt_or_eq,33,$(PRODUCT_SHIPPING_API_LEVEL)))
-    PRODUCT_PACKAGES += $(PRODUCT_PACKAGES_SHIPPING_API_LEVEL_33)
-  endif
-  ifneq (,$(call math_gt_or_eq,34,$(PRODUCT_SHIPPING_API_LEVEL)))
-    PRODUCT_PACKAGES += $(PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34)
-  endif
-endif
-
 # If build command defines OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS,
 # override PRODUCT_EXTRA_VNDK_VERSIONS with it.
 ifdef OVERRIDE_PRODUCT_EXTRA_VNDK_VERSIONS
@@ -590,6 +578,15 @@
 endif
 .KATI_READONLY := CHECK_VENDOR_SEAPP_VIOLATIONS
 
+# Boolean variable determining if selinux labels of /dev are enforced
+CHECK_DEV_TYPE_VIOLATIONS := false
+ifneq ($(call math_gt,$(VSR_VENDOR_API_LEVEL),35),)
+  CHECK_DEV_TYPE_VIOLATIONS := true
+else ifneq ($(PRODUCT_CHECK_DEV_TYPE_VIOLATIONS),)
+  CHECK_DEV_TYPE_VIOLATIONS := $(PRODUCT_CHECK_DEV_TYPE_VIOLATIONS)
+endif
+.KATI_READONLY := CHECK_DEV_TYPE_VIOLATIONS
+
 define product-overrides-config
 $$(foreach rule,$$(PRODUCT_$(1)_OVERRIDES),\
     $$(if $$(filter 2,$$(words $$(subst :,$$(space),$$(rule)))),,\
diff --git a/core/release_config.mk b/core/release_config.mk
index 68dd876..1fb5747 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -63,11 +63,19 @@
 #
 # $1 config name
 # $2 release config files
+# $3 overridden release config.  Only applied for $(TARGET_RELEASE), not in depth.
 define declare-release-config
     $(if $(strip $(2)),,  \
         $(error declare-release-config: config $(strip $(1)) must have release config files) \
     )
     $(eval _all_release_configs := $(sort $(_all_release_configs) $(strip $(1))))
+    $(if $(strip $(3)), \
+      $(if $(filter $(_all_release_configs), $(strip $(3))),
+        $(if $(filter $(_all_release_configs.$(strip $(1)).OVERRIDES),$(strip $(3))),,
+          $(eval _all_release_configs.$(strip $(1)).OVERRIDES := $(_all_release_configs.$(strip $(1)).OVERRIDES) $(strip $(3)))), \
+        $(error No release config $(strip $(3))) \
+      ) \
+    )
     $(eval _all_release_configs.$(strip $(1)).DECLARED_IN := $(_included) $(_all_release_configs.$(strip $(1)).DECLARED_IN))
     $(eval _all_release_configs.$(strip $(1)).FILES := $(_all_release_configs.$(strip $(1)).FILES) $(strip $(2)))
 endef
@@ -105,8 +113,10 @@
 # Don't sort this, use it in the order they gave us.
 # Do allow duplicate entries, retaining only the first usage.
 flag_value_files :=
-$(foreach f,$(_all_release_configs.$(TARGET_RELEASE).FILES), \
-  $(if $(filter $(f),$(flag_value_files)),,$(eval flag_value_files += $(f)))\
+$(foreach r,$(_all_release_configs.$(TARGET_RELEASE).OVERRIDES) $(TARGET_RELEASE), \
+    $(foreach f,$(_all_release_configs.$(r).FILES), \
+      $(if $(filter $(f),$(flag_value_files)),,$(eval flag_value_files += $(f)))\
+    )\
 )
 
 # Unset variables so they can't use them
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 947f66f..30acbba 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -386,7 +386,6 @@
   $(call add_json_str, BoardFlashEraseBlockSize, $(BOARD_FLASH_ERASE_BLOCK_SIZE))
 
   $(call add_json_bool, BoardUsesRecoveryAsBoot, $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
-  $(call add_json_bool, BoardBuildGkiBootImageWithoutRamdisk, $(filter true,$(BOARD_BUILD_GKI_BOOT_IMAGE_WITHOUT_RAMDISK)))
   $(call add_json_bool, ProductUseDynamicPartitionSize, $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITION_SIZE)))
   $(call add_json_bool, CopyImagesForTargetFilesZip, $(filter true,$(COPY_IMAGES_FOR_TARGET_FILES_ZIP)))
 
diff --git a/envsetup.sh b/envsetup.sh
index 3d29ed7..cc808d2 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -836,15 +836,21 @@
     # Note this is the string "release", not the value of the variable.
     export TARGET_BUILD_TYPE=release
 
+    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || echo
+
+    set_stuff_for_environment
+    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig
+
+    if [ "${TARGET_BUILD_VARIANT}" = "userdebug" ] && [[  -z "${ANDROID_QUIET_BUILD}" ]]; then
+      echo
+      echo "Want FASTER LOCAL BUILDS? Use -eng instead of -userdebug (however for" \
+        "performance benchmarking continue to use userdebug)"
+    fi
     if [ $used_lunch_menu -eq 1 ]; then
       echo
       echo "Hint: next time you can simply run 'lunch $selection'"
     fi
 
-    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || echo
-
-    set_stuff_for_environment
-    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig
     destroy_build_var_cache
 
     if [[ -n "${CHECK_MU_CONFIG:-}" ]]; then
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 5331224..f31749b 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -310,20 +310,17 @@
     system_manifest.xml \
     system_compatibility_matrix.xml \
 
-HIDL_SUPPORT_SERVICES := \
-    hwservicemanager \
-    android.hidl.allocator@1.0-service \
-    android.hidl.memory@1.0-impl \
-
-# TODO(b/299166571) Remove this after the artifact path requirements checker picks up
-# this library correctly with the *SHIPPING_API_LEVEL_34 variable
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
-	$(TARGET_COPY_OUT_SYSTEM)/lib/hw/android.hidl.memory@1.0-impl.so \
-	$(TARGET_COPY_OUT_SYSTEM)/lib64/hw/android.hidl.memory@1.0-impl.so \
-
 # Base modules when shipping api level is less than or equal to 34
 PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
-    $(HIDL_SUPPORT_SERVICES) \
+    android.hidl.memory@1.0-impl \
+
+# hwservicemanager is now installed on system_ext, but apexes might be using
+# old libraries that are expecting it to be installed on system. This allows
+# those apexes to continue working. The symlink can be removed once we are sure
+# there are no devices using hwservicemanager (when Android V launching devices
+# are no longer supported for dessert upgrades).
+PRODUCT_PACKAGES += \
+    hwservicemanager_compat_symlink_module \
 
 PRODUCT_PACKAGES_ARM64 := libclang_rt.hwasan \
  libclang_rt.hwasan.bootstrap \
diff --git a/target/product/base_system_ext.mk b/target/product/base_system_ext.mk
index 852d7ca..d8c1863 100644
--- a/target/product/base_system_ext.mk
+++ b/target/product/base_system_ext.mk
@@ -22,3 +22,8 @@
     passwd_system_ext \
     selinux_policy_system_ext \
     system_ext_manifest.xml \
+
+# Base modules when shipping api level is less than or equal to 34
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
+    hwservicemanager \
+    android.hidl.allocator@1.0-service \
diff --git a/target/product/generic_system.mk b/target/product/generic_system.mk
index 6d40436..38efde4 100644
--- a/target/product/generic_system.mk
+++ b/target/product/generic_system.mk
@@ -128,10 +128,6 @@
 
 _base_mk_allowed_list :=
 
-# TODO(b/299166571) Remove this after the artifact path requirements checker picks up
-# hwservicemanager correctly.
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += $(TARGET_COPY_OUT_SYSTEM)/bin/hwservicemanager
-
 _my_allowed_list := $(_base_mk_allowed_list)
 
 # For mainline, system.img should be mounted at /, so we include ROOT here.
diff --git a/target/product/handheld_system_ext.mk b/target/product/handheld_system_ext.mk
index 187b627..1218f7a 100644
--- a/target/product/handheld_system_ext.mk
+++ b/target/product/handheld_system_ext.mk
@@ -29,3 +29,8 @@
     StorageManager \
     SystemUI \
     WallpaperCropper \
+
+# Base modules when shipping api level is less than or equal to 34
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
+    hwservicemanager \
+    android.hidl.allocator@1.0-service \
diff --git a/target/product/telephony_system_ext.mk b/target/product/telephony_system_ext.mk
index f81a607..f821381 100644
--- a/target/product/telephony_system_ext.mk
+++ b/target/product/telephony_system_ext.mk
@@ -21,3 +21,7 @@
 PRODUCT_PACKAGES += \
     CarrierConfig \
     EmergencyInfo \
+
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
+    hwservicemanager \
+    android.hidl.allocator@1.0-service \
diff --git a/tools/aconfig/protos/aconfig.proto b/tools/aconfig/protos/aconfig.proto
index d5e2868..9e193ec 100644
--- a/tools/aconfig/protos/aconfig.proto
+++ b/tools/aconfig/protos/aconfig.proto
@@ -40,6 +40,7 @@
   optional string description = 3;
   repeated string bug = 4;
   optional bool is_fixed_read_only = 5;
+  optional bool is_exported = 6;
 };
 
 message flag_declarations {
@@ -77,6 +78,8 @@
   optional flag_permission permission = 7;
   repeated tracepoint trace = 8;
   optional bool is_fixed_read_only = 9;
+  optional bool is_exported = 10;
+
 }
 
 message parsed_flags {
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index 42d900b..5aa373a 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -151,12 +151,9 @@
 #ifdef __cplusplus
 
 #include <memory>
-#include <vector>
 
 namespace com::android::aconfig::test {
 
-extern std::vector<int8_t> cache_;
-
 class flag_provider_interface {
 public:
     virtual ~flag_provider_interface() = default;
@@ -359,6 +356,7 @@
     const PROD_SOURCE_FILE_EXPECTED: &str = r#"
 #include "com_android_aconfig_test.h"
 #include <server_configurable_flags/get_flags.h>
+#include <vector>
 
 namespace com::android::aconfig::test {
 
@@ -407,10 +405,10 @@
                 return cache_[2];
             }
 
+    private:
+        std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1);
     };
 
-    std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1);
-
     std::unique_ptr<flag_provider_interface> provider_ =
         std::make_unique<flag_provider>();
 }
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index c8c7975..ff0df1f 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -98,6 +98,7 @@
             };
             parsed_flag.set_permission(flag_permission);
             parsed_flag.set_is_fixed_read_only(flag_declaration.is_fixed_read_only());
+            parsed_flag.set_is_exported(flag_declaration.is_exported());
             let mut tracepoint = ProtoTracepoint::new();
             tracepoint.set_source(input.source.clone());
             tracepoint.set_state(DEFAULT_FLAG_STATE);
diff --git a/tools/aconfig/src/protos.rs b/tools/aconfig/src/protos.rs
index d3b5b37..a5a5342 100644
--- a/tools/aconfig/src/protos.rs
+++ b/tools/aconfig/src/protos.rs
@@ -308,6 +308,7 @@
     namespace: "first_ns"
     description: "This is the description of the first flag."
     bug: "123"
+    is_exported: true
 }
 flag {
     name: "second"
@@ -326,12 +327,14 @@
         assert_eq!(first.description(), "This is the description of the first flag.");
         assert_eq!(first.bug, vec!["123"]);
         assert!(!first.is_fixed_read_only());
+        assert!(first.is_exported());
         let second = flag_declarations.flag.iter().find(|pf| pf.name() == "second").unwrap();
         assert_eq!(second.name(), "second");
         assert_eq!(second.namespace(), "second_ns");
         assert_eq!(second.description(), "This is the description of the second flag.");
         assert_eq!(second.bug, vec!["abc"]);
         assert!(second.is_fixed_read_only());
+        assert!(!second.is_exported());
 
         // bad input: missing package in flag declarations
         let error = flag_declarations::try_from_text_proto(
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index bb3d1f0..31c67b3 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -42,6 +42,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -57,6 +58,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: true
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -77,6 +79,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -97,6 +100,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: true
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -122,6 +126,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -142,6 +147,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 "#;
 
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index d19c0fa..cc1b18d 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -18,16 +18,9 @@
 #ifdef __cplusplus
 
 #include <memory>
-{{ if not for_test- }}
-#include <vector>
-{{ -endif }}
 
 namespace {cpp_namespace} \{
 
-{{ if not for_test- }}
-extern std::vector<int8_t> cache_;
-{{ -endif }}
-
 class flag_provider_interface \{
 public:
     virtual ~flag_provider_interface() = default;
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index 91e828a..1bfa4b6 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -5,6 +5,8 @@
 {{ if for_test }}
 #include <unordered_map>
 #include <string>
+{{ -else- }}
+#include <vector>
 {{ endif }}
 
 namespace {cpp_namespace} \{
@@ -69,16 +71,15 @@
             {{ -endif }}
         }
         {{ endfor }}
+    private:
+        std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1);
     };
 
-    std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1);
 
 {{ -endif }}
 
 std::unique_ptr<flag_provider_interface> provider_ =
     std::make_unique<flag_provider>();
-
-
 }
 
 
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index 8527e93..b49b665 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -39,6 +39,7 @@
     namespace: "aconfig_test"
     description: "This flag is DISABLED + READ_WRITE"
     bug: "456"
+    is_exported: true
 }
 
 # This flag's final value calculated from:
diff --git a/tools/metadata/generator.go b/tools/metadata/generator.go
index bb8293a..e970e17 100644
--- a/tools/metadata/generator.go
+++ b/tools/metadata/generator.go
@@ -153,7 +153,7 @@
 	}
 
 	inputFileData := strings.TrimRight(readFileToString(*inputFile), "\n")
-	filePaths := strings.Split(inputFileData, "\n")
+	filePaths := strings.Split(inputFileData, " ")
 	if len(filePaths) == 1 && filePaths[0] == "" {
 		writeNewlineToOutputFile(*outputFile)
 		return
diff --git a/tools/metadata/testdata/inputFiles.txt b/tools/metadata/testdata/inputFiles.txt
index 61e6a8d..e44bc94 100644
--- a/tools/metadata/testdata/inputFiles.txt
+++ b/tools/metadata/testdata/inputFiles.txt
@@ -1,2 +1 @@
-file1.txt
-file2.txt
\ No newline at end of file
+file1.txt file2.txt
\ No newline at end of file
diff --git a/tools/metadata/testdata/inputFilesNegativeCase.txt b/tools/metadata/testdata/inputFilesNegativeCase.txt
index 17a9480..a37aa3f 100644
--- a/tools/metadata/testdata/inputFilesNegativeCase.txt
+++ b/tools/metadata/testdata/inputFilesNegativeCase.txt
@@ -1,2 +1 @@
-file3.txt
-file4.txt
\ No newline at end of file
+file3.txt file4.txt
\ No newline at end of file
diff --git a/tools/releasetools/merge/merge_target_files.py b/tools/releasetools/merge/merge_target_files.py
index 6bf1b49..4619246 100755
--- a/tools/releasetools/merge/merge_target_files.py
+++ b/tools/releasetools/merge/merge_target_files.py
@@ -46,6 +46,10 @@
       The optional path to a newline-separated config file of items that
       are extracted as-is from the vendor target files package.
 
+  --boot-image-dir-path
+      The input boot image directory path. This path contains IMAGES/boot.img
+      file.
+
   --output-target-files output-target-files-package
       If provided, the output merged target files package. Also a zip archive.
 
@@ -136,6 +140,7 @@
 OPTIONS.framework_misc_info_keys = []
 OPTIONS.vendor_target_files = None
 OPTIONS.vendor_item_list = []
+OPTIONS.boot_image_dir_path = None
 OPTIONS.output_target_files = None
 OPTIONS.output_dir = None
 OPTIONS.output_item_list = []
@@ -210,6 +215,12 @@
       output_dir=output_target_files_temp_dir,
       item_list=OPTIONS.vendor_item_list)
 
+  if OPTIONS.boot_image_dir_path:
+    merge_utils.CollectTargetFiles(
+        input_zipfile_or_dir=OPTIONS.boot_image_dir_path,
+        output_dir=output_target_files_temp_dir,
+        item_list=['IMAGES/boot.img'])
+
   # Perform special case processing on META/* items.
   # After this function completes successfully, all the files we need to create
   # the output target files package are in place.
@@ -539,6 +550,8 @@
       OPTIONS.vendor_item_list = a
     elif o == '--vendor-item-list':
       OPTIONS.vendor_item_list = a
+    elif o == '--boot-image-dir-path':
+      OPTIONS.boot_image_dir_path = a
     elif o == '--output-target-files':
       OPTIONS.output_target_files = a
     elif o == '--output-dir':
@@ -587,6 +600,7 @@
           'vendor-target-files=',
           'other-item-list=',
           'vendor-item-list=',
+          'boot-image-dir-path=',
           'output-target-files=',
           'output-dir=',
           'output-item-list=',