Enable puffin in update_engine

Call the approximate functions to set up the deflates of a zip archive
file. This effectively enables puffdiff when generating an a/b
update package.

Test: Unittests pass. Generate and verify a package on sailfish
Change-Id: Id025c42529b8b9547d4c7d7ac57898450bc6a1c1
diff --git a/Android.mk b/Android.mk
index aa9fb6b..5a3129e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -616,6 +616,7 @@
     liblzma \
     libpayload_consumer \
     libpuffdiff \
+    libz \
     update_metadata-protos \
     $(ue_libpayload_consumer_exported_static_libraries) \
     $(ue_update_metadata_protos_exported_static_libraries)
diff --git a/payload_generator/deflate_utils.cc b/payload_generator/deflate_utils.cc
index 88e42e0..060acbc 100644
--- a/payload_generator/deflate_utils.cc
+++ b/payload_generator/deflate_utils.cc
@@ -255,7 +255,7 @@
   part.fs_interface->GetFiles(&tmp_files);
   result_files->reserve(tmp_files.size());
 
-  for (const auto& file : tmp_files) {
+  for (auto& file : tmp_files) {
     if (IsSquashfsImage(part.path, file)) {
       // Read the image into a file.
       base::FilePath path;
@@ -285,7 +285,34 @@
                      << " was a Squashfs file, but it was not.";
       }
     }
-    // TODO(ahassani): Process other types of files like apk, zip, etc.
+
+    // Search for deflates if the file is in zip format.
+    bool is_zip =
+        base::EndsWith(
+            file.name, ".apk", base::CompareCase::INSENSITIVE_ASCII) ||
+        base::EndsWith(
+            file.name, ".zip", base::CompareCase::INSENSITIVE_ASCII) ||
+        base::EndsWith(file.name, ".jar", base::CompareCase::INSENSITIVE_ASCII);
+
+    if (is_zip) {
+      brillo::Blob data;
+      TEST_AND_RETURN_FALSE(
+          utils::ReadExtents(part.path,
+                             file.extents,
+                             &data,
+                             kBlockSize * utils::BlocksInExtents(file.extents),
+                             kBlockSize));
+      std::vector<puffin::BitExtent> deflates_sub_blocks;
+      TEST_AND_RETURN_FALSE(puffin::LocateDeflateSubBlocksInZipArchive(
+          data, &deflates_sub_blocks));
+      // Shift the deflate's extent to the offset starting from the beginning
+      // of the current partition; and the delta processor will align the
+      // extents in a continuous buffer later.
+      TEST_AND_RETURN_FALSE(
+          ShiftBitExtentsOverExtents(file.extents, &deflates_sub_blocks));
+      file.deflates = std::move(deflates_sub_blocks);
+    }
+
     result_files->push_back(file);
   }
   return true;