[incfs] Stream the hash tree for incremental installation

Instead of sending the whole tree upfront use the same
streaming interface for it as for the data blocks

This improves installation speed by almost 200ms,
650-800ms -> 500-600ms

Bug: 153696423
Test: manual, adb install in various configurations

Change-Id: Ia83de2af54ca0b1969397514ea5d761719af9055
Merged-In: Ia83de2af54ca0b1969397514ea5d761719af9055
diff --git a/adb/client/incremental.cpp b/adb/client/incremental.cpp
index 9765292..2814932 100644
--- a/adb/client/incremental.cpp
+++ b/adb/client/incremental.cpp
@@ -16,13 +16,13 @@
 
 #include "incremental.h"
 
-#include <android-base/endian.h>
+#include "incremental_utils.h"
+
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <openssl/base64.h>
 
 #include "adb_client.h"
-#include "adb_io.h"
 #include "adb_utils.h"
 #include "commandline.h"
 #include "sysdeps.h"
@@ -31,65 +31,8 @@
 
 namespace incremental {
 
-namespace {
-
-static constexpr auto IDSIG = ".idsig"sv;
-
 using android::base::StringPrintf;
 
-using Size = int64_t;
-
-static inline int32_t read_int32(borrowed_fd fd) {
-    int32_t result;
-    return ReadFdExactly(fd, &result, sizeof(result)) ? result : -1;
-}
-
-static inline void append_int(borrowed_fd fd, std::vector<char>* bytes) {
-    int32_t le_val = read_int32(fd);
-    auto old_size = bytes->size();
-    bytes->resize(old_size + sizeof(le_val));
-    memcpy(bytes->data() + old_size, &le_val, sizeof(le_val));
-}
-
-static inline void append_bytes_with_size(borrowed_fd fd, std::vector<char>* bytes) {
-    int32_t le_size = read_int32(fd);
-    if (le_size < 0) {
-        return;
-    }
-    int32_t size = int32_t(le32toh(le_size));
-    auto old_size = bytes->size();
-    bytes->resize(old_size + sizeof(le_size) + size);
-    memcpy(bytes->data() + old_size, &le_size, sizeof(le_size));
-    ReadFdExactly(fd, bytes->data() + old_size + sizeof(le_size), size);
-}
-
-static inline std::pair<std::vector<char>, int32_t> read_id_sig_headers(borrowed_fd fd) {
-    std::vector<char> result;
-    append_int(fd, &result);              // version
-    append_bytes_with_size(fd, &result);  // hashingInfo
-    append_bytes_with_size(fd, &result);  // signingInfo
-    auto le_tree_size = read_int32(fd);
-    auto tree_size = int32_t(le32toh(le_tree_size));  // size of the verity tree
-    return {std::move(result), tree_size};
-}
-
-static inline Size verity_tree_size_for_file(Size fileSize) {
-    constexpr int INCFS_DATA_FILE_BLOCK_SIZE = 4096;
-    constexpr int SHA256_DIGEST_SIZE = 32;
-    constexpr int digest_size = SHA256_DIGEST_SIZE;
-    constexpr int hash_per_block = INCFS_DATA_FILE_BLOCK_SIZE / digest_size;
-
-    Size total_tree_block_count = 0;
-
-    auto block_count = 1 + (fileSize - 1) / INCFS_DATA_FILE_BLOCK_SIZE;
-    auto hash_block_count = block_count;
-    for (auto i = 0; hash_block_count > 1; i++) {
-        hash_block_count = (hash_block_count + hash_per_block - 1) / hash_per_block;
-        total_tree_block_count += hash_block_count;
-    }
-    return total_tree_block_count * INCFS_DATA_FILE_BLOCK_SIZE;
-}
-
 // Read, verify and return the signature bytes. Keeping fd at the position of start of verity tree.
 static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
                                                               std::string signature_file,
@@ -104,7 +47,7 @@
         return {};
     }
 
-    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY | O_CLOEXEC));
+    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY));
     if (fd < 0) {
         if (!silent) {
             fprintf(stderr, "Failed to open signature file: %s. Abort.\n", signature_file.c_str());
@@ -172,9 +115,8 @@
             return {};
         }
 
-        auto file_desc =
-                StringPrintf("%s:%lld:%s:%s", android::base::Basename(file).c_str(),
-                             (long long)st.st_size, std::to_string(i).c_str(), signature.c_str());
+        auto file_desc = StringPrintf("%s:%lld:%d:%s:1", android::base::Basename(file).c_str(),
+                                      (long long)st.st_size, i, signature.c_str());
         command_args.push_back(std::move(file_desc));
 
         signature_fds.push_back(std::move(signature_fd));
@@ -190,21 +132,9 @@
         return {};
     }
 
-    // Pushing verity trees for all installation files.
-    for (auto&& local_fd : signature_fds) {
-        if (!copy_to_file(local_fd.get(), connection_fd.get())) {
-            if (!silent) {
-                fprintf(stderr, "Failed to stream tree bytes: %s. Abort.\n", strerror(errno));
-            }
-            return {};
-        }
-    }
-
     return connection_fd;
 }
 
-}  // namespace
-
 bool can_install(const Files& files) {
     for (const auto& file : files) {
         struct stat st;