Merge "aconfig: move `cache_` as a memeber" into main
diff --git a/core/artifact_path_requirements.mk b/core/artifact_path_requirements.mk
index 566b9f7..c949cc4 100644
--- a/core/artifact_path_requirements.mk
+++ b/core/artifact_path_requirements.mk
@@ -4,6 +4,7 @@
 # Fakes don't get installed, and NDK stubs aren't installed to device.
 static_allowed_patterns := $(TARGET_OUT_FAKE)/% $(SOONG_OUT_DIR)/ndk/%
 # RROs become REQUIRED by the source module, but are always placed on the vendor partition.
+static_allowed_patterns += %__auto_generated_characteristics_rro.apk
 static_allowed_patterns += %__auto_generated_rro_product.apk
 static_allowed_patterns += %__auto_generated_rro_vendor.apk
 # Auto-included targets are not considered
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f96504a..8236dc9 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -1156,11 +1156,9 @@
 
 ##########################################################
 # Track module-level dependencies.
-# Use $(LOCAL_MODULE) instead of $(my_register_name) to ignore module's bitness.
 # (b/204397180) Unlock RECORD_ALL_DEPS was acknowledged reasonable for better Atest performance.
-ALL_DEPS.MODULES += $(LOCAL_MODULE)
-ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \
-  $(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) \
+ALL_MODULES.$(my_register_name).ALL_DEPS := \
+  $(ALL_MODULES.$(my_register_name).ALL_DEPS) \
   $(LOCAL_STATIC_LIBRARIES) \
   $(LOCAL_WHOLE_STATIC_LIBRARIES) \
   $(LOCAL_SHARED_LIBRARIES) \
@@ -1170,7 +1168,7 @@
   $(LOCAL_HEADER_LIBRARIES) \
   $(LOCAL_STATIC_JAVA_LIBRARIES) \
   $(LOCAL_JAVA_LIBRARIES) \
-  $(LOCAL_JNI_SHARED_LIBRARIES))
+  $(LOCAL_JNI_SHARED_LIBRARIES)
 
 ###########################################################
 ## umbrella targets used to verify builds
diff --git a/core/definitions.mk b/core/definitions.mk
index 44643d9..7a6c064 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -106,9 +106,6 @@
 # All modules already converted to Soong
 SOONG_ALREADY_CONV :=
 
-# ALL_DEPS.*.ALL_DEPS keys
-ALL_DEPS.MODULES :=
-
 ###########################################################
 ## Debugging; prints a variable list to stdout
 ###########################################################
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 6791125..37a389f 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -58,6 +58,7 @@
 # We can do this only if preopt is enabled and if the product uses libart config (which sets the
 # default properties for preopting).
 ifeq ($(WITH_DEXPREOPT), true)
+ifneq ($(WITH_DEXPREOPT_ART_BOOT_IMG_ONLY), true)
 ifeq ($(PRODUCT_USES_DEFAULT_ART_CONFIG), true)
 
 boot_zip := $(PRODUCT_OUT)/boot.zip
@@ -152,4 +153,5 @@
 
 endif  #ART_MODULE_BUILD_FROM_SOURCE || MODULE_BUILD_FROM_SOURCE
 endif  #PRODUCT_USES_DEFAULT_ART_CONFIG
+endif  #WITH_DEXPREOPT_ART_BOOT_IMG_ONLY
 endif  #WITH_DEXPREOPT
diff --git a/core/java_common.mk b/core/java_common.mk
index ec04718..c1ccd1a 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -386,7 +386,7 @@
 endif # !LOCAL_IS_HOST_MODULE
 
 # (b/204397180) Record ALL_DEPS by default.
-ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) $(full_java_bootclasspath_libs)
+ALL_MODULES.$(my_register_name).ALL_DEPS := $(ALL_MODULES.$(my_register_name).ALL_DEPS) $(full_java_bootclasspath_libs)
 
 # Export the SDK libs. The sdk library names listed in LOCAL_SDK_LIBRARIES are first exported.
 # Then sdk library names exported from dependencies are all re-exported.
