Merge "docker: update sha256sum for repo version 1.25"
diff --git a/core/Makefile b/core/Makefile
index 0ccd719..78ef81f 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -3445,7 +3445,7 @@
   build_ota_package := false
   build_otatools_package := false
 else
-  # set build_ota_package, and allow opt-out below
+  # Set build_ota_package, and allow opt-out below.
   build_ota_package := true
   ifeq ($(TARGET_SKIP_OTA_PACKAGE),true)
     build_ota_package := false
@@ -3456,20 +3456,22 @@
   ifeq ($(TARGET_PRODUCT),sdk)
     build_ota_package := false
   endif
-  ifneq ($(filter generic%,$(TARGET_DEVICE)),)
-    build_ota_package := false
-  endif
-  ifeq ($(TARGET_NO_KERNEL),true)
-    build_ota_package := false
-  endif
-  ifeq ($(recovery_fstab),)
-    build_ota_package := false
-  endif
   ifeq ($(TARGET_BUILD_PDK),true)
     build_ota_package := false
   endif
+  ifneq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+    ifneq ($(filter generic%,$(TARGET_DEVICE)),)
+      build_ota_package := false
+    endif
+    ifeq ($(TARGET_NO_KERNEL),true)
+      build_ota_package := false
+    endif
+    ifeq ($(recovery_fstab),)
+      build_ota_package := false
+    endif
+  endif # PRODUCT_BUILD_GENERIC_OTA_PACKAGE
 
-  # set build_otatools_package, and allow opt-out below
+  # Set build_otatools_package, and allow opt-out below.
   build_otatools_package := true
   ifeq ($(TARGET_SKIP_OTATOOLS_PACKAGE),true)
     build_otatools_package := false
@@ -3925,6 +3927,9 @@
 	$(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "blockimgdiff_versions=3,4" >> $(zip_root)/META/misc_info.txt
+ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+	$(hide) echo "build_generic_ota_package=true" >> $(zip_root)/META/misc_info.txt
+endif
 ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
 	# OTA scripts are only interested in fingerprint related properties
 	$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
diff --git a/core/board_config.mk b/core/board_config.mk
index 6f04fb3..9ea3509 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -475,6 +475,13 @@
   endif
 endif
 
+# Sanity check for building generic OTA packages. Currently it only supports A/B OTAs.
+ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+  ifneq ($(AB_OTA_UPDATER),true)
+    $(error PRODUCT_BUILD_GENERIC_OTA_PACKAGE with 'AB_OTA_UPDATER != true' is not supported)
+  endif
+endif
+
 # Check BOARD_VNDK_VERSION
 define check_vndk_version
   $(eval vndk_path := prebuilts/vndk/v$(1)) \
diff --git a/core/product.mk b/core/product.mk
index 29bd1d1..777d2bc 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -322,6 +322,11 @@
 # set this variable to prevent OTA failures.
 _product_var_list += PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
 
+# If set to true, this product builds a generic OTA package, which installs generic system images
+# onto matching devices. The product may only build a subset of system images (e.g. only
+# system.img), so devices need to install the package in a system-only OTA manner.
+_product_var_list += PRODUCT_BUILD_GENERIC_OTA_PACKAGE
+
 # Whether any paths are excluded from being set XOM when ENABLE_XOM=true
 _product_var_list += PRODUCT_XOM_EXCLUDE_PATHS
 _product_var_list += PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 632c1e2..171c794 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -834,7 +834,7 @@
   reconstructed from the block list, for whom we should avoid applying imgdiff.
 
   Args:
-    which: The partition name, which must be "system" or "vendor".
+    which: The partition name, e.g. "system", "vendor".
     tmpdir: The directory that contains the prebuilt image and block map file.
     input_zip: The target-files ZIP archive.
     allow_shared_blocks: Whether having shared blocks is allowed.
@@ -843,8 +843,6 @@
   Returns:
     A SparseImage object, with file_map info loaded.
   """
-  assert which in ("system", "vendor")
-
   path = os.path.join(tmpdir, "IMAGES", which + ".img")
   mappath = os.path.join(tmpdir, "IMAGES", which + ".map")
 
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 9e36c78..89add40 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -641,11 +641,13 @@
         },
         sparse_image.file_map)
 
-  def test_GetSparseImage_invalidImageName(self):
+  def test_GetSparseImage_missingImageFile(self):
     self.assertRaises(
-        AssertionError, common.GetSparseImage, 'system2', None, None, False)
+        AssertionError, common.GetSparseImage, 'system2', self.testdata_dir,
+        None, False)
     self.assertRaises(
-        AssertionError, common.GetSparseImage, 'unknown', None, None, False)
+        AssertionError, common.GetSparseImage, 'unknown', self.testdata_dir,
+        None, False)
 
   def test_GetSparseImage_missingBlockMapFile(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')