Merge "Create APEX ABI dumps with next release configuration" into main
diff --git a/core/Makefile b/core/Makefile
index 4900ac2..02deadd 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -3423,13 +3423,12 @@
 #   $(2): The partition's staging directory
 #   $(3): Files to include in the partition
 define write-partition-file-list
-$(1): PRIVATE_RELEVANT_EXTRA_INSTALL_ZIPS := $(call relevant-extra-install-zips,$(filter $(2)/%,$(3)))
-$(1): $$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $$(foreach p,$$(PRIVATE_RELEVANT_EXTRA_INSTALL_ZIPS),$$(call word-colon,3,$$(p)))
+$(1): $$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(foreach p,$(call relevant-extra-install-zips,$(filter $(2)/%,$(3))),$(call word-colon,3,$(p)))
 	@echo Writing $$@
 	rm -f $$@
 	echo -n > $$@
 	$$(foreach f,$(subst $(2)/,,$(filter $(2)/%,$(3))),echo "$$(f)" >> $$@$$(newline))
-	$$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(2) $$(PRIVATE_RELEVANT_EXTRA_INSTALL_ZIPS) >> $$@
+	$$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(2) $(call relevant-extra-install-zips,$(filter $(2)/%,$(3))) >> $$@
 endef
 
 # -----------------------------------------------------------------
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index fb4ae76..e83a166 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -85,6 +85,7 @@
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_dice_changes,$(RELEASE_AVF_ENABLE_DICE_CHANGES))
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_llpvm_changes,$(RELEASE_AVF_ENABLE_LLPVM_CHANGES))
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_multi_tenant_microdroid_vm,$(RELEASE_AVF_ENABLE_MULTI_TENANT_MICRODROID_VM))
+$(call add_soong_config_var_value,ANDROID,release_avf_enable_network,$(RELEASE_AVF_ENABLE_NETWORK))
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_remote_attestation,$(RELEASE_AVF_ENABLE_REMOTE_ATTESTATION))
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_vendor_modules,$(RELEASE_AVF_ENABLE_VENDOR_MODULES))
 $(call add_soong_config_var_value,ANDROID,release_avf_enable_virt_cpufreq,$(RELEASE_AVF_ENABLE_VIRT_CPUFREQ))
diff --git a/core/art_config.mk b/core/art_config.mk
index 196db4f..9e87a7b 100644
--- a/core/art_config.mk
+++ b/core/art_config.mk
@@ -22,17 +22,16 @@
 
 # Create APEX_BOOT_JARS_EXCLUDED which is a list of jars to be removed from
 # ApexBoorJars when built from mainline prebuilts.
-# soong variables indicate whether the prebuilt is enabled:
-# - $(m)_module/source_build for art and TOGGLEABLE_PREBUILT_MODULES
-# - ANDROID/module_build_from_source for other mainline modules
 # Note that RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST is the list of module names
 # and library names of jars that need to be removed. We have to keep separated list per
 # release config due to possibility of different prebuilt content.
-APEX_BOOT_JARS_EXCLUDED :=
-$(foreach pair, $(RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST),\
-  $(eval m := $(subst com.android.,,$(call word-colon,1,$(pair)))) \
-  $(if $(call soong_config_get,$(m)_module,source_build), \
-    $(if $(filter true,$(call soong_config_get,$(m)_module,source_build)),, \
-      $(eval APEX_BOOT_JARS_EXCLUDED += $(pair))), \
-    $(if $(filter true,$(call soong_config_get,ANDROID,module_build_from_source)),, \
-      $(eval APEX_BOOT_JARS_EXCLUDED += $(pair)))))
+#
+# If a device has opted to not use google prebuilts (determined using
+# PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS), then no jars need to be removed.
+# Example of products where PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS is true are
+# 1. aosp devices (they do not use google apexes)
+# 2. hwasan devices (apex prebuilts are not compatible with these devices)
+# 3. coverage builds
+ifneq (true, $(PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS))
+  APEX_BOOT_JARS_EXCLUDED += $(RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST)
+endif
diff --git a/core/main.mk b/core/main.mk
index d700fcb..62fa53d 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -276,7 +276,7 @@
 # Include all of the makefiles in the system
 #
 
-subdir_makefiles := $(SOONG_ANDROID_MK)
+subdir_makefiles := $(SOONG_OUT_DIR)/installs-$(TARGET_PRODUCT).mk $(SOONG_ANDROID_MK)
 # Android.mk files are only used on Linux builds, Mac only supports Android.bp
 ifeq ($(HOST_OS),linux)
   subdir_makefiles += $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
@@ -287,8 +287,6 @@
 
 $(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
 
-include $(SOONG_OUT_DIR)/installs-$(TARGET_PRODUCT).mk
-
 # For an unbundled image, we can skip blueprint_tools because unbundled image
 # aims to remove a large number framework projects from the manifest, the
 # sources or dependencies for these tools may be missing from the tree.
diff --git a/core/product.mk b/core/product.mk
index 0a761fb..15faf7d 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -447,7 +447,8 @@
 #   device may have to re-compile everything on the first boot if the kernel doesn't support
 #   userfaultfd
 # - "false": disallows the build system and the runtime to use userfaultfd GC even if the device
-#   supports it
+#   supports it. This option is temporary - the plan is to remove it by Aug 2025, at which time
+#   Mainline updates of the ART module will ignore it as well.
 _product_single_value_vars += PRODUCT_ENABLE_UFFD_GC
 
 # Specifies COW version to be used by update_engine and libsnapshot. If this value is not
@@ -483,6 +484,9 @@
 # TODO(b/325991735): link to documentation once it is done.
 _product_single_value_vars += PRODUCT_AVF_MICRODROID_GUEST_GKI_VERSION
 
+# Enables 16KB developer option for device if set.
+_product_single_value_vars += PRODUCT_16K_DEVELOPER_OPTION
+
 .KATI_READONLY := _product_single_value_vars _product_list_vars
 _product_var_list :=$= $(_product_single_value_vars) $(_product_list_vars)
 
diff --git a/core/release_config.mk b/core/release_config.mk
index 97c8dd3..5fe3d39 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -14,6 +14,16 @@
 
 
 # -----------------------------------------------------------------
+# Determine which pass this is.
+# -----------------------------------------------------------------
+# On the first pass, we are asked for only PRODUCT_RELEASE_CONFIG_MAPS,
+# on the second pass, we are asked for whatever else is wanted.
+_final_product_config_pass:=
+ifneq (PRODUCT_RELEASE_CONFIG_MAPS,$(DUMP_MANY_VARS))
+    _final_product_config_pass:=true
+endif
+
+# -----------------------------------------------------------------
 # Choose the flag files
 # -----------------------------------------------------------------
 # Release configs are defined in reflease_config_map files, which map
@@ -90,7 +100,7 @@
 
 ifneq (,$(_must_protobuf))
     ifeq (,$(_can_protobuf))
-	# We must use protobuf, but we cannot use protobuf.
+        # We must use protobuf, but we cannot use protobuf.
         $(error release config is a mixture of .scl and .textproto)
     endif
 endif
@@ -120,12 +130,22 @@
         # Disable the build flag in release-config.
         _args += --guard=false
     endif
-    _flags_file:=$(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).mk
-    $(KATI_shell_no_rerun $(OUT_DIR)/release-config $(_args) >$(OUT_DIR)/release-config.out 2>&1 && touch -t 200001010000 $(OUT_DIR)/release-config.out $(_flags_file))
+    _flags_file:=$(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).vars
+    # release-config generates $(_flags_varmk)
+    _flags_varmk:=$(_flags_file:.vars=.varmk)
+    $(shell $(OUT_DIR)/release-config $(_args) >$(OUT_DIR)/release-config.out 2>&1 && touch -t 200001010000 $(_flags_varmk))
     $(if $(filter-out 0,$(.SHELLSTATUS)),$(error release-config failed to run))
-    # This will also set _all_release_configs for us.
-    $(eval include $(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).mk)
-    $(KATI_extra_file_deps $(OUT_DIR)/release-config $(config_map_files))
+    ifneq (,$(_final_product_config_pass))
+        # Save the final version of the config.
+        $(shell if ! cmp --quiet $(_flags_varmk) $(_flags_file); then cp $(_flags_varmk) $(_flags_file); fi)
+        # This will also set _all_release_configs and _used_files for us.
+        $(eval include $(_flags_file))
+        $(KATI_extra_file_deps $(OUT_DIR)/release-config $(protobuf_map_files) $(_flags_file))
+    else
+        # This is the first pass of product config.
+        $(eval include $(_flags_varmk))
+    endif
+    _used_files :=
     ifeq (,$(_must_protobuf)$(RELEASE_BUILD_FLAGS_IN_PROTOBUF))
         _use_protobuf :=
     endif
@@ -238,7 +258,7 @@
 
 # During pass 1 of product config, using a non-existent release config is not an error.
 # We can safely assume that we are doing pass 1 if DUMP_MANY_VARS=="PRODUCT_RELEASE_CONFIG_MAPS".
-ifneq (PRODUCT_RELEASE_CONFIG_MAPS,$(DUMP_MANY_VARS))
+ifneq (,$(_final_product_config_pass))
     ifeq ($(filter $(_all_release_configs), $(TARGET_RELEASE)),)
         $(error No release config found for TARGET_RELEASE: $(TARGET_RELEASE). Available releases are: $(_all_release_configs))
     endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index acd213c..7300e8c 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -174,6 +174,10 @@
 $(foreach flag,$(_ALL_RELEASE_FLAGS),\
   $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).VALUE)))
 $(call end_json_map)
