adb: implement LZ4 compression.

Add support for LZ4 compression, which compresses and decompresses far
more quickly than brotli, at the cost of worse compression ratio.

`adb sync -d system` speeds (in MB/s) on aosp_blueline-eng:

           none    brotli    lz4
USB 3.0     120       110    190
USB 2.0      38        75     63

Bug: https://issuetracker.google.com/150827486
Test: python3 -m unittest test_device.FileOperationsTest{Uncompressed,Brotli,LZ4}
Change-Id: Ibef6ac15a76b4e5dcd02d7fb9433cbb1c02b8382
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 9078ae9..02f6e9c 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1331,6 +1331,8 @@
 
     if (str == "brotli") {
         return CompressionType::Brotli;
+    } else if (str == "lz4") {
+        return CompressionType::LZ4;
     }
 
     error_exit("unexpected compression type %s", str.c_str());
diff --git a/adb/client/file_sync_client.cpp b/adb/client/file_sync_client.cpp
index c71880c..75334d7 100644
--- a/adb/client/file_sync_client.cpp
+++ b/adb/client/file_sync_client.cpp
@@ -237,6 +237,7 @@
             have_ls_v2_ = CanUseFeature(features_, kFeatureLs2);
             have_sendrecv_v2_ = CanUseFeature(features_, kFeatureSendRecv2);
             have_sendrecv_v2_brotli_ = CanUseFeature(features_, kFeatureSendRecv2Brotli);
+            have_sendrecv_v2_lz4_ = CanUseFeature(features_, kFeatureSendRecv2LZ4);
             fd.reset(adb_connect("sync:", &error));
             if (fd < 0) {
                 Error("connect failed: %s", error.c_str());
@@ -262,12 +263,15 @@
 
     bool HaveSendRecv2() const { return have_sendrecv_v2_; }
     bool HaveSendRecv2Brotli() const { return have_sendrecv_v2_brotli_; }
+    bool HaveSendRecv2LZ4() const { return have_sendrecv_v2_lz4_; }
 
     // Resolve a compression type which might be CompressionType::Any to a specific compression
     // algorithm.
     CompressionType ResolveCompressionType(CompressionType compression) const {
         if (compression == CompressionType::Any) {
-            if (HaveSendRecv2Brotli()) {
+            if (HaveSendRecv2LZ4()) {
+                return CompressionType::LZ4;
+            } else if (HaveSendRecv2Brotli()) {
                 return CompressionType::Brotli;
             }
             return CompressionType::None;
@@ -361,6 +365,10 @@
                 msg.send_v2_setup.flags = kSyncFlagBrotli;
                 break;
 
+            case CompressionType::LZ4:
+                msg.send_v2_setup.flags = kSyncFlagLZ4;
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -400,6 +408,10 @@
                 msg.recv_v2_setup.flags |= kSyncFlagBrotli;
                 break;
 
+            case CompressionType::LZ4:
+                msg.recv_v2_setup.flags |= kSyncFlagLZ4;
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -599,7 +611,7 @@
         syncsendbuf sbuf;
         sbuf.id = ID_DATA;
 
-        std::variant<std::monostate, NullEncoder, BrotliEncoder> encoder_storage;
+        std::variant<std::monostate, NullEncoder, BrotliEncoder, LZ4Encoder> encoder_storage;
         Encoder* encoder = nullptr;
         switch (compression) {
             case CompressionType::None:
@@ -610,6 +622,10 @@
                 encoder = &encoder_storage.emplace<BrotliEncoder>(SYNC_DATA_MAX);
                 break;
 
+            case CompressionType::LZ4:
+                encoder = &encoder_storage.emplace<LZ4Encoder>(SYNC_DATA_MAX);
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -891,6 +907,7 @@
     bool have_ls_v2_;
     bool have_sendrecv_v2_;
     bool have_sendrecv_v2_brotli_;
+    bool have_sendrecv_v2_lz4_;
 
     TransferLedger global_ledger_;
     TransferLedger current_ledger_;
@@ -1093,7 +1110,7 @@
     uint64_t bytes_copied = 0;
 
     Block buffer(SYNC_DATA_MAX);
-    std::variant<std::monostate, NullDecoder, BrotliDecoder> decoder_storage;
+    std::variant<std::monostate, NullDecoder, BrotliDecoder, LZ4Decoder> decoder_storage;
     Decoder* decoder = nullptr;
 
     std::span buffer_span(buffer.data(), buffer.size());
@@ -1106,6 +1123,10 @@
             decoder = &decoder_storage.emplace<BrotliDecoder>(buffer_span);
             break;
 
+        case CompressionType::LZ4:
+            decoder = &decoder_storage.emplace<LZ4Decoder>(buffer_span);
+            break;
+
         case CompressionType::Any:
             LOG(FATAL) << "unexpected CompressionType::Any";
     }
@@ -1160,8 +1181,7 @@
             }
 
             bytes_copied += output.size();
-
-            sc.RecordBytesTransferred(msg.data.size);
+            sc.RecordBytesTransferred(output.size());
             sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, expected_size);
 
             if (result == DecodeResult::NeedInput) {