Merge "Remove module-lib and system-server from TARGET_AVAILABLE_SDK_VERSIONS"
diff --git a/banchanHelp.sh b/banchanHelp.sh
index af7294c..eab22e4 100755
--- a/banchanHelp.sh
+++ b/banchanHelp.sh
@@ -6,7 +6,7 @@
 cd ../..
 TOP="${PWD}"
 
-message='usage: banchan <module> ... [arm|x86|arm64|x86_64] [eng|userdebug|user]
+message='usage: banchan <module> ... [<product>|arm|x86|arm64|x86_64] [eng|userdebug|user]
 
 banchan selects individual APEX modules to be built by the Android build system.
 Like "tapas", "banchan" does not request the building of images for a device but
@@ -19,6 +19,11 @@
 The module names should match apex{} modules in Android.bp files, typically
 starting with "com.android.".
 
+The product argument should be a product name ending in "_<arch>", where <arch>
+is one of arm, x86, arm64, x86_64. It can also be just an arch, in which case
+the standard product for building modules with that architecture is used, i.e.
+module_<arch>.
+
 The usage of the other arguments matches that of the rest of the platform
 build system and can be found by running `m help`'
 
diff --git a/core/base_rules.mk b/core/base_rules.mk
index c973997..a42d702 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -1005,7 +1005,9 @@
 ifndef LOCAL_IS_HOST_MODULE
 ALL_MODULES.$(my_register_name).FILE_CONTEXTS := $(LOCAL_FILE_CONTEXTS)
 endif
+ifdef LOCAL_IS_UNIT_TEST
 ALL_MODULES.$(my_register_name).IS_UNIT_TEST := $(LOCAL_IS_UNIT_TEST)
+endif
 test_config :=
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index f9042c2..90f00c0 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -115,20 +115,18 @@
   my_sanitize_diag :=
 endif
 
-# Enable CFI in included paths (for Arm64 only).
+# Enable CFI in included paths.
 ifeq ($(filter cfi, $(my_sanitize)),)
-  ifneq ($(filter arm64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
-    combined_include_paths := $(CFI_INCLUDE_PATHS) \
-                              $(PRODUCT_CFI_INCLUDE_PATHS)
-    combined_exclude_paths := $(CFI_EXCLUDE_PATHS) \
-                              $(PRODUCT_CFI_EXCLUDE_PATHS)
+  combined_include_paths := $(CFI_INCLUDE_PATHS) \
+                            $(PRODUCT_CFI_INCLUDE_PATHS)
+  combined_exclude_paths := $(CFI_EXCLUDE_PATHS) \
+                            $(PRODUCT_CFI_EXCLUDE_PATHS)
 
-    ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_include_paths)),\
-           $(filter $(dir)%,$(LOCAL_PATH)))),)
-      ifeq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
-           $(filter $(dir)%,$(LOCAL_PATH)))),)
-        my_sanitize := cfi $(my_sanitize)
-      endif
+  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_include_paths)),\
+         $(filter $(dir)%,$(LOCAL_PATH)))),)
+    ifeq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
+         $(filter $(dir)%,$(LOCAL_PATH)))),)
+      my_sanitize := cfi $(my_sanitize)
     endif
   endif
 endif
diff --git a/core/main.mk b/core/main.mk
index 1e9a95f..05203bb 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -293,7 +293,7 @@
 ifneq ($(TARGET_BUILD_VARIANT),user)
   ifdef PRODUCT_SET_DEBUGFS_RESTRICTIONS
     ADDITIONAL_VENDOR_PROPERTIES += \
-      ro.product.enforce_debugfs_restrictions=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS)
+      ro.product.debugfs_restrictions.enabled=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS)
   endif
 endif
 
@@ -914,7 +914,7 @@
 # Scan all modules in general-tests, device-tests and other selected suites and
 # flatten the shared library dependencies.
 define update-host-shared-libs-deps-for-suites
