Merge cherrypicks of [4562103, 4560827, 4563998, 4563999, 4564000, 4564001, 4564351, 4564352, 4564333, 4564033, 4560455, 4564034, 4560674, 4560675, 4563620, 4561607, 4561062, 4561063] into pi-release

Change-Id: I1014418092b886985dce80e21e3a15cbcc51d894
diff --git a/testcases/host/verify_dtbo/VtsFirmwareDtboVerification.py b/testcases/host/verify_dtbo/VtsFirmwareDtboVerification.py
index 47ed998..2ae0f57 100644
--- a/testcases/host/verify_dtbo/VtsFirmwareDtboVerification.py
+++ b/testcases/host/verify_dtbo/VtsFirmwareDtboVerification.py
@@ -19,8 +19,10 @@
 import logging
 import os
 import shutil
+import struct
 import subprocess
 import tempfile
+import zlib
 
 from vts.runners.host import asserts
 from vts.runners.host import base_test
@@ -34,6 +36,20 @@
 DEVICE_TEMP_DIR = "/data/local/tmp/"  # temporary dir in device.
 FDT_PATH = "/sys/firmware/fdt"  # path to device tree.
 PROPERTY_SLOT_SUFFIX = "ro.boot.slot_suffix"  # indicates current slot suffix for A/B devices
+DTBO_HEADER_SIZE = 32  # size of dtbo header
+DT_HEADER_FLAGS_OFFSET = 16  # offset in DT header to read compression info
+COMPRESSION_FLAGS_BIT_MASK = 0x0f  # Bit mask to get compression format from flags field of DT
+                                   # header for version 1 DTBO header.
+DECOMPRESS_WBIT_ARG = 47  # Automatically accepts either the zlib or gzip format.
+FDT_MAGIC = 0xd00dfeed  # FDT Magic
+
+
+class CompressionFormat(object):
+    """Enum representing DT compression format for a DT entry.
+    """
+    NO_COMPRESSION = 0x00
+    ZLIB_COMPRESSION = 0x01
+    GZIP_COMPRESSION = 0x02
 
 
 class VtsFirmwareDtboVerification(base_test.BaseTestClass):
@@ -59,6 +75,41 @@
         """Checks if the the preconditions to run the test are met."""
         asserts.skipIf("x86" in self.dut.cpu_abi, "Skipping test for x86 ABI")
 
+    def DecompressDTEntries(self, host_dtbo_image, unpacked_dtbo_path):
+        """Decompresses DT entries based on the flag field in the DT Entry header.
+
+        Args:
+            host_dtbo_image: Path to the DTBO image on host.
+            unpacked_dtbo_path: Path where DTBO was unpacked.
+        """
+
+        with open(host_dtbo_image, "rb") as file_in:
+            buf = file_in.read(DTBO_HEADER_SIZE)
+            (magic, total_size, header_size, dt_entry_size, dt_entry_count,
+             dt_entries_offset, page_size, version) = struct.unpack_from(">8I", buf, 0)
+            if version > 0:
+                for dt_entry_idx in range(dt_entry_count):
+                    file_in.seek(dt_entries_offset +
+                                 DT_HEADER_FLAGS_OFFSET)
+                    dt_entries_offset += dt_entry_size
+                    flags = struct.unpack(">I", file_in.read(1 * 4))[0]
+                    compression_format = flags & COMPRESSION_FLAGS_BIT_MASK
+                    if (compression_format not in [CompressionFormat.ZLIB_COMPRESSION,
+                                                   CompressionFormat.GZIP_COMPRESSION]):
+                        asserts.assertEqual(compression_format, CompressionFormat.NO_COMPRESSION,
+                                            "Unknown compression format %d" % compression_format)
+                        continue
+                    dt_entry_path = "%s.%s" % (unpacked_dtbo_path, dt_entry_idx)
+                    logging.info("decompressing %s", dt_entry_path)
+                    with open(dt_entry_path, "rb") as f:
+                        unzipped_dtbo_file = zlib.decompress(f.read(), DECOMPRESS_WBIT_ARG)
+                    with open(dt_entry_path, "r+b") as f:
+                        f.write(unzipped_dtbo_file)
+                        f.seek(0)
+                        fdt_magic = struct.unpack(">I", f.read(1 * 4))[0]
+                        asserts.assertEqual(fdt_magic, FDT_MAGIC,
+                                            "Bad FDT(Flattened Device Tree) Format")
+
     def testCheckDTBOPartition(self):
         """Validates DTBO partition using mkdtboimg.py."""
         try:
@@ -87,6 +138,8 @@
             logging.exception(e)
             logging.error('dtbo_dump_cmd is: %s', dtbo_dump_cmd)
             asserts.fail("Invalid DTBO Image")
+        # TODO(b/109892148) Delete code below once decompress option is enabled for mkdtboimg.py
+        self.DecompressDTEntries(host_dtbo_image, unpacked_dtbo_path)
 
     def testVerifyOverlay(self):
         """Verifies application of DT overlays."""