Merge "extract_kernel: make it py2/py3 compatible"
diff --git a/core/Makefile b/core/Makefile
index 95bac40..30b6cc9 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4110,6 +4110,7 @@
   mksquashfsimage.sh \
   mkuserimg_mke2fs \
   ota_from_target_files \
+  repack_bootimg \
   sefcontext_compile \
   sgdisk \
   shflags \
@@ -5028,7 +5029,7 @@
 	@# help early validation of the .zip file while uploading it.
 	$(hide) find $(zip_root)/META | sort >$@.list
 	$(hide) find $(zip_root) -path $(zip_root)/META -prune -o -print | sort >>$@.list
-	$(hide) $(SOONG_ZIP) -d -o $@ -C $(zip_root) -l $@.list
+	$(hide) $(SOONG_ZIP) -d -o $@ -C $(zip_root) -r $@.list
 
 .PHONY: target-files-package
 target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 3a0c0f1..5b24881 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -33,7 +33,17 @@
   $(call add_soong_config_namespace,art_module)
   SOONG_CONFIG_art_module += source_build
 endif
-SOONG_CONFIG_art_module_source_build ?= true
+ifneq (,$(filter true,$(NATIVE_COVERAGE) $(CLANG_COVERAGE)))
+  # Always build ART APEXes from source in coverage builds since the prebuilts
+  # aren't built with instrumentation.
+  # TODO(b/172480617): Find another solution for this.
+  SOONG_CONFIG_art_module_source_build := true
+else
+  # This sets the default for building ART APEXes from source rather than
+  # prebuilts (in packages/modules/ArtPrebuilt and prebuilt/module_sdk/art) in
+  # all other platform builds.
+  SOONG_CONFIG_art_module_source_build ?= true
+endif
 
 # Apex build mode variables
 ifdef APEX_BUILD_FOR_PRE_S_DEVICES
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 4fd8baa..68f880f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -508,6 +508,7 @@
 ###########################################################
 
 my_init_rc_installed :=
+my_init_rc_path :=
 my_init_rc_pairs :=
 my_installed_symlinks :=
 my_default_test_module :=
@@ -534,7 +535,11 @@
 # Rule to install the module's companion init.rc.
 my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix)) $(LOCAL_INIT_RC)
 ifneq ($(strip $(my_init_rc)),)
-my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(LOCAL_PATH)/$(rc):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(rc)))
+# Make doesn't support recovery as an output partition, but some Soong modules installed in recovery
+# have init.rc files that need to be installed alongside them. Manually handle the case where the
+# output file is in the recovery partition.
+my_init_rc_path := $(if $(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)),$(TARGET_RECOVERY_ROOT_OUT)/system/etc,$(TARGET_OUT$(partition_tag)_ETC))
+my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(LOCAL_PATH)/$(rc):$(my_init_rc_path)/init/$(notdir $(rc)))
 my_init_rc_installed := $(foreach rc,$(my_init_rc_pairs),$(call word-colon,2,$(rc)))
 
 # Make sure we only set up the copy rules once, even if another arch variant
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5effac7..019892e 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -277,6 +277,7 @@
 LOCAL_SOONG_BUNDLE :=
 LOCAL_SOONG_CLASSES_JAR :=
 LOCAL_SOONG_DEX_JAR :=
+LOCAL_SOONG_DEXPREOPT_CONFIG :=
 LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=
 LOCAL_SOONG_HEADER_JAR :=
 LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=
diff --git a/core/definitions.mk b/core/definitions.mk
index 4300efe..5f0bf55 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -632,14 +632,6 @@
 endef
 
 ###########################################################
-## Convert install path to on-device path.
-###########################################################
-# $(1): install path
-define install-path-to-on-device-path
-$(patsubst $(PRODUCT_OUT)%,%,$(1))
-endef
-
-###########################################################
 ## The intermediates directory.  Where object files go for
 ## a given target.  We could technically get away without
 ## the "_intermediates" suffix on the directory, but it's
@@ -2146,6 +2138,17 @@
 $(hide) $(call commit-change-for-toc,$@)
 endef
 