diff --git a/core/main.mk b/core/main.mk
index 367b5bf..1fccc60 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1271,6 +1271,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 0d5a07d..3667bb1 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -451,6 +451,8 @@
 
 _product_list_vars += PRODUCT_VALIDATION_CHECKS
 
+_product_single_value_vars += PRODUCT_BUILD_FROM_SOURCE_STUB
+
 .KATI_READONLY := _product_single_value_vars _product_list_vars
 _product_var_list :=$= $(_product_single_value_vars) $(_product_list_vars)
 
diff --git a/core/product_config.mk b/core/product_config.mk
index 3ee9654..7c55d00 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
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 08e9a65..947f66f 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -397,6 +397,8 @@
 
 $(call add_json_bool, NextReleaseHideFlaggedApi, $(filter true,$(PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API)))
 
+$(call add_json_bool, BuildFromSourceStub, $(findstring true,$(PRODUCT_BUILD_FROM_SOURCE_STUB) $(BUILD_FROM_SOURCE_STUB)))
+
 $(call json_end)
 
 $(file >$(SOONG_VARIABLES).tmp,$(json_contents))
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 9668b53..8e2d58e 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -18,7 +18,7 @@
 			'"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)],' \
 			'"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)"$(COMMA)' \
 			'"test_config": [$(KATI_foreach_sep w,$(COMMA) ,$(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)),"$(w)")],' \
-			'"dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)")],' \
+			'"dependencies": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).ALL_DEPS)),"$(w)")],' \
 			'"shared_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SHARED_LIBS)),"$(w)")],' \
 			'"static_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).STATIC_LIBS)),"$(w)")],' \
 			'"system_shared_libs": [$(KATI_foreach_sep w,$(COMMA) ,$(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)),"$(w)")],' \
diff --git a/envsetup.sh b/envsetup.sh
index c20837b..3d29ed7 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1880,10 +1880,6 @@
       >&2 echo "Couldn't locate the top of the tree. Try setting TOP."
       return 1
     fi
-
-    if [[ -z "${ANDROID_QUIET_BUILD:-}" && -n "${ANDROID_BUILD_BANNER}" ]]; then
-      echo "$ANDROID_BUILD_BANNER"
-    fi
 )
 
 function m()
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 69a2abf..f31749b 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -21,7 +21,6 @@
     am \
     android.hidl.base-V1.0-java \
     android.hidl.manager-V1.0-java \
-    android.hidl.memory@1.0-impl \
     android.system.suspend-service \
     android.test.base \
     android.test.mock \
@@ -311,13 +310,17 @@
     system_manifest.xml \
     system_compatibility_matrix.xml \
 
-HIDL_SUPPORT_SERVICES := \
-    hwservicemanager \
-    android.hidl.allocator@1.0-service \
-
 # 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/base_vendor.mk b/target/product/base_vendor.mk
index 8d5b7bf..a0c5929 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -46,7 +46,6 @@
 
 # Base modules and settings for the vendor partition.
 PRODUCT_PACKAGES += \
-    android.hidl.memory@1.0-impl.vendor \
     com.android.hardware.cas \
     boringssl_self_test_vendor \
     dumpsys_vendor \
@@ -75,6 +74,10 @@
     selinux_policy_nonsystem \
     shell_and_utilities_vendor \
 
+# Base modules when shipping api level is less than or equal to 34
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
+     android.hidl.memory@1.0-impl.vendor \
+
 # OMX not supported for 64bit_only builds
 # Only supported when SHIPPING_API_LEVEL is less than or equal to 33
 ifneq ($(TARGET_SUPPORTS_OMX_SERVICE),false)
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index bc11fea..b02a583 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -73,6 +73,7 @@
     com.android.ipsec:android.net.ipsec.ike \
     com.android.media:updatable-media \
     com.android.mediaprovider:framework-mediaprovider \