+$(call add_json_map,  BuildFlagTypes)
+$(foreach flag,$(_ALL_RELEASE_FLAGS),\
+  $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).TYPE)))
+$(call end_json_map)
 
 $(call add_json_bool, DirectedVendorSnapshot,            $(DIRECTED_VENDOR_SNAPSHOT))
 $(call add_json_map,  VendorSnapshotModules)
diff --git a/core/sysprop_config.mk b/core/sysprop_config.mk
index a019a7d..e8428c8 100644
--- a/core/sysprop_config.mk
+++ b/core/sysprop_config.mk
@@ -265,6 +265,9 @@
 config_enable_uffd_gc := \
   $(firstword $(OVERRIDE_ENABLE_UFFD_GC) $(PRODUCT_ENABLE_UFFD_GC) default)
 
+# This is a temporary system property that controls the ART module. The plan is
+# to remove it by Aug 2025, at which time Mainline updates of the ART module
+# will ignore it as well.
 # If the value is "default", it will be mangled by post_process_props.py.
 ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(config_enable_uffd_gc)
 
diff --git a/core/tasks/device-platinum-tests.mk b/core/tasks/device-platinum-tests.mk
new file mode 100644
index 0000000..270248c
--- /dev/null
+++ b/core/tasks/device-platinum-tests.mk
@@ -0,0 +1,68 @@
+# Copyright (C) 2024 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.
+
+
+.PHONY: device-platinum-tests
+
+device-platinum-tests-zip := $(PRODUCT_OUT)/device-platinum-tests.zip
+# Create an artifact to include a list of test config files in device-platinum-tests.
+device-platinum-tests-list-zip := $(PRODUCT_OUT)/device-platinum-tests_list.zip
+# Create an artifact to include all test config files in device-platinum-tests.
+device-platinum-tests-configs-zip := $(PRODUCT_OUT)/device-platinum-tests_configs.zip
+my_host_shared_lib_for_device_platinum_tests := $(call copy-many-files,$(COMPATIBILITY.device-platinum-tests.HOST_SHARED_LIBRARY.FILES))
+device_platinum_tests_host_shared_libs_zip := $(PRODUCT_OUT)/device-platinum-tests_host-shared-libs.zip
+
+$(device-platinum-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-platinum-tests-list-zip) $(device-platinum-tests-configs-zip) $(device_platinum_tests_host_shared_libs_zip)
+$(device-platinum-tests-zip) : PRIVATE_device_platinum_tests_list := $(PRODUCT_OUT)/device-platinum-tests_list
+$(device-platinum-tests-zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_platinum_tests)
+$(device-platinum-tests-zip) : PRIVATE_device_host_shared_libs_zip := $(device_platinum_tests_host_shared_libs_zip)
+$(device-platinum-tests-zip) : $(COMPATIBILITY.device-platinum-tests.FILES) $(my_host_shared_lib_for_device_platinum_tests) $(SOONG_ZIP)
+	rm -f $@-shared-libs.list
+	echo $(sort $(COMPATIBILITY.device-platinum-tests.FILES)) | tr " " "\n" > $@.list
+	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
+	grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true
+	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
+	  echo $$shared_lib >> $@-host.list; \
+	  echo $$shared_lib >> $@-shared-libs.list; \
+	done
+	grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true
+	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
+	grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true
+	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list -sha256
+	$(hide) $(SOONG_ZIP) -d -o $(device-platinum-tests-configs-zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-test-configs.list \
+	  -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list
+	$(SOONG_ZIP) -d -o $(PRIVATE_device_host_shared_libs_zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-shared-libs.list
+	rm -f $(PRIVATE_device_platinum_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_device_platinum_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_device_platinum_tests_list)
+	$(hide) $(SOONG_ZIP) -d -o $(device-platinum-tests-list-zip) -C $(dir $@) -f $(PRIVATE_device_platinum_tests_list)
+	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
+	  $@-shared-libs.list $@-host-shared-libs.list $(PRIVATE_device_platinum_tests_list)
+
+device-platinum-tests: $(device-platinum-tests-zip)
+$(call dist-for-goals, device-platinum-tests, $(device-platinum-tests-zip) $(device-platinum-tests-list-zip) $(device-platinum-tests-configs-zip) $(device_platinum_tests_host_shared_libs_zip))
+
+$(call declare-1p-container,$(device-platinum-tests-zip),)
+$(call declare-container-license-deps,$(device-platinum-tests-zip),$(COMPATIBILITY.device-platinum-tests.FILES) $(my_host_shared_lib_for_device_platinum_tests),$(PRODUCT_OUT)/:/)
+
+tests: device-platinum-tests
+
+# Reset temp vars
+device-platinum-tests-zip :=
+device-platinum-tests-list-zip :=
+device-platinum-tests-configs-zip :=
+my_host_shared_lib_for_device_platinum_tests :=
+device_platinum_tests_host_shared_libs_zip :=
\ No newline at end of file
diff --git a/core/tasks/meta-lic.mk b/core/tasks/meta-lic.mk
index 2126bd0..c41de63 100644
--- a/core/tasks/meta-lic.mk
+++ b/core/tasks/meta-lic.mk
@@ -140,3 +140,10 @@
 $(eval $(call declare-1p-copy-files,frameworks/base,dirty-image-objects))
 $(eval $(call declare-1p-copy-files,frameworks/base/config,))
 $(eval $(call declare-1p-copy-files,frameworks/native/data,))
+
+# Moved here from hardware/google/camera/Android.mk
+$(eval $(call declare-1p-copy-files,hardware/google/camera,))
+
+# Moved here from hardware/interfaces/tv/Android.mk
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_0.xml))
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_1.xml))
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index aa695eb..daa7089 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -32,6 +32,7 @@
 			$(call write-optional-json-list, "auto_test_config", $(sort $(ALL_MODULES.$(m).auto_test_config))) \
 			$(call write-optional-json-list, "test_config", $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS))) \
 			$(call write-optional-json-list, "dependencies", $(sort $(ALL_MODULES.$(m).ALL_DEPS))) \