+# Runs jarjar on an input file.  Jarjar doesn't exit with a nonzero return code
+# when there is a syntax error in a rules file and doesn't write the output
+# file, so removes the output file before running jarjar and check if it exists
+# after running jarjar.
+define transform-jarjar
+echo $($(PRIVATE_PREFIX)DISPLAY) JarJar: $@
+rm -f $@
+$(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+[ -e $@ ] || (echo "Missing output file"; exit 1)
+endef
+
 # Moves $1.tmp to $1 if necessary. This is designed to be used with
 # .KATI_RESTAT. For kati, this function doesn't update the timestamp
 # of $1 when $1.tmp is identical to $1 so that ninja won't rebuild
diff --git a/core/dex_preopt_config_merger.py b/core/dex_preopt_config_merger.py
new file mode 100755
index 0000000..1bd1519
--- /dev/null
+++ b/core/dex_preopt_config_merger.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2021 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.
+#
+"""
+A tool for merging dexpreopt.config files for <uses-library> dependencies into
+the dexpreopt.config file of the library/app that uses them. This is needed to
+generate class loader context (CLC) for dexpreopt.
+
+In Make there is no topological order when processing different modules, so a
+<uses-library> dependency module may have not been processed yet by the time the
+dependent module is processed. Therefore makefiles communicate the information
+from dependencies via dexpreopt.config files and add file-level dependencies
+from a module dexpreopt.config to its dependency configs. The actual patching
+of configs is done by this script, which is called from the makefiles.
+"""
+
+from __future__ import print_function
+
+import json
+from collections import OrderedDict
+import sys
+
+
+def main():
+  """Program entry point."""
+  if len(sys.argv) < 2:
+    raise SystemExit('usage: %s <main-config> [dep-config ...]' % sys.argv[0])
+
+  # Read all JSON configs.
+  cfgs = []
+  for arg in sys.argv[1:]:
+    with open(arg, 'r') as f:
+      cfgs.append(json.load(f, object_pairs_hook=OrderedDict))
+
+  # The first config is the dexpreopted library/app, the rest are its
+  # <uses-library> dependencies.
+  cfg0 = cfgs[0]
+
+  # Put dependency configs in a map keyed on module name (for easier lookup).
+  uses_libs = {}
+  for cfg in cfgs[1:]:
+    uses_libs[cfg['Name']] = cfg
+
+  # Load the original CLC map.
+  clc_map = cfg0['ClassLoaderContexts']
+
+  # Create a new CLC map that will be a copy of the original one with patched
+  # fields from dependency dexpreopt.config files.
+  clc_map2 = OrderedDict()
+
+  # Patch CLC for each SDK version. Although this should not be necessary for
+  # compatibility libraries (so-called "conditional CLC"), because they all have
+  # known names, known paths in system/framework, and no subcontext. But keep
+  # the loop in case this changes in the future.
+  for sdk_ver in clc_map:
+    clcs = clc_map[sdk_ver]
+    clcs2 = OrderedDict()
+    for lib in clcs:
+      clc = clcs[lib]
+      if lib in uses_libs:
+        ulib = uses_libs[lib]
+        # On-device (install) path to the dependency DEX jar file.
+        clc['Device'] = ulib['DexLocation']
+        # CLC of the dependency becomes a subcontext. We only need sub-CLC for
+        # 'any' version because all other versions are for compatibility
+        # libraries, which exist only for apps and not for libraries.
+        clc['Subcontexts'] = ulib['ClassLoaderContexts'].get('any')
+        # Patch the library name in the CLC as well.
+        clcs2[ulib['ProvidesUsesLibrary']] = clc
+      else:
+        # dexpreopt.config for this <uses-library> is not among the script
+        # arguments, which may be the case with compatibility libraries that
+        # don't need patching anyway. Just use the original CLC.
+        clcs2[lib] = clc
+    clc_map2[sdk_ver] = clcs2
+
+  # Overwrite the original class loader context with the patched one.
+  cfg0['ClassLoaderContexts'] = clc_map2
+
+  # Update dexpreopt.config file.
+  with open(sys.argv[1], 'w') as f:
+    f.write(json.dumps(cfgs[0], indent=4, separators=(',', ': ')))
+
+if __name__ == '__main__':
+  main()
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index b74e047..6f6ac28 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -189,24 +189,38 @@
   my_filtered_optional_uses_libraries := $(filter-out $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES), \
     $(LOCAL_OPTIONAL_USES_LIBRARIES))
 