+    com.android.mediaprovider:framework-pdf \
     com.android.ondevicepersonalization:framework-ondevicepersonalization \
     com.android.os.statsd:framework-statsd \
     com.android.permission:framework-permission \
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/gsi/current.txt b/target/product/gsi/current.txt
index 9ff886e..53c9e0c 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -34,7 +34,6 @@
 VNDK-SP: android.hardware.graphics.mapper@4.0.so
 VNDK-SP: android.hardware.renderscript@1.0.so
 VNDK-SP: android.hidl.memory.token@1.0.so
-VNDK-SP: android.hidl.memory@1.0-impl.so
 VNDK-SP: android.hidl.memory@1.0.so
 VNDK-SP: android.hidl.safe_union@1.0.so
 VNDK-SP: libRSCpuRef.so
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/mainline_sdk.mk b/target/product/mainline_sdk.mk
index 0ea72cc..cb23bc8 100644
--- a/target/product/mainline_sdk.mk
+++ b/target/product/mainline_sdk.mk
@@ -18,3 +18,5 @@
 PRODUCT_DEVICE := mainline_sdk
 
 PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API := true
+
+PRODUCT_BUILD_FROM_SOURCE_STUB := true
\ No newline at end of file
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index fff8d4c..b9ccad3 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -30,3 +30,5 @@
 PRODUCT_DEVICE := mainline_x86
 
 PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API := true
+
+PRODUCT_BUILD_FROM_SOURCE_STUB := true
\ No newline at end of file
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/Android.bp b/tools/Android.bp
index b8ab162..5c54fcf 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -96,3 +96,13 @@
         unit_test: true,
     },
 }
+
+python_binary_host {
+  name: "characteristics_rro_generator",
+  srcs: ["characteristics_rro_generator.py"],
+  version: {
+    py3: {
+      embedded_launcher: true,
+    },
+  },
+}
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index 4ad3f4e..5aa373a 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -162,7 +162,7 @@
 
     virtual bool disabled_rw() = 0;
 
-    virtual bool disabled_rw_2() = 0;
+    virtual bool disabled_rw_in_other_namespace() = 0;
 
     virtual bool enabled_fixed_ro() = 0;
 
@@ -181,8 +181,8 @@
     return provider_->disabled_rw();
 }
 