-$(foreach suite,general-tests device-tests vts art-host-tests host-unit-tests,\
+$(foreach suite,general-tests device-tests vts tvts art-host-tests host-unit-tests,\
   $(foreach m,$(COMPATIBILITY.$(suite).MODULES),\
     $(eval my_deps := $(call get-all-shared-libs-deps,$(m)))\
     $(foreach dep,$(my_deps),\
diff --git a/envsetup.sh b/envsetup.sh
index f4e5f4e..a2f7227 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -111,7 +111,7 @@
     if [ "$BUILD_VAR_CACHE_READY" = "true" ]
     then
         eval "echo \"\${abs_var_cache_$1}\""
-    return
+        return
     fi
 
     local T=$(gettop)
@@ -799,17 +799,19 @@
 function banchan()
 {
     local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)"
-    local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|arm64|x86_64)$' | xargs)"
+    local product="$(echo $* | xargs -n 1 echo | \grep -E '^(.*_)?(arm|x86|arm64|x86_64)$' | xargs)"
     local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
-    local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|arm64|x86_64)$' | xargs)"
+    local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|(.*_)?(arm|x86|arm64|x86_64))$' | xargs)"
 
     if [ "$showHelp" != "" ]; then
       $(gettop)/build/make/banchanHelp.sh
       return
     fi
 
-    if [ $(echo $arch | wc -w) -gt 1 ]; then
-        echo "banchan: Error: Multiple build archs supplied: $arch"
+    if [ -z "$product" ]; then
+        product=arm
+    elif [ $(echo $product | wc -w) -gt 1 ]; then
+        echo "banchan: Error: Multiple build archs or products supplied: $products"
         return
     fi
     if [ $(echo $variant | wc -w) -gt 1 ]; then
@@ -821,8 +823,8 @@
         return
     fi
 
-    local product=module_arm
-    case $arch in
+    case $product in
+      arm)    product=module_arm;;
       x86)    product=module_x86;;
       arm64)  product=module_arm64;;
       x86_64) product=module_x86_64;;
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index eedd479..03340db 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -16,3 +16,8 @@
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/cfi-common.mk)
+
+# Enables treble, which enabled certain -D compilation flags. In particular, libhidlbase
+# uses -DENFORCE_VINTF_MANIFEST. See b/185759877
+PRODUCT_SHIPPING_API_LEVEL := 29
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index a56c305..00bbb21 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -62,7 +62,7 @@
 import verity_utils
 import ota_metadata_pb2
 
-from apex_utils import GetSystemApexInfoFromTargetFiles
+from apex_utils import GetApexInfoFromTargetFiles
 from common import AddCareMapForAbOta
 
 if sys.hexversion < 0x02070000:
@@ -686,7 +686,7 @@
                            "{}.img".format(partition_name))))
 
 def AddApexInfo(output_zip):
-  apex_infos = GetSystemApexInfoFromTargetFiles(OPTIONS.input_tmp)
+  apex_infos = GetApexInfoFromTargetFiles(OPTIONS.input_tmp, 'system')
   apex_metadata_proto = ota_metadata_pb2.ApexMetadata()
   apex_metadata_proto.apex_info.extend(apex_infos)
   apex_info_bytes = apex_metadata_proto.SerializeToString()
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 1c88053..893266f 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -516,7 +516,7 @@
     raise ApexInfoError(
         'Failed to get type for {}:\n{}'.format(apex_file, e))
 