-  # compatibility libraries are added to class loader context of an app only if
-  # targetSdkVersion in the app's manifest is lower than the given SDK version
+  # TODO(b/132357300): This may filter out too much, as PRODUCT_PACKAGES doesn't
+  # include all packages (the full list is unknown until reading all Android.mk
+  # makefiles). As a consequence, a library may be present but not included in
+  # dexpreopt, which will result in class loader context mismatch and a failure
+  # to load dexpreopt code on device. We should fix this, either by deferring
+  # dependency computation until the full list of product packages is known, or
+  # by adding product-specific lists of missing libraries.
+  my_filtered_optional_uses_libraries := $(filter $(my_filtered_optional_uses_libraries), \
+    $(PRODUCT_PACKAGES))
 
-  my_dexpreopt_libs_compat_28 := \
-    org.apache.http.legacy
+  ifeq ($(LOCAL_MODULE_CLASS),APPS)
+    # compatibility libraries are added to class loader context of an app only if
+    # targetSdkVersion in the app's manifest is lower than the given SDK version
 
-  my_dexpreopt_libs_compat_29 := \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java
+    my_dexpreopt_libs_compat_28 := \
+      org.apache.http.legacy
 
-  my_dexpreopt_libs_compat_30 := \
-    android.test.base \
-    android.test.mock
+    my_dexpreopt_libs_compat_29 := \
+      android.hidl.base-V1.0-java \
+      android.hidl.manager-V1.0-java
 
-  my_dexpreopt_libs_compat := \
-    $(my_dexpreopt_libs_compat_28) \
-    $(my_dexpreopt_libs_compat_29) \
-    $(my_dexpreopt_libs_compat_30)
+    my_dexpreopt_libs_compat_30 := \
+      android.test.base \
+      android.test.mock
+
+    my_dexpreopt_libs_compat := \
+      $(my_dexpreopt_libs_compat_28) \
+      $(my_dexpreopt_libs_compat_29) \
+      $(my_dexpreopt_libs_compat_30)
+  else
+    my_dexpreopt_libs_compat :=
+  endif
 
   my_dexpreopt_libs := $(sort \
     $(LOCAL_USES_LIBRARIES) \
@@ -215,13 +229,25 @@
 
   # 1: SDK version
   # 2: list of libraries
+  #
+  # Make does not process modules in topological order wrt. <uses-library>
+  # dependencies, therefore we cannot rely on variables to get the information
+  # about dependencies (in particular, their on-device path and class loader
+  # context). This information is communicated via dexpreopt.config files: each
+  # config depends on configs for <uses-library> dependencies of this module,
+  # and the dex_preopt_config_merger.py script reads all configs and inserts the
+  # missing bits from dependency configs into the module config.
+  #
+  # By default on-device path is /system/framework/*.jar, and class loader
+  # subcontext is empty. These values are correct for compatibility libraries,
+  # which are special and not handled by dex_preopt_config_merger.py.
+  #
   add_json_class_loader_context = \
     $(call add_json_map, $(1)) \
     $(foreach lib, $(2),\
       $(call add_json_map, $(lib)) \
-      $(eval file := $(filter %/$(lib).jar, $(call module-installed-files,$(lib)))) \
-      $(call add_json_str, Host,        $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
-      $(call add_json_str, Device,      $(call install-path-to-on-device-path,$(file))) \
+      $(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
+      $(call add_json_str, Device, /system/framework/$(lib).jar) \
       $(call add_json_map, Subcontexts, ${$}) $(call end_json_map) \
       $(call end_json_map)) \
     $(call end_json_map)
@@ -275,12 +301,27 @@
   my_dexpreopt_config := $(intermediates)/dexpreopt.config
   my_dexpreopt_script := $(intermediates)/dexpreopt.sh
   my_dexpreopt_zip := $(intermediates)/dexpreopt.zip
+  my_dexpreopt_config_merger := $(BUILD_SYSTEM)/dex_preopt_config_merger.py
 
+  # Module dexpreopt.config depends on dexpreopt.config files of each
+  # <uses-library> dependency, because these libraries may be processed after
+  # the current module by Make (there's no topological order), so the dependency
+  # information (paths, class loader context) may not be ready yet by the time
+  # this dexpreopt.config is generated. So it's necessary to add file-level
+  # dependencies between dexpreopt.config files.
+  my_dexpreopt_dep_configs := $(foreach lib, \
+    $(filter-out $(my_dexpreopt_libs_compat),$(LOCAL_USES_LIBRARIES) $(my_filtered_optional_uses_libraries)), \
+    $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,)/dexpreopt.config)
+
+  $(my_dexpreopt_config): $(my_dexpreopt_dep_configs) $(my_dexpreopt_config_merger)
   $(my_dexpreopt_config): PRIVATE_MODULE := $(LOCAL_MODULE)
   $(my_dexpreopt_config): PRIVATE_CONTENTS := $(json_contents)
+  $(my_dexpreopt_config): PRIVATE_DEP_CONFIGS := $(my_dexpreopt_dep_configs)
+  $(my_dexpreopt_config): PRIVATE_CONFIG_MERGER := $(my_dexpreopt_config_merger)
   $(my_dexpreopt_config):
 	@echo "$(PRIVATE_MODULE) dexpreopt.config"
 	echo -e -n '$(subst $(newline),\n,$(subst ','\'',$(subst \,\\,$(PRIVATE_CONTENTS))))' > $@
+	$(PRIVATE_CONFIG_MERGER) $@ $(PRIVATE_DEP_CONFIGS)
 
   .KATI_RESTAT: $(my_dexpreopt_script)
   $(my_dexpreopt_script): PRIVATE_MODULE := $(LOCAL_MODULE)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index da32978..5eeb8ac 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -125,8 +125,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_header_jarjar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_header_jarjar): $(full_classes_turbine_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo Header JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_header_jarjar := $(full_classes_turbine_jar)
 endif
@@ -149,8 +148,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_combined_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_combined_jar)
 endif
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index f9abe9b..0f95202 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -113,8 +113,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_combined_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_combined_jar)
 endif
diff --git a/core/java.mk b/core/java.mk
index 5fe8da5..d28c0c4 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -253,8 +253,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_header_jarjar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_header_jarjar): $(full_classes_turbine_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo Header JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_header_jarjar := $(full_classes_turbine_jar)
 endif
@@ -334,8 +333,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_processed_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_processed_jar)
 endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index fde5832..fd8d3e4 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -159,7 +159,6 @@
 $(call add_json_bool, Check_elf_files,                   $(filter true,$(PRODUCT_CHECK_ELF_FILES)))
 
 $(call add_json_bool, Uml,                               $(filter true,$(TARGET_USER_MODE_LINUX)))
-$(call add_json_bool, Use_lmkd_stats_log,                $(filter true,$(TARGET_LMKD_STATS_LOG)))
 $(call add_json_str,  VendorPath,                        $(TARGET_COPY_OUT_VENDOR))
 $(call add_json_str,  OdmPath,                           $(TARGET_COPY_OUT_ODM))
 $(call add_json_str,  VendorDlkmPath,                    $(TARGET_COPY_OUT_VENDOR_DLKM))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 5444d96..c600178 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -5,6 +5,7 @@
 # LOCAL_SOONG_HEADER_JAR
 # LOCAL_SOONG_DEX_JAR
 # LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
+# LOCAL_SOONG_DEXPREOPT_CONFIG
 
 ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
   $(call pretty-error,soong_java_prebuilt.mk may only be used from Soong)
@@ -146,6 +147,12 @@
   ALL_MODULES.$(my_register_name).AAR := $(LOCAL_SOONG_AAR)
 endif
 
+# Copy dexpreopt.config files from Soong libraries to the location where Make
+# modules can find them.
+ifdef LOCAL_SOONG_DEXPREOPT_CONFIG
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_DEXPREOPT_CONFIG), $(call local-intermediates-dir,)/dexpreopt.config))
+endif
+
 javac-check : $(full_classes_jar)
 javac-check-$(LOCAL_MODULE) : $(full_classes_jar)
 .PHONY: javac-check-$(LOCAL_MODULE)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index fe90165..0c91a14 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -240,7 +240,7 @@
     #  It must be of the form "YYYY-MM-DD" on production devices.
     #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-      PLATFORM_SECURITY_PATCH := 2021-01-05
+      PLATFORM_SECURITY_PATCH := 2021-02-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/target/board/module_arm64/device.mk b/target/board/module_arm64/device.mk
deleted file mode 100644
index 0d4c543..0000000
--- a/target/board/module_arm64/device.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/core_64_bit.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/board/module_x86/device.mk b/target/board/module_x86/device.mk
deleted file mode 100644
index cceb987..0000000
--- a/target/board/module_x86/device.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/board/module_x86_64/device.mk b/target/board/module_x86_64/device.mk
deleted file mode 100644
index 0d4c543..0000000
--- a/target/board/module_x86_64/device.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/core_64_bit.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index c7ae1f0..5238d40 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -400,4 +400,8 @@
 PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
     frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
 
+# This property allows enabling Keystore 2.0 selectively for testing.
+# TODO Remove when Keystore 2.0 migration is complete. b/171563717
+PRODUCT_SYSTEM_PROPERTIES += persist.android.security.keystore2.enable=false
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 2c74ce0..25716ce 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -34,6 +34,9 @@
 # Split selinux policy
 PRODUCT_FULL_TREBLE_OVERRIDE := true
 
+# Enable dynamic partitions to facilitate mixing onto Cuttlefish
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
diff --git a/target/product/module_arm.mk b/target/product/module_arm.mk
index 09ccf5f..d99dce8 100644
--- a/target/product/module_arm.mk
+++ b/target/product/module_arm.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_arm/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_arm
 PRODUCT_BRAND := Android
diff --git a/target/product/module_arm64.mk b/target/product/module_arm64.mk
index 468c9db..fc9529c 100644
--- a/target/product/module_arm64.mk
+++ b/target/product/module_arm64.mk
@@ -14,7 +14,8 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_arm64/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_arm64
 PRODUCT_BRAND := Android
diff --git a/target/board/module_arm/device.mk b/target/product/module_common.mk
similarity index 75%
rename from target/board/module_arm/device.mk
rename to target/product/module_common.mk
index cceb987..eedd479 100644
--- a/target/board/module_arm/device.mk
+++ b/target/product/module_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2020 The Android Open Source Project
+# Copyright (C) 2021 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.
@@ -14,5 +14,5 @@
 # limitations under the License.
 #
 
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
diff --git a/target/product/module_x86.mk b/target/product/module_x86.mk
index dec4aed..b852e7a 100644
--- a/target/product/module_x86.mk
+++ b/target/product/module_x86.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_x86
 PRODUCT_BRAND := Android
diff --git a/target/product/module_x86_64.mk b/target/product/module_x86_64.mk
index 5fabade..f6bc1fc 100644
--- a/target/product/module_x86_64.mk
+++ b/target/product/module_x86_64.mk
@@ -14,7 +14,8 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_x86_64/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_x86_64
 PRODUCT_BRAND := Android
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 473d854..2429f17 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -282,6 +282,7 @@
         "boot_signer",
         "brotli",
         "bsdiff",
+        "deapexer",
         "imgdiff",
         "minigzip",
         "lz4",
@@ -590,6 +591,7 @@
     name: "releasetools_py3_test",
     defaults: ["releasetools_test_defaults"],
     main: "test_utils.py",
+    test_suites: ["general-tests"],
     version: {
         py2: {
             enabled: false,
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 3177fa0..644b92a 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -545,7 +545,7 @@
     debugfs_path = os.path.join(OPTIONS.search_path, "bin", "debugfs_static")
   deapexer = 'deapexer'
   if OPTIONS.search_path:
-    deapexer_path = os.path.join(OPTIONS.search_path, "deapexer")
+    deapexer_path = os.path.join(OPTIONS.search_path, "bin", "deapexer")
     if os.path.isfile(deapexer_path):
       deapexer = deapexer_path
   for apex_filename in os.listdir(target_dir):