+			$(call write-optional-json-list, "required", $(sort $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET))) \
 			$(call write-optional-json-list, "shared_libs", $(sort $(ALL_MODULES.$(m).SHARED_LIBS))) \
 			$(call write-optional-json-list, "static_libs", $(sort $(ALL_MODULES.$(m).STATIC_LIBS))) \
 			$(call write-optional-json-list, "system_shared_libs", $(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS))) \
@@ -52,6 +53,8 @@
 	$(PRIVATE_MERGE_JSON_OBJECTS) -o $@ $(PRIVATE_SOONG_MODULE_INFO) $@.tmp
 	rm $@.tmp
 
+.PHONY: module-info
+module-info: $(MODULE_INFO_JSON)
 
 droidcore-unbundled: $(MODULE_INFO_JSON)
 
diff --git a/core/tasks/performance-tests.mk b/core/tasks/performance-tests.mk
new file mode 100644
index 0000000..32c156d
--- /dev/null
+++ b/core/tasks/performance-tests.mk
@@ -0,0 +1,54 @@
+# Copyright (C) 2024 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.
+
+
+.PHONY: performance-tests
+
+performance-tests-zip := $(PRODUCT_OUT)/performance-tests.zip
+# Create an artifact to include a list of test config files in performance-tests.
+performance-tests-list-zip := $(PRODUCT_OUT)/performance-tests_list.zip
+# Create an artifact to include all test config files in performance-tests.
+performance-tests-configs-zip := $(PRODUCT_OUT)/performance-tests_configs.zip
+
+$(performance-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(performance-tests-list-zip) $(performance-tests-configs-zip)
+$(performance-tests-zip) : PRIVATE_performance_tests_list := $(PRODUCT_OUT)/performance-tests_list
+$(performance-tests-zip) : $(COMPATIBILITY.performance-tests.FILES) $(SOONG_ZIP)
+	echo $(sort $(COMPATIBILITY.performance-tests.FILES)) | tr " " "\n" > $@.list
+	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
+	grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true
+	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
+	grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true
+	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list -sha256
+	$(hide) $(SOONG_ZIP) -d -o $(performance-tests-configs-zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-test-configs.list \
+	  -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list
+	rm -f $(PRIVATE_performance_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_performance_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_performance_tests_list)
+	$(hide) $(SOONG_ZIP) -d -o $(performance-tests-list-zip) -C $(dir $@) -f $(PRIVATE_performance_tests_list)
+	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
+	  $(PRIVATE_performance_tests_list)
+
+performance-tests: $(performance-tests-zip)
+$(call dist-for-goals, performance-tests, $(performance-tests-zip) $(performance-tests-list-zip) $(performance-tests-configs-zip))
+
+$(call declare-1p-container,$(performance-tests-zip),)
+$(call declare-container-license-deps,$(performance-tests-zip),$(COMPATIBILITY.performance-tests.FILES),$(PRODUCT_OUT)/:/)
+
+tests: performance-tests
+
+# Reset temp vars
+performance-tests-zip :=
+performance-tests-list-zip :=
+performance-tests-configs-zip :=
diff --git a/envsetup.sh b/envsetup.sh
index ff3c3a6..640ed14 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -93,7 +93,6 @@
 - godir:      Go to the directory containing a file.
 - allmod:     List all modules.
 - gomod:      Go to the directory containing a module.
-- bmod:       Get the Bazel label of a Soong module if it is converted with bp2build.
 - pathmod:    Get the directory containing a module.
 - outmod:     Gets the location of a module's installed outputs with a certain extension.
 - dirmods:    Gets the modules defined in a given directory.
@@ -209,40 +208,6 @@
   fi
 }
 
-# check to see if the supplied product is one we can build
-function check_product()
-{
-    local T=$(gettop)
-    if [ ! "$T" ]; then
-        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
-        return
-    fi
-        TARGET_PRODUCT=$1 \
-        TARGET_RELEASE= \
-        TARGET_BUILD_VARIANT= \
-        TARGET_BUILD_TYPE= \
-        TARGET_BUILD_APPS= \
-        get_build_var TARGET_DEVICE > /dev/null
-    # hide successful answers, but allow the errors to show
-}
-
-VARIANT_CHOICES=(user userdebug eng)
-
-# check to see if the supplied variant is valid
-function check_variant()
-{
-    local v
-    for v in ${VARIANT_CHOICES[@]}
-    do
-        if [ "$v" = "$1" ]
-        then
-            return 0
-        fi
-    done
-    return 1
-}
-
-
 # Add directories to PATH that are dependent on the lunch target.
 # For directories that are not lunch-specific, add them in set_global_paths
 function set_lunch_paths()
@@ -480,9 +445,6 @@
         fi
     done
 
-    if should_add_completion bit ; then
-        complete -C "bit --tab" bit
-    fi
     if [ -z "$ZSH_VERSION" ]; then
         # Doesn't work in zsh.
         complete -o nospace -F _croot croot
@@ -495,240 +457,9 @@
     complete -F _complete_android_module_names gomod
     complete -F _complete_android_module_names outmod
     complete -F _complete_android_module_names installmod
-    complete -F _complete_android_module_names bmod
     complete -F _complete_android_module_names m
 }
 