-inline bool disabled_rw_2() {
-    return provider_->disabled_rw_2();
+inline bool disabled_rw_in_other_namespace() {
+    return provider_->disabled_rw_in_other_namespace();
 }
 
 inline bool enabled_fixed_ro() {
@@ -206,7 +206,7 @@
 
 bool com_android_aconfig_test_disabled_rw();
 
-bool com_android_aconfig_test_disabled_rw_2();
+bool com_android_aconfig_test_disabled_rw_in_other_namespace();
 
 bool com_android_aconfig_test_enabled_fixed_ro();
 
@@ -241,9 +241,9 @@
 
     virtual void disabled_rw(bool val) = 0;
 
-    virtual bool disabled_rw_2() = 0;
+    virtual bool disabled_rw_in_other_namespace() = 0;
 
-    virtual void disabled_rw_2(bool val) = 0;
+    virtual void disabled_rw_in_other_namespace(bool val) = 0;
 
     virtual bool enabled_fixed_ro() = 0;
 
@@ -278,12 +278,12 @@
     provider_->disabled_rw(val);
 }
 
-inline bool disabled_rw_2() {
-    return provider_->disabled_rw_2();
+inline bool disabled_rw_in_other_namespace() {
+    return provider_->disabled_rw_in_other_namespace();
 }
 
-inline void disabled_rw_2(bool val) {
-    provider_->disabled_rw_2(val);
+inline void disabled_rw_in_other_namespace(bool val) {
+    provider_->disabled_rw_in_other_namespace(val);
 }
 
 inline bool enabled_fixed_ro() {
@@ -327,9 +327,9 @@
 
 void set_com_android_aconfig_test_disabled_rw(bool val);
 
-bool com_android_aconfig_test_disabled_rw_2();
+bool com_android_aconfig_test_disabled_rw_in_other_namespace();
 
-void set_com_android_aconfig_test_disabled_rw_2(bool val);
+void set_com_android_aconfig_test_disabled_rw_in_other_namespace(bool val);
 
 bool com_android_aconfig_test_enabled_fixed_ro();
 
@@ -377,11 +377,11 @@
                 return cache_[0];
             }
 
-            virtual bool disabled_rw_2() override {
+            virtual bool disabled_rw_in_other_namespace() override {
                 if (cache_[1] == -1) {
                     cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
                         "aconfig_flags.other_namespace",
-                        "com.android.aconfig.test.disabled_rw_2",
+                        "com.android.aconfig.test.disabled_rw_in_other_namespace",
                         "false") == "true";
                 }
                 return cache_[1];
@@ -421,8 +421,8 @@
     return com::android::aconfig::test::disabled_rw();
 }
 
-bool com_android_aconfig_test_disabled_rw_2() {
-    return com::android::aconfig::test::disabled_rw_2();
+bool com_android_aconfig_test_disabled_rw_in_other_namespace() {
+    return com::android::aconfig::test::disabled_rw_in_other_namespace();
 }
 
 bool com_android_aconfig_test_enabled_fixed_ro() {
@@ -485,20 +485,20 @@
                 overrides_["disabled_rw"] = val;
             }
 
-            virtual bool disabled_rw_2() override {
-                auto it = overrides_.find("disabled_rw_2");
+            virtual bool disabled_rw_in_other_namespace() override {
+                auto it = overrides_.find("disabled_rw_in_other_namespace");
                   if (it != overrides_.end()) {
                       return it->second;
                 } else {
                   return server_configurable_flags::GetServerConfigurableFlag(
                       "aconfig_flags.other_namespace",
-                      "com.android.aconfig.test.disabled_rw_2",
+                      "com.android.aconfig.test.disabled_rw_in_other_namespace",
                       "false") == "true";
                 }
             }
 
-            virtual void disabled_rw_2(bool val) override {
-                overrides_["disabled_rw_2"] = val;
+            virtual void disabled_rw_in_other_namespace(bool val) override {
+                overrides_["disabled_rw_in_other_namespace"] = val;
             }
 
             virtual bool enabled_fixed_ro() override {
@@ -570,13 +570,13 @@
     com::android::aconfig::test::disabled_rw(val);
 }
 
-bool com_android_aconfig_test_disabled_rw_2() {
-    return com::android::aconfig::test::disabled_rw_2();
+bool com_android_aconfig_test_disabled_rw_in_other_namespace() {
+    return com::android::aconfig::test::disabled_rw_in_other_namespace();
 }
 
 
-void set_com_android_aconfig_test_disabled_rw_2(bool val) {
-    com::android::aconfig::test::disabled_rw_2(val);
+void set_com_android_aconfig_test_disabled_rw_in_other_namespace(bool val) {
+    com::android::aconfig::test::disabled_rw_in_other_namespace(val);
 }
 
 
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index 5470cb3..a822cd5 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -179,7 +179,7 @@
         @UnsupportedAppUsage
         boolean disabledRw();
         @UnsupportedAppUsage
-        boolean disabledRw2();
+        boolean disabledRwInOtherNamespace();
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledFixedRo();
@@ -202,7 +202,7 @@
         /** @hide */
         public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
         /** @hide */
-        public static final String FLAG_DISABLED_RW_2 = "com.android.aconfig.test.disabled_rw_2";
+        public static final String FLAG_DISABLED_RW_IN_OTHER_NAMESPACE = "com.android.aconfig.test.disabled_rw_in_other_namespace";
         /** @hide */
         public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
         /** @hide */
@@ -220,8 +220,8 @@
             return FEATURE_FLAGS.disabledRw();
         }
         @UnsupportedAppUsage
-        public static boolean disabledRw2() {
-            return FEATURE_FLAGS.disabledRw2();
+        public static boolean disabledRwInOtherNamespace() {
+            return FEATURE_FLAGS.disabledRwInOtherNamespace();
         }
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
@@ -262,8 +262,8 @@
         }
         @Override
         @UnsupportedAppUsage
-        public boolean disabledRw2() {
-            return getValue(Flags.FLAG_DISABLED_RW_2);
+        public boolean disabledRwInOtherNamespace() {
+            return getValue(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE);
         }
         @Override
         @UnsupportedAppUsage
@@ -302,7 +302,7 @@
             Map.ofEntries(
                 Map.entry(Flags.FLAG_DISABLED_RO, false),
                 Map.entry(Flags.FLAG_DISABLED_RW, false),
-                Map.entry(Flags.FLAG_DISABLED_RW_2, false),
+                Map.entry(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false),
                 Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
                 Map.entry(Flags.FLAG_ENABLED_RO, false),
                 Map.entry(Flags.FLAG_ENABLED_RW, false)
@@ -336,7 +336,7 @@
             private static boolean aconfig_test_is_cached = false;
             private static boolean other_namespace_is_cached = false;
             private static boolean disabledRw = false;
-            private static boolean disabledRw2 = false;
+            private static boolean disabledRwInOtherNamespace = false;
             private static boolean enabledRw = true;
 
 
@@ -363,8 +363,8 @@
             private void load_overrides_other_namespace() {
                 try {
                     Properties properties = DeviceConfig.getProperties("other_namespace");
-                    disabledRw2 =
-                        properties.getBoolean("com.android.aconfig.test.disabled_rw_2", false);
+                    disabledRwInOtherNamespace =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw_in_other_namespace", false);
                 } catch (NullPointerException e) {
                     throw new RuntimeException(
                         "Cannot read value from namespace other_namespace "
@@ -394,11 +394,11 @@
             }
             @Override
             @UnsupportedAppUsage
-            public boolean disabledRw2() {
+            public boolean disabledRwInOtherNamespace() {
                 if (!other_namespace_is_cached) {
                     load_overrides_other_namespace();
                 }
-                return disabledRw2;
+                return disabledRwInOtherNamespace;
             }
             @Override
             @UnsupportedAppUsage
@@ -489,7 +489,7 @@
             }
             @Override
             @UnsupportedAppUsage
-            public boolean disabledRw2() {
+            public boolean disabledRwInOtherNamespace() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
diff --git a/tools/aconfig/src/codegen_rust.rs b/tools/aconfig/src/codegen_rust.rs
index fb4f981..d8675e7 100644
--- a/tools/aconfig/src/codegen_rust.rs
+++ b/tools/aconfig/src/codegen_rust.rs
@@ -104,10 +104,10 @@
         "com.android.aconfig.test.disabled_rw",
         "false") == "true";
 
-    /// flag value cache for disabled_rw_2
-    static ref CACHED_disabled_rw_2: bool = flags_rust::GetServerConfigurableFlag(
+    /// flag value cache for disabled_rw_in_other_namespace
+    static ref CACHED_disabled_rw_in_other_namespace: bool = flags_rust::GetServerConfigurableFlag(
         "aconfig_flags.other_namespace",
-        "com.android.aconfig.test.disabled_rw_2",
+        "com.android.aconfig.test.disabled_rw_in_other_namespace",
         "false") == "true";
 
     /// flag value cache for enabled_rw
@@ -128,9 +128,9 @@
         *CACHED_disabled_rw
     }
 
-    /// query flag disabled_rw_2
-    pub fn disabled_rw_2(&self) -> bool {
-        *CACHED_disabled_rw_2
+    /// query flag disabled_rw_in_other_namespace
+    pub fn disabled_rw_in_other_namespace(&self) -> bool {
+        *CACHED_disabled_rw_in_other_namespace
     }
 
     /// query flag enabled_fixed_ro
@@ -164,10 +164,10 @@
     PROVIDER.disabled_rw()
 }
 
-/// query flag disabled_rw_2
+/// query flag disabled_rw_in_other_namespace
 #[inline(always)]
-pub fn disabled_rw_2() -> bool {
-    PROVIDER.disabled_rw_2()
+pub fn disabled_rw_in_other_namespace() -> bool {
+    PROVIDER.disabled_rw_in_other_namespace()
 }
 
 /// query flag enabled_fixed_ro
@@ -228,19 +228,19 @@
         self.overrides.insert("disabled_rw", val);
     }
 
-    /// query flag disabled_rw_2
-    pub fn disabled_rw_2(&self) -> bool {
-        self.overrides.get("disabled_rw_2").copied().unwrap_or(
+    /// query flag disabled_rw_in_other_namespace
+    pub fn disabled_rw_in_other_namespace(&self) -> bool {
+        self.overrides.get("disabled_rw_in_other_namespace").copied().unwrap_or(
             flags_rust::GetServerConfigurableFlag(
                 "aconfig_flags.other_namespace",
-                "com.android.aconfig.test.disabled_rw_2",
+                "com.android.aconfig.test.disabled_rw_in_other_namespace",
                 "false") == "true"
         )
     }
 
-    /// set flag disabled_rw_2
-    pub fn set_disabled_rw_2(&mut self, val: bool) {
-        self.overrides.insert("disabled_rw_2", val);
+    /// set flag disabled_rw_in_other_namespace
+    pub fn set_disabled_rw_in_other_namespace(&mut self, val: bool) {
+        self.overrides.insert("disabled_rw_in_other_namespace", val);
     }
 
     /// query flag enabled_fixed_ro
@@ -317,16 +317,16 @@
     PROVIDER.lock().unwrap().set_disabled_rw(val);
 }
 
-/// query flag disabled_rw_2
+/// query flag disabled_rw_in_other_namespace
 #[inline(always)]
-pub fn disabled_rw_2() -> bool {
-    PROVIDER.lock().unwrap().disabled_rw_2()
+pub fn disabled_rw_in_other_namespace() -> bool {
+    PROVIDER.lock().unwrap().disabled_rw_in_other_namespace()
 }
 
-/// set flag disabled_rw_2
+/// set flag disabled_rw_in_other_namespace
 #[inline(always)]
-pub fn set_disabled_rw_2(val: bool) {
-    PROVIDER.lock().unwrap().set_disabled_rw_2(val);
+pub fn set_disabled_rw_in_other_namespace(val: bool) {
+    PROVIDER.lock().unwrap().set_disabled_rw_in_other_namespace(val);
 }
 
 /// query flag enabled_fixed_ro
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 63aef29..c8c7975 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -433,7 +433,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_defaults(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_2=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
+        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_in_other_namespace=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
     }
 
     #[test]
@@ -441,7 +441,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_sysprops(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_2=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
+        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_in_other_namespace=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
     }
 
     #[test]
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index 922d4c6..bb3d1f0 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -60,9 +60,9 @@
 }
 parsed_flag {
   package: "com.android.aconfig.test"
-  name: "disabled_rw_2"
+  name: "disabled_rw_in_other_namespace"
   namespace: "other_namespace"
-  description: "This flag is DISABLED + READ_WRITE"
+  description: "This flag is DISABLED + READ_WRITE, and is defined in another namespace"
   bug: "999"
   state: DISABLED
   permission: READ_WRITE
diff --git a/tools/aconfig/tests/first.values b/tools/aconfig/tests/first.values
index 448fb3a..07d8d1d 100644
--- a/tools/aconfig/tests/first.values
+++ b/tools/aconfig/tests/first.values
@@ -18,7 +18,7 @@
 }
 flag_value {
     package: "com.android.aconfig.test"
-    name: "disabled_rw_2"
+    name: "disabled_rw_in_other_namespace"
     state: DISABLED
     permission: READ_WRITE
 }
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index 3076f5e..8527e93 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -53,8 +53,8 @@
 }
 
 flag {
-    name: "disabled_rw_2"
+    name: "disabled_rw_in_other_namespace"
     namespace: "other_namespace"
-    description: "This flag is DISABLED + READ_WRITE"
+    description: "This flag is DISABLED + READ_WRITE, and is defined in another namespace"
     bug: "999"
 }
diff --git a/tools/characteristics_rro_generator.py b/tools/characteristics_rro_generator.py
new file mode 100644
index 0000000..6489673
--- /dev/null
+++ b/tools/characteristics_rro_generator.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+import sys
+from xml.dom.minidom import parseString
+
+def parse_package(manifest):
+    with open(manifest, 'r') as f:
+        data = f.read()
+    dom = parseString(data)
+    return dom.documentElement.getAttribute('package')
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        sys.exit(f"usage: {sys_argv[0]} target_package_manifest output\n")
+    package_name = parse_package(sys.argv[1])
+    with open(sys.argv[2], "w") as f:
+        f.write(f'''<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="{package_name}.auto_generated_characteristics_rro">
+    <application android:hasCode="false" />
+    <overlay android:targetPackage="{package_name}"
+             android:isStatic="true"
+             android:priority="0" />
+</manifest>
+''')
diff --git a/tools/metadata/generator.go b/tools/metadata/generator.go
index eb87755..e970e17 100644
--- a/tools/metadata/generator.go
+++ b/tools/metadata/generator.go
@@ -73,6 +73,20 @@
 	return string(data)
 }
 
+func writeNewlineToOutputFile(outputFile string) {
+	file, err := os.Create(outputFile)
+	data := "\n"
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer file.Close()
+
+	_, err = file.Write([]byte(data))
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
 func processTestSpecProtobuf(
 	filePath string, ownershipMetadataMap *sync.Map, keyLocks *keyToLocksMap,
 	errCh chan error, wg *sync.WaitGroup,
@@ -139,7 +153,11 @@
 	}
 
 	inputFileData := strings.TrimRight(readFileToString(*inputFile), "\n")
-	filePaths := strings.Split(inputFileData, "\n")
+	filePaths := strings.Split(inputFileData, " ")
+	if len(filePaths) == 1 && filePaths[0] == "" {
+		writeNewlineToOutputFile(*outputFile)
+		return
+	}
 	ownershipMetadataMap := &sync.Map{}
 	keyLocks := &keyToLocksMap{}
 	errCh := make(chan error, len(filePaths))
diff --git a/tools/metadata/testdata/emptyInputFile.txt b/tools/metadata/testdata/emptyInputFile.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tools/metadata/testdata/emptyInputFile.txt
@@ -0,0 +1 @@
+
diff --git a/tools/metadata/testdata/generatedEmptyOutputFile.txt b/tools/metadata/testdata/generatedEmptyOutputFile.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tools/metadata/testdata/generatedEmptyOutputFile.txt
@@ -0,0 +1 @@
+
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/metadata/testdata/metadata_test.go b/tools/metadata/testdata/metadata_test.go
index 03c4f29..71856fe 100644
--- a/tools/metadata/testdata/metadata_test.go
+++ b/tools/metadata/testdata/metadata_test.go
@@ -63,3 +63,27 @@
 		)
 	}
 }
+
+func TestEmptyInputFile(t *testing.T) {
+	cmd := exec.Command(
+		"metadata", "-rule", "test_spec", "-inputFile", "./emptyInputFile.txt", "-outputFile",
+		"./generatedEmptyOutputFile.txt",
+	)
+	stderr, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Error running metadata command: %s. Error: %v", stderr, err)
+	}
+
+	// Read the contents of the generated output file
+	generatedOutput, err := ioutil.ReadFile("./generatedEmptyOutputFile.txt")
+	if err != nil {
+		t.Fatalf("Error reading generated output file: %s", err)
+	}
+
+	fmt.Println()
+
+	// Compare the contents
+	if string(generatedOutput) != "\n" {
+		t.Errorf("Generated file contents do not match the expected output")
+	}
+}
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=',