-def GetSystemApexInfoFromTargetFiles(input_file):
+def GetApexInfoFromTargetFiles(input_file, partition, compressed_only=True):
   """
   Get information about system APEX stored in the input_file zip
 
@@ -532,15 +532,17 @@
   if not isinstance(input_file, str):
     raise RuntimeError("must pass filepath to target-files zip or directory")
 
+  apex_subdir = os.path.join(partition.upper(), 'apex')
   if os.path.isdir(input_file):
     tmp_dir = input_file
   else:
-    tmp_dir = UnzipTemp(input_file, ["SYSTEM/apex/*"])
-  target_dir = os.path.join(tmp_dir, "SYSTEM/apex/")
+    tmp_dir = UnzipTemp(input_file, [os.path.join(apex_subdir, '*')])
+  target_dir = os.path.join(tmp_dir, apex_subdir)
 
   # Partial target-files packages for vendor-only builds may not contain
   # a system apex directory.
   if not os.path.exists(target_dir):
+    logger.info('No APEX directory at path: %s', target_dir)
     return []
 
   apex_infos = []
@@ -585,6 +587,7 @@
                          '--output', decompressed_file_path])
       apex_info.decompressed_size = os.path.getsize(decompressed_file_path)
 
+    if not compressed_only or apex_info.is_compressed:
       apex_infos.append(apex_info)
 
   return apex_infos
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index 17d3030..5e6c42d 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -96,6 +96,7 @@
 from xml.etree import ElementTree
 
 import add_img_to_target_files
+import apex_utils
 import build_image
 import build_super_image
 import check_target_files_vintf
@@ -739,6 +740,35 @@
   return cmd
 
 
+def validate_merged_apex_info(output_target_files_dir, partitions):
+  """Validates the APEX files in the merged target files directory.
+
+  Checks the APEX files in all possible preinstalled APEX directories.
+  Depends on the <partition>/apex/* APEX files within partitions.
+
+  Args:
+    output_target_files_dir: Output directory containing merged partition directories.
+    partitions: A list of all the partitions in the output directory.
+
+  Raises:
+    RuntimeError: if apex_utils fails to parse any APEX file.
+    ExternalError: if the same APEX package is provided by multiple partitions.
+  """
+  apex_packages = set()
+
+  apex_partitions = ('system', 'system_ext', 'product', 'vendor')
+  for partition in filter(lambda p: p in apex_partitions, partitions):
+    apex_info = apex_utils.GetApexInfoFromTargetFiles(
+        output_target_files_dir, partition, compressed_only=False)
+    partition_apex_packages = set([info.package_name for info in apex_info])
+    duplicates = apex_packages.intersection(partition_apex_packages)
+    if duplicates:
+      raise ExternalError(
+          'Duplicate APEX packages found in multiple partitions: %s' %
+          ' '.join(duplicates))
+    apex_packages.update(partition_apex_packages)
+
+
 def generate_care_map(partitions, output_target_files_dir):
   """Generates a merged META/care_map.pb file in the output target files dir.
 
@@ -1116,6 +1146,9 @@
   common.RunAndCheckOutput(split_sepolicy_cmd)
   # TODO(b/178864050): Run tests on the combined.policy file.
 
+  # Run validation checks on the pre-installed APEX files.
+  validate_merged_apex_info(output_target_files_temp_dir, partition_map.keys())
+
   generate_images(output_target_files_temp_dir, rebuild_recovery)
 
   generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 072bb01..4f61472 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -15,6 +15,7 @@
 #
 
 import os.path
+import shutil
 
 import common
 import test_utils
@@ -22,7 +23,7 @@
     validate_config_lists, DEFAULT_FRAMEWORK_ITEM_LIST,
     DEFAULT_VENDOR_ITEM_LIST, DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
     item_list_to_partition_set, process_apex_keys_apk_certs_common,
-    compile_split_sepolicy)
+    compile_split_sepolicy, validate_merged_apex_info)
 
 
 class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
@@ -274,3 +275,36 @@
                       '{OTP}/vendor/etc/selinux/plat_pub_versioned.cil '
                       '{OTP}/product/etc/selinux/mapping/30.0.cil').format(
                           OTP=product_out_dir))
+
+  def _copy_apex(self, source, output_dir, partition):
+    shutil.copy(
+        source,
+        os.path.join(output_dir, partition, 'apex', os.path.basename(source)))
+
+  @test_utils.SkipIfExternalToolsUnavailable()
+  def test_validate_merged_apex_info(self):
+    output_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(output_dir, 'SYSTEM/apex'))
+    os.makedirs(os.path.join(output_dir, 'VENDOR/apex'))
+
+    self._copy_apex(
+        os.path.join(self.testdata_dir, 'has_apk.apex'), output_dir, 'SYSTEM')
+    self._copy_apex(
+        os.path.join(test_utils.get_current_dir(),
+                     'com.android.apex.compressed.v1.capex'), output_dir,
+        'VENDOR')
+    validate_merged_apex_info(output_dir, ('system', 'vendor'))
+
+  @test_utils.SkipIfExternalToolsUnavailable()
+  def test_validate_merged_apex_info_RaisesOnPackageInMultiplePartitions(self):
+    output_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(output_dir, 'SYSTEM/apex'))
+    os.makedirs(os.path.join(output_dir, 'VENDOR/apex'))
+
+    same_apex_package = os.path.join(self.testdata_dir, 'has_apk.apex')
+    self._copy_apex(same_apex_package, output_dir, 'SYSTEM')
+    self._copy_apex(same_apex_package, output_dir, 'VENDOR')
+    self.assertRaisesRegexp(
+        common.ExternalError,
+        'Duplicate APEX packages found in multiple partitions: com.android.wifi',
+        validate_merged_apex_info, output_dir, ('system', 'vendor'))
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 9f64849..661712a 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -33,7 +33,7 @@
     GetTargetFilesZipWithoutPostinstallConfig,
     Payload, PayloadSigner, POSTINSTALL_CONFIG,
     StreamingPropertyFiles, AB_PARTITIONS)
-from apex_utils import GetSystemApexInfoFromTargetFiles
+from apex_utils import GetApexInfoFromTargetFiles
 from test_utils import PropertyFilesTestCase
 
 
@@ -281,9 +281,9 @@
         metadata)
 
   @test_utils.SkipIfExternalToolsUnavailable()
-  def test_GetSystemApexInfoFromTargetFiles(self):
+  def test_GetApexInfoFromTargetFiles(self):
     target_files = construct_target_files(compressedApex=True)
-    apex_infos = GetSystemApexInfoFromTargetFiles(target_files)
+    apex_infos = GetApexInfoFromTargetFiles(target_files, 'system')
     self.assertEqual(len(apex_infos), 1)
     self.assertEqual(apex_infos[0].package_name, "com.android.apex.compressed")
     self.assertEqual(apex_infos[0].version, 1)