-function multitree_lunch_help()
-{
-    echo "usage: lunch PRODUCT-RELEASE-VARIANT" 1>&2
-    echo "    Set up android build environment based on a product short name and variant" 1>&2
-    echo 1>&2
-    echo "lunch COMBO_FILE VARIANT" 1>&2
-    echo "    Set up android build environment based on a specific lunch combo file" 1>&2
-    echo "    and variant." 1>&2
-    echo 1>&2
-    echo "lunch --print [CONFIG]" 1>&2
-    echo "    Print the contents of a configuration.  If CONFIG is supplied, that config" 1>&2
-    echo "    will be flattened and printed.  If CONFIG is not supplied, the currently" 1>&2
-    echo "    selected config will be printed.  Returns 0 on success or nonzero on error." 1>&2
-    echo 1>&2
-    echo "lunch --list" 1>&2
-    echo "    List all possible combo files available in the current tree" 1>&2
-    echo 1>&2
-    echo "lunch --help" 1>&2
-    echo "lunch -h" 1>&2
-    echo "    Prints this message." 1>&2
-}
-
-function multitree_lunch()
-{
-    local code
-    local results
-    # Lunch must be run in the topdir, but this way we get a clear error
-    # message, instead of FileNotFound.
-    local T=$(multitree_gettop)
-    if [ -z "$T" ]; then
-      _multitree_lunch_error
-      return 1
-    fi
-    if $(echo "$1" | grep -q '^-') ; then
-        # Calls starting with a -- argument are passed directly and the function
-        # returns with the lunch.py exit code.
-        "${T}/orchestrator/build/orchestrator/core/lunch.py" "$@"
-        code=$?
-        if [[ $code -eq 2 ]] ; then
-          echo 1>&2
-          multitree_lunch_help
-          return $code
-        elif [[ $code -ne 0 ]] ; then
-          return $code
-        fi
-    else
-        # All other calls go through the --lunch variant of lunch.py
-        results=($(${T}/orchestrator/build/orchestrator/core/lunch.py --lunch "$@"))
-        code=$?
-        if [[ $code -eq 2 ]] ; then
-          echo 1>&2
-          multitree_lunch_help
-          return $code
-        elif [[ $code -ne 0 ]] ; then
-          return $code
-        fi
-
-        export TARGET_BUILD_COMBO=${results[0]}
-        export TARGET_BUILD_VARIANT=${results[1]}
-    fi
-}
-
-function choosetype()
-{
-    echo "Build type choices are:"
-    echo "     1. release"
-    echo "     2. debug"
-    echo
-
-    local DEFAULT_NUM DEFAULT_VALUE
-    DEFAULT_NUM=1
-    DEFAULT_VALUE=release
-
-    export TARGET_BUILD_TYPE=
-    local ANSWER
-    while [ -z $TARGET_BUILD_TYPE ]
-    do
-        echo -n "Which would you like? ["$DEFAULT_NUM"] "
-        if [ -z "$1" ] ; then
-            read ANSWER
-        else
-            echo $1
-            ANSWER=$1
-        fi
-        case $ANSWER in
-        "")
-            export TARGET_BUILD_TYPE=$DEFAULT_VALUE
-            ;;
-        1)
-            export TARGET_BUILD_TYPE=release
-            ;;
-        release)
-            export TARGET_BUILD_TYPE=release
-            ;;
-        2)
-            export TARGET_BUILD_TYPE=debug
-            ;;
-        debug)
-            export TARGET_BUILD_TYPE=debug
-            ;;
-        *)
-            echo
-            echo "I didn't understand your response.  Please try again."
-            echo
-            ;;
-        esac
-        if [ -n "$1" ] ; then
-            break
-        fi
-    done
-
-    build_build_var_cache
-    set_stuff_for_environment
-    destroy_build_var_cache
-}
-
-#
-# This function isn't really right:  It chooses a TARGET_PRODUCT
-# based on the list of boards.  Usually, that gets you something
-# that kinda works with a generic product, but really, you should
-# pick a product by name.
-#
-function chooseproduct()
-{
-    local default_value
-    if [ "x$TARGET_PRODUCT" != x ] ; then
-        default_value=$TARGET_PRODUCT
-    else
-        default_value=aosp_arm
-    fi
-
-    export TARGET_BUILD_APPS=
-    export TARGET_PRODUCT=
-    local ANSWER
-    while [ -z "$TARGET_PRODUCT" ]
-    do
-        echo -n "Which product would you like? [$default_value] "
-        if [ -z "$1" ] ; then
-            read ANSWER
-        else
-            echo $1
-            ANSWER=$1
-        fi
-
-        if [ -z "$ANSWER" ] ; then
-            export TARGET_PRODUCT=$default_value
-        else
-            if check_product $ANSWER
-            then
-                export TARGET_PRODUCT=$ANSWER
-            else
-                echo "** Not a valid product: $ANSWER"
-            fi
-        fi
-        if [ -n "$1" ] ; then
-            break
-        fi
-    done
-
-    build_build_var_cache
-    set_stuff_for_environment
-    destroy_build_var_cache
-}
-
-function choosevariant()
-{
-    echo "Variant choices are:"
-    local index=1
-    local v
-    for v in ${VARIANT_CHOICES[@]}
-    do
-        # The product name is the name of the directory containing
-        # the makefile we found, above.
-        echo "     $index. $v"
-        index=$(($index+1))
-    done
-
-    local default_value=eng
-    local ANSWER
-
-    export TARGET_BUILD_VARIANT=
-    while [ -z "$TARGET_BUILD_VARIANT" ]
-    do
-        echo -n "Which would you like? [$default_value] "
-        if [ -z "$1" ] ; then
-            read ANSWER
-        else
-            echo $1
-            ANSWER=$1
-        fi
-
-        if [ -z "$ANSWER" ] ; then
-            export TARGET_BUILD_VARIANT=$default_value
-        elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
-            if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
-                export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[@]:$(($ANSWER-1)):1}
-            fi
-        else
-            if check_variant $ANSWER
-            then
-                export TARGET_BUILD_VARIANT=$ANSWER
-            else
-                echo "** Not a valid variant: $ANSWER"
-            fi
-        fi
-        if [ -n "$1" ] ; then
-            break
-        fi
-    done
-}
-
-function choosecombo()
-{
-    choosetype $1
-
-    echo
-    echo
-    chooseproduct $2
-
-    echo
-    echo
-    choosevariant $3
-
-    echo
-    build_build_var_cache
-    set_stuff_for_environment
-    printconfig
-    destroy_build_var_cache
-}
-
 function add_lunch_combo()
 {
     if [ -n "$ZSH_VERSION" ]; then
@@ -1026,34 +757,6 @@
     destroy_build_var_cache
 }
 
-# TODO: Merge into gettop as part of launching multitree
-function multitree_gettop
-{
-    local TOPFILE=orchestrator/build/make/core/envsetup.mk
-    if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
-        # The following circumlocution ensures we remove symlinks from TOP.
-        (cd "$TOP"; PWD= /bin/pwd)
-    else
-        if [ -f $TOPFILE ] ; then
-            # The following circumlocution (repeated below as well) ensures
-            # that we record the true directory name and not one that is
-            # faked up with symlink names.
-            PWD= /bin/pwd
-        else
-            local HERE=$PWD
-            local T=
-            while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
-                \cd ..
-                T=`PWD= /bin/pwd -P`
-            done
-            \cd "$HERE"
-            if [ -f "$T/$TOPFILE" ]; then
-                echo "$T"
-            fi
-        fi
-    fi
-}
-
 function croot()
 {
     local T=$(gettop)
@@ -1144,11 +847,11 @@
   # Remove the trap to prevent duplicate log.
   trap - EXIT;
   "${logger}" \
-    --tool_tag "${tool_tag}" \
-    --start_timestamp "${start_time}" \
-    --end_timestamp "$(date +%s.%N)" \
-    --tool_args "$*" \
-    --exit_code "${exit_code}" \
+    --tool_tag="${tool_tag}" \
+    --start_timestamp="${start_time}" \
+    --end_timestamp="$(date +%s.%N)" \
+    --tool_args="$*" \
+    --exit_code="${exit_code}" \
     ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \
     > /dev/null 2>&1 &
   exit ${exit_code}
@@ -1183,18 +886,6 @@
     fi
 }
 
-# syswrite - disable verity, reboot if needed, and remount image
-#
-# Easy way to make system.img/etc writable
-function syswrite() {
-  adb wait-for-device && adb root && adb wait-for-device || return 1
-  if [[ $(adb disable-verity | grep -i "reboot") ]]; then
-      echo "rebooting"
-      adb reboot && adb wait-for-device && adb root && adb wait-for-device || return 1
-  fi
-  adb remount || return 1
-}
-
 # coredump_setup - enable core dumps globally for any process
 #                  that has the core-file-size limit set correctly
 #
@@ -1297,146 +988,11 @@
     fi
 }
 
-case `uname -s` in
-    Darwin)
-        function sgrep()
-        {
-            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cc|cpp|hpp|S|java|kt|xml|sh|mk|aidl|vts|proto|rs|go)' \
-                -exec grep --color -n "$@" {} +
-        }
-
-        ;;
-    *)
-        function sgrep()
-        {
-            find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cc\|cpp\|hpp\|S\|java\|kt\|xml\|sh\|mk\|aidl\|vts\|proto\|rs\|go\)' \
-                -exec grep --color -n "$@" {} +
-        }
-        ;;
-esac
-
 function gettargetarch
 {
     get_build_var TARGET_ARCH
 }
 
-function ggrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" \
-        -exec grep --color -n "$@" {} +
-}
-
-function gogrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.go" \
-        -exec grep --color -n "$@" {} +
-}
-
-function jgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" \
-        -exec grep --color -n "$@" {} +
-}
-
-function rsgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rs" \
-        -exec grep --color -n "$@" {} +
-}
-
-function jsongrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.json" \
-        -exec grep --color -n "$@" {} +
-}
-
-function tomlgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.toml" \
-        -exec grep --color -n "$@" {} +
-}
-
-function ktgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.kt" \
-        -exec grep --color -n "$@" {} +
-}
-
-function cgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \
-        -exec grep --color -n "$@" {} +
-}
-
-function resgrep()
-{
-    local dir
-    for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do
-        find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} +
-    done
-}
-
-function mangrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' \
-        -exec grep --color -n "$@" {} +
-}
-
-function owngrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'OWNERS' \
-        -exec grep --color -n "$@" {} +
-}
-
-function sepgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \
-        -exec grep --color -n -r --exclude-dir=\.git "$@" {} +
-}
-
-function rcgrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rc*" \
-        -exec grep --color -n "$@" {} +
-}
-
-function pygrep()
-{
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.py" \
-        -exec grep --color -n "$@" {} +
-}
-
-case `uname -s` in
-    Darwin)
-        function mgrep()
-        {
-            find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \
-                -exec grep --color -n "$@" {} +
-        }
-
-        function treegrep()
-        {
-            find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|hpp|S|java|kt|xml)' \
-                -exec grep --color -n -i "$@" {} +
-        }
-
-        ;;
-    *)
-        function mgrep()
-        {
-            find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regextype posix-extended -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \
-                -exec grep --color -n "$@" {} +
-        }
-
-        function treegrep()
-        {
-            find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|hpp|S|java|kt|xml)' -type f \
-                -exec grep --color -n -i "$@" {} +
-        }
-
-        ;;
-esac
-
 function getprebuilt
 {
     get_abs_build_var ANDROID_PREBUILTS
@@ -1588,17 +1144,6 @@
       adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
 }
 
-# simple shortcut to the runtest command
-function runtest()
-{
-    local T=$(gettop)
-    if [ ! "$T" ]; then
-        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
-        return
-    fi
-    ("$T"/development/testrunner/runtest.py $@)
-}
-
 function godir () {
     if [[ -z "$1" ]]; then
         echo "Usage: godir <regex>"
@@ -1650,23 +1195,6 @@
     \cd $T/$pathname
 }
 
-# Update module-info.json in out.
-function refreshmod() {
-    if [ ! "$ANDROID_PRODUCT_OUT" ]; then
-        echo "No ANDROID_PRODUCT_OUT. Try running 'lunch' first." >&2
-        return 1
-    fi
-
-    echo "Refreshing modules (building module-info.json). Log at $ANDROID_PRODUCT_OUT/module-info.json.build.log." >&2
-
-    # for the output of the next command
-    mkdir -p $ANDROID_PRODUCT_OUT || return 1
-
-    # Note, can't use absolute path because of the way make works.
-    m $(get_build_var PRODUCT_OUT)/module-info.json \
-        > $ANDROID_PRODUCT_OUT/module-info.json.build.log 2>&1
-}
-
 # Verifies that module-info.txt exists, returning nonzero if it doesn't.
 function verifymodinfo() {
     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
@@ -1690,48 +1218,6 @@
     cat $ANDROID_PRODUCT_OUT/all_modules.txt 2>/dev/null
 }
 
-# Return the Bazel label of a Soong module if it is converted with bp2build.
-function bmod()
-(
-    if [ $# -eq 0 ]; then
-        echo "usage: bmod <module 1> <module 2> ... <module n>" >&2
-        return 1
-    fi
-
-    # We could run bp2build here, but it might trigger bp2build invalidation
-    # when used with `b` (e.g. --run_soong_tests) and/or add unnecessary waiting
-    # time overhead.
-    #
-    # For a snappy result, use the latest generated version in soong_injection,
-    # and ask users to run m bp2build if it doesn't exist.
-    converted_json="$(get_abs_build_var OUT_DIR)/soong/soong_injection/metrics/converted_modules_path_map.json"
-
-    if [ ! -f ${converted_json} ]; then
-      echo "bp2build files not found. Have you ran 'm bp2build'?" >&2
-      return 1
-    fi
-
-    modules=()
-    for m in "$@"; do
-        modules+=("\"$m\",")
-    done
-    local res=$(python3 -c "import json
-modules = [${modules[*]}]
-converted_json='$converted_json'
-bp2build_converted_map = json.load(open(converted_json))
-for module in modules:
-    if module not in bp2build_converted_map:
-        print(module + ' is not converted to Bazel.')
-    else:
-        print(bp2build_converted_map[module] + ':' + module)")
-
-    echo "${res}"
-    unconverted_count=$(echo "${res}" | grep -c "not converted to Bazel")
-    if [[ ${unconverted_count} -ne 0 ]]; then
-        return 1
-    fi
-)
-
 # Get the path of a specific module in the android tree, as cached in module-info.json.
 # If any build change is made, and it should be reflected in the output, you should run
 # 'refreshmod' first.  Note: This is the inverse of dirmods.
@@ -1904,50 +1390,6 @@
     fi
 }
 
-function _wrap_build()
-{
-    if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then
-      "$@"
-      return $?
-    fi
-    local start_time=$(date +"%s")
-    "$@"
-    local ret=$?
-    local end_time=$(date +"%s")
-    local tdiff=$(($end_time-$start_time))
-    local hours=$(($tdiff / 3600 ))
-    local mins=$((($tdiff % 3600) / 60))
-    local secs=$(($tdiff % 60))
-    local ncolors=$(tput colors 2>/dev/null)
-    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
-        color_failed=$'\E'"[0;31m"
-        color_success=$'\E'"[0;32m"
-        color_warning=$'\E'"[0;33m"
-        color_reset=$'\E'"[00m"
-    else
-        color_failed=""
-        color_success=""
-        color_reset=""
-    fi
-
-    echo
-    if [ $ret -eq 0 ] ; then
-        echo -n "${color_success}#### build completed successfully "
-    else
-        echo -n "${color_failed}#### failed to build some targets "
-    fi
-    if [ $hours -gt 0 ] ; then
-        printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
-    elif [ $mins -gt 0 ] ; then
-        printf "(%02g:%02g (mm:ss))" $mins $secs
-    elif [ $secs -gt 0 ] ; then
-        printf "(%s seconds)" $secs
-    fi
-    echo " ####${color_reset}"
-    echo
-    return $ret
-}
-
 function _trigger_build()
 (
     local -r bc="$1"; shift
@@ -1965,52 +1407,11 @@
     return $ret
 )
 
-function m()
-(
-    _trigger_build "all-modules" "$@"
-)
-
-function mm()
-(
-    _trigger_build "modules-in-a-dir-no-deps" "$@"
-)
-
-function mmm()
-(
-    _trigger_build "modules-in-dirs-no-deps" "$@"
-)
-
-function mma()
-(
-    _trigger_build "modules-in-a-dir" "$@"
-)
-
-function mmma()
-(
-    _trigger_build "modules-in-dirs" "$@"
-)
-
 function make()
 {
     _wrap_build $(get_make_command "$@") "$@"
 }
 
-function _multitree_lunch_error()
-{
-      >&2 echo "Couldn't locate the top of the tree. Please run \'source build/envsetup.sh\' and multitree_lunch from the root of your workspace."
-}
-
-function multitree_build()
-{
-    local T=$(multitree_gettop)
-    if [ -n "$T" ]; then
-      "$T/orchestrator/build/orchestrator/core/orchestrator.py" "$@"
-    else
-      _multitree_lunch_error
-      return 1
-    fi
-}
-
 function provision()
 {
     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
@@ -2132,25 +1533,42 @@
     fi
 }
 
-function avbtool() {
-    if [[ ! -f "$ANDROID_SOONG_HOST_OUT"/bin/avbtool ]]; then
-        m avbtool
-    fi
-    "$ANDROID_SOONG_HOST_OUT"/bin/avbtool $@
-}
+# These functions used to be here but are now standalone scripts
+# in build/soong/bin.  Unset these for the time being so the real
+# script is picked up.
+# TODO: Remove this some time after a suitable delay (maybe 2025?)
+unset aninja
+unset overrideflags
+unset m
+unset mm
+unset mmm
+unset mma
+unset mmma
+unset cgrep
+unset ggrep
+unset gogrep
+unset jgrep
+unset jsongrep
+unset ktgrep
+unset mangrep
+unset mgrep
+unset owngrep
+unset pygrep
+unset rcgrep
+unset resgrep
+unset rsgrep
+unset sepgrep
+unset sgrep
+unset tomlgrep
+unset treegrep
+unset syswrite
+unset refreshmod
 
-function overrideflags() {
-    local T="$(gettop)"
-    (\cd "${T}" && build/make/tools/overrideflags.sh "$@")
-}
-
-function aninja() {
-    local T="$(gettop)"
-    (\cd "${T}" && prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@")
-}
 
 validate_current_shell
 set_global_paths
 source_vendorsetup
 addcompletions
 
+
+
diff --git a/shell_utils.sh b/shell_utils.sh
index 9de5a50..450bb83 100644
--- a/shell_utils.sh
+++ b/shell_utils.sh
@@ -40,15 +40,24 @@
     fi
 }
 
-# Sets TOP, or if the root of the tree can't be found, prints a message and
-# exits.  Since this function exits, it should not be called from functions
-# defined in envsetup.sh.
+# Asserts that the root of the tree can be found.
 if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
 function require_top
 {
     TOP=$(gettop)
     if [[ ! $TOP ]] ; then
-        echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree." >&2
+        echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree or TOP must be set." >&2
+        exit 1
+    fi
+}
+fi
+
+# Asserts that the lunch variables have been set
+if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
+function require_lunch
+{
+    if [[ ! $TARGET_PRODUCT || ! $TARGET_RELEASE || ! $TARGET_BUILD_VARIANT  ]] ; then
+        echo "Please run lunch and try again." >&2
         exit 1
     fi
 }
@@ -71,4 +80,50 @@
     echo "${out_dir}"
 }
 
+# Pretty print the build status and duration
+function _wrap_build()
+{
+    if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then
+      "$@"
+      return $?
+    fi
+    local start_time=$(date +"%s")
+    "$@"
+    local ret=$?
+    local end_time=$(date +"%s")
+    local tdiff=$(($end_time-$start_time))
+    local hours=$(($tdiff / 3600 ))
+    local mins=$((($tdiff % 3600) / 60))
+    local secs=$(($tdiff % 60))
+    local ncolors=$(tput colors 2>/dev/null)
+    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
+        color_failed=$'\E'"[0;31m"
+        color_success=$'\E'"[0;32m"
+        color_warning=$'\E'"[0;33m"
+        color_reset=$'\E'"[00m"
+    else
+        color_failed=""
+        color_success=""
+        color_reset=""
+    fi
+
+    echo
+    if [ $ret -eq 0 ] ; then
+        echo -n "${color_success}#### build completed successfully "
+    else
+        echo -n "${color_failed}#### failed to build some targets "
+    fi
+    if [ $hours -gt 0 ] ; then
+        printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
+    elif [ $mins -gt 0 ] ; then
+        printf "(%02g:%02g (mm:ss))" $mins $secs
+    elif [ $secs -gt 0 ] ; then
+        printf "(%s seconds)" $secs
+    fi
+    echo " ####${color_reset}"
+    echo
+    return $ret
+}
+
+
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index b1a26c3..c553765 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -174,7 +174,6 @@
     libjpeg \
     liblog \
     libm.bootstrap \
-    libmdnssd \
     libmedia \
     libmedia_jni \
     libmediandk \
@@ -293,6 +292,7 @@
     uprobestats \
     usbd \
     vdc \
+    vintf \
     voip-common \
     vold \
     watchdogd \
diff --git a/target/product/ndk.mk b/target/product/ndk.mk
index 1dfd0db..e4f77f7 100644
--- a/target/product/ndk.mk
+++ b/target/product/ndk.mk
@@ -19,3 +19,5 @@
 PRODUCT_NAME := ndk
 PRODUCT_BRAND := Android
 PRODUCT_DEVICE := ndk
+
+PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
diff --git a/target/product/virtual_ab_ota/vabc_features.mk b/target/product/virtual_ab_ota/vabc_features.mk
index 3f484e4..1219763 100644
--- a/target/product/virtual_ab_ota/vabc_features.mk
+++ b/target/product/virtual_ab_ota/vabc_features.mk
@@ -34,6 +34,21 @@
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+# Low memory device configurations. If memory usage and cpu utilization is
+# a bottleneck during OTA, the below configurations can be added to a
+# device's .mk file improve performance for low mem devices. Disabling
+# ro.virtual_ab.compression.xor.enabled and ro.virtual_ab.io_uring.enabled
+# is also recommended
+#
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.o_direct.enabled=true
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.merge_thread_priority=19
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.worker_thread_priority=0
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_worker_threads=3
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_merge_threads=1
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_verify_threads=1
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.cow_op_merge_size=16
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.verify_threshold_size=1073741824
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.verify_block_size=1048576
 
 # Enabling this property, will improve OTA install time
 # but will use an additional CPU core
diff --git a/tests/run_tool_with_logging_test.py b/tests/run_tool_with_logging_test.py
index 18abd8e..6f9b59c 100644
--- a/tests/run_tool_with_logging_test.py
+++ b/tests/run_tool_with_logging_test.py
@@ -90,8 +90,8 @@
 
     test_tool.assert_called_once_with_args("arg1 arg2")
     expected_logger_args = (
-        "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp"
-        " \d+\.\d+ --tool_args arg1 arg2 --exit_code 0"
+        "--tool_tag=FAKE_TOOL --start_timestamp=\d+\.\d+ --end_timestamp="
+        "\d+\.\d+ --tool_args=arg1 arg2 --exit_code=0"
     )
     test_logger.assert_called_once_with_args(expected_logger_args)
 
@@ -163,8 +163,8 @@
     self.assertEqual(returncode, INTERRUPTED_RETURN_CODE)
 
     expected_logger_args = (
-        "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp"
-        " \d+\.\d+ --tool_args arg1 arg2 --exit_code 130"
+        "--tool_tag=FAKE_TOOL --start_timestamp=\d+\.\d+ --end_timestamp="
+        "\d+\.\d+ --tool_args=arg1 arg2 --exit_code=130"
     )
     test_logger.assert_called_once_with_args(expected_logger_args)
 
@@ -205,6 +205,19 @@
 
     self._assert_logger_dry_run()
 
+  def test_tool_args_do_not_fail_logger(self):
+    test_tool = TestScript.create(self.working_dir)
+    logger_path = self._import_logger()
+
+    self._run_script_and_wait(f"""
+      TMPDIR="{self.working_dir.name}"
+      ANDROID_TOOL_LOGGER="{logger_path}"
+      ANDROID_TOOL_LOGGER_EXTRA_ARGS="--dry_run"
+      run_tool_with_logging "FAKE_TOOL" {test_tool.executable} --tool-arg1
+    """)
+
+    self._assert_logger_dry_run()
+
   def _import_logger(self) -> Path:
     logger = "tool_event_logger"
     logger_path = Path(self.working_dir.name).joinpath(logger)
diff --git a/tools/aconfig/aconfig_protos/Android.bp b/tools/aconfig/aconfig_protos/Android.bp
index 18c545a..d241994 100644
--- a/tools/aconfig/aconfig_protos/Android.bp
+++ b/tools/aconfig/aconfig_protos/Android.bp
@@ -17,7 +17,22 @@
     apex_available: [
         "com.android.configinfrastructure",
         "//apex_available:platform",
-    ]
+    ],
+}
+
+java_library {
+    name: "libaconfig_java_proto_nano",
+    srcs: ["protos/aconfig.proto"],
+    static_libs: ["libprotobuf-java-nano"],
+    proto: {
+        type: "nano",
+    },
+    sdk_version: "current",
+    min_sdk_version: "UpsideDownCake",
+    apex_available: [
+        "//apex_available:platform",
+    ],
+    jarjar_rules: "jarjar-nano-rules.txt",
 }
 
 java_library_host {
@@ -58,7 +73,7 @@
     ],
     proc_macros: [
         "libpaste",
-    ]
+    ],
 }
 
 rust_library {
diff --git a/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt b/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt
new file mode 100644
index 0000000..b58fa64
--- /dev/null
+++ b/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.** android.internal.framework.protobuf.@1
\ No newline at end of file
diff --git a/tools/aconfig/aflags/src/aconfig_storage_source.rs b/tools/aconfig/aflags/src/aconfig_storage_source.rs
index c21c542..04140c7 100644
--- a/tools/aconfig/aflags/src/aconfig_storage_source.rs
+++ b/tools/aconfig/aflags/src/aconfig_storage_source.rs
@@ -27,8 +27,7 @@
             let container =
                 file_info.container.ok_or(anyhow!("storage file is missing container"))?;
 
-            for listed_flag in
-                aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
+            for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
             {
                 result.push(Flag {
                     name: listed_flag.flag_name,
diff --git a/tools/aconfig/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs
index 516b773..05c15bb 100644
--- a/tools/aconfig/aflags/src/main.rs
+++ b/tools/aconfig/aflags/src/main.rs
@@ -35,10 +35,14 @@
 
 impl std::fmt::Display for FlagPermission {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", match &self {
-            Self::ReadOnly => "read-only",
-            Self::ReadWrite => "read-write",
-        })
+        write!(
+            f,
+            "{}",
+            match &self {
+                Self::ReadOnly => "read-only",
+                Self::ReadWrite => "read-write",
+            }
+        )
     }
 }
 
@@ -50,10 +54,14 @@
 
 impl std::fmt::Display for ValuePickedFrom {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", match &self {
-            Self::Default => "default",
-            Self::Server => "server",
-        })
+        write!(
+            f,
+            "{}",
+            match &self {
+                Self::Default => "default",
+                Self::Server => "server",
+            }
+        )
     }
 }
 
@@ -77,10 +85,14 @@
 
 impl std::fmt::Display for FlagValue {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", match &self {
-            Self::Enabled => "enabled",
-            Self::Disabled => "disabled",
-        })
+        write!(
+            f,
+            "{}",
+            match &self {
+                Self::Enabled => "enabled",
+                Self::Disabled => "disabled",
+            }
+        )
     }
 }
 
@@ -153,6 +165,10 @@
         /// Read from the new flag storage.
         #[clap(long)]
         use_new_storage: bool,
+
+        /// Optionally filter by container name.
+        #[clap(short = 'c', long = "container")]
+        container: Option<String>,
     },
 
     /// Enable an aconfig flag on this device, on the next boot.
@@ -176,6 +192,23 @@
     longest_permission_col: usize,
 }
 
+struct Filter {
+    container: Option<String>,
+}
+
+impl Filter {
+    fn apply(&self, flags: &[Flag]) -> Vec<Flag> {
+        flags
+            .iter()
+            .filter(|flag| match &self.container {
+                Some(c) => flag.container == *c,
+                None => true,
+            })
+            .cloned()
+            .collect()
+    }
+}
+
 fn format_flag_row(flag: &Flag, info: &PaddingInfo) -> String {
     let full_name = flag.qualified_name();
     let p0 = info.longest_flag_col + 1;
@@ -215,11 +248,12 @@
     Ok(())
 }
 
-fn list(source_type: FlagSourceType) -> Result<String> {
-    let flags = match source_type {
+fn list(source_type: FlagSourceType, container: Option<String>) -> Result<String> {
+    let flags_unfiltered = match source_type {
         FlagSourceType::DeviceConfig => DeviceConfigSource::list_flags()?,
         FlagSourceType::AconfigStorage => AconfigStorageSource::list_flags()?,
     };
+    let flags = (Filter { container }).apply(&flags_unfiltered);
     let padding_info = PaddingInfo {
         longest_flag_col: flags.iter().map(|f| f.qualified_name().len()).max().unwrap_or(0),
         longest_val_col: flags.iter().map(|f| f.value.to_string().len()).max().unwrap_or(0),
@@ -251,8 +285,12 @@
 fn main() {
     let cli = Cli::parse();
     let output = match cli.command {
-        Command::List { use_new_storage: true } => list(FlagSourceType::AconfigStorage).map(Some),
-        Command::List { use_new_storage: false } => list(FlagSourceType::DeviceConfig).map(Some),
+        Command::List { use_new_storage: true, container } => {
+            list(FlagSourceType::AconfigStorage, container).map(Some)
+        }
+        Command::List { use_new_storage: false, container } => {
+            list(FlagSourceType::DeviceConfig, container).map(Some)
+        }
         Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None),
         Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None),
     };
@@ -262,3 +300,84 @@
         Err(message) => println!("Error: {message}"),
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_filter_container() {
+        let flags = vec![
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test1".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "system".to_string(),
+            },
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test2".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "not_system".to_string(),
+            },
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test3".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "system".to_string(),
+            },
+        ];
+
+        assert_eq!((Filter { container: Some("system".to_string()) }).apply(&flags).len(), 2);
+    }
+
+    #[test]
+    fn test_filter_no_container() {
+        let flags = vec![
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test1".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "system".to_string(),
+            },
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test2".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "not_system".to_string(),
+            },
+            Flag {
+                namespace: "namespace".to_string(),
+                name: "test3".to_string(),
+                package: "package".to_string(),
+                value: FlagValue::Disabled,
+                staged_value: None,
+                permission: FlagPermission::ReadWrite,
+                value_picked_from: ValuePickedFrom::Default,
+                container: "system".to_string(),
+            },
+        ];
+
+        assert_eq!((Filter { container: None }).apply(&flags).len(), 3);
+    }
+}
diff --git a/tools/overrideflags.sh b/tools/overrideflags.sh
deleted file mode 100755
index b8605dc..0000000
--- a/tools/overrideflags.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash -e
-# 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.
-
-
-source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../shell_utils.sh
-require_top
-
-function print_help() {
-    echo -e "overrideflags is used to set default value for local build."
-    echo -e "\nOptions:"
-    echo -e "\t--release-config  \tPath to release configuration directory. Required"
-    echo -e "\t--no-edit         \tIf present, skip editing flag value file."
-    echo -e "\t-h/--help         \tShow this help."
-}
-
-function main() {
-    while (($# > 0)); do
-        case $1 in
-        --release-config)
-            if [[ $# -le 1 ]]; then
-                echo "--release-config requires a path"
-                return 1
-            fi
-            local release_config_dir="$2"
-            shift 2
-            ;;
-        --no-edit)
-            local no_edit="true"
-            shift 1
-            ;;
-        -h|--help)
-            print_help
-            return
-            ;;
-        *)
-            echo "$1 is unrecognized"
-            print_help
-            return 1
-            ;;
-        esac
-    done
-
-
-
-    case $(uname -s) in
-        Darwin)
-            local host_arch=darwin-x86
-            ;;
-        Linux)
-            local host_arch=linux-x86
-            ;;
-        *)
-            >&2 echo Unknown host $(uname -s)
-            return
-            ;;
-    esac
-
-    if [[ -z "${release_config_dir}" ]]; then
-        echo "Please provide release configuration path by --release-config"
-        exit 1
-    elif [ ! -d "${release_config_dir}" ]; then
-        echo "${release_config_dir} is an invalid directory"
-        exit 1
-    fi
-    local T="$(gettop)"
-    local aconfig_dir="${T}"/build/make/tools/aconfig/
-    local overrideflag_py="${aconfig_dir}"/overrideflags/overrideflags.py
-    local overridefile="${release_config_dir}/aconfig/override_values.textproto"
-
-    # Edit override file
-    if [[ -z "${no_edit}" ]]; then
-        editor="${EDITOR:-$(which vim)}"
-
-        eval "${editor} ${overridefile}"
-        if [ $? -ne 0 ]; then
-            echo "Fail to set override values"
-            return 1
-        fi
-    fi
-
-    ${T}/prebuilts/build-tools/${host_arch}/bin/py3-cmd -u "${overrideflag_py}" \
-        --overrides "${overridefile}" \
-        --out "${release_config_dir}/aconfig"
-}
-
-
-main "$@"
diff --git a/tools/perf/format_benchmarks b/tools/perf/format_benchmarks
index 162c577..26493b2 100755
--- a/tools/perf/format_benchmarks
+++ b/tools/perf/format_benchmarks
@@ -188,7 +188,10 @@
         for key, column in summary["columns"]:
             for id, cell in column:
                 duration_ns = statistics.median([b["duration_ns"] for b in cell])
-                table.SetFixedCol(cell[0]["title"], [" ".join(cell[0]["modules"])])
+                modules = cell[0]["modules"]
+                if not modules:
+                    modules = ["---"]
+                table.SetFixedCol(cell[0]["title"], [" ".join(modules)])
                 table.Set(tuple([summary["date"].strftime("%Y-%m-%d"),
                                  summary["branch"],
                                  summary["tag"]]
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 432ea19..5a024ce 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -914,12 +914,13 @@
     # and install time performance. All OTA's with
     # both the source build and target build with VIRTUAL_AB_COW_VERSION = 3
     # can support the new format. Otherwise, fallback on older versions
-    if not source_info.vabc_cow_version or not target_info.vabc_cow_version:
-      logger.info("Source or Target doesn't have VABC_COW_VERSION specified, default to version 2")
-      OPTIONS.vabc_cow_version = 2
-    elif source_info.vabc_cow_version != target_info.vabc_cow_version:
-      logger.info("Source and Target have different cow VABC_COW_VERSION specified, default to minimum version")
-      OPTIONS.vabc_cow_version = min(source_info.vabc_cow_version, target_info.vabc_cow_version)
+    if not OPTIONS.vabc_cow_version:
+      if not source_info.vabc_cow_version or not target_info.vabc_cow_version:
+        logger.info("Source or Target doesn't have VABC_COW_VERSION specified, default to version 2")
+        OPTIONS.vabc_cow_version = 2
+      elif source_info.vabc_cow_version != target_info.vabc_cow_version:
+        logger.info("Source and Target have different cow VABC_COW_VERSION specified, default to minimum version")
+        OPTIONS.vabc_cow_version = min(source_info.vabc_cow_version, target_info.vabc_cow_version)
 
     # Virtual AB Compression was introduced in Androd S.
     # Later, we backported VABC to Android R. But verity support was not
@@ -933,19 +934,20 @@
     assert "ab_partitions" in OPTIONS.info_dict, \
         "META/ab_partitions.txt is required for ab_update."
     source_info = None
-    if not target_info.vabc_cow_version:
+    if not OPTIONS.vabc_cow_version:
+      if not target_info.vabc_cow_version:
+          OPTIONS.vabc_cow_version = 2
+      elif target_info.vabc_cow_version >= "3" and target_info.vendor_api_level < 35:
+        logger.warning(
+              "This full OTA is configured to use VABC cow version"
+              " 3 which is supported since"
+              " Android API level 35, but device is "
+              "launched with {} . If this full OTA is"
+              " served to a device running old build, OTA might fail due to "
+              "unsupported vabc cow version. For safety, version 2 is used because "
+              "it's supported since day 1.".format(
+                  target_info.vendor_api_level))
         OPTIONS.vabc_cow_version = 2
-    elif target_info.vabc_cow_version >= "3" and target_info.vendor_api_level < 35:
-      logger.warning(
-            "This full OTA is configured to use VABC cow version"
-            " 3 which is supported since"
-            " Android API level 35, but device is "
-            "launched with {} . If this full OTA is"
-            " served to a device running old build, OTA might fail due to "
-            "unsupported vabc cow version. For safety, version 2 is used because "
-            "it's supported since day 1.".format(
-                target_info.vendor_api_level))
-      OPTIONS.vabc_cow_version = 2
     if OPTIONS.vabc_compression_param is None and vabc_compression_param:
       minimum_api_level_required = VABC_COMPRESSION_PARAM_SUPPORT[
           vabc_compression_param]