adb: implement zstd compression for file sync.

Bug: http://b/150827486
Test: test_device.py
Change-Id: I9fac4c760d9dbdce0b3b883db975cfa9b27a9e80
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index eaa32e5..43772ba 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1336,6 +1336,8 @@
         return CompressionType::Brotli;
     } else if (str == "lz4") {
         return CompressionType::LZ4;
+    } else if (str == "zstd") {
+        return CompressionType::Zstd;
     }
 
     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 7185939..8bbe2a8 100644
--- a/adb/client/file_sync_client.cpp
+++ b/adb/client/file_sync_client.cpp
@@ -240,6 +240,7 @@
             have_sendrecv_v2_ = CanUseFeature(*features, kFeatureSendRecv2);
             have_sendrecv_v2_brotli_ = CanUseFeature(*features, kFeatureSendRecv2Brotli);
             have_sendrecv_v2_lz4_ = CanUseFeature(*features, kFeatureSendRecv2LZ4);
+            have_sendrecv_v2_zstd_ = CanUseFeature(*features, kFeatureSendRecv2Zstd);
             have_sendrecv_v2_dry_run_send_ = CanUseFeature(*features, kFeatureSendRecv2DryRunSend);
             std::string error;
             fd.reset(adb_connect("sync:", &error));
@@ -268,13 +269,16 @@
     bool HaveSendRecv2() const { return have_sendrecv_v2_; }
     bool HaveSendRecv2Brotli() const { return have_sendrecv_v2_brotli_; }
     bool HaveSendRecv2LZ4() const { return have_sendrecv_v2_lz4_; }
+    bool HaveSendRecv2Zstd() const { return have_sendrecv_v2_zstd_; }
     bool HaveSendRecv2DryRunSend() const { return have_sendrecv_v2_dry_run_send_; }
 
     // Resolve a compression type which might be CompressionType::Any to a specific compression
     // algorithm.
     CompressionType ResolveCompressionType(CompressionType compression) const {
         if (compression == CompressionType::Any) {
-            if (HaveSendRecv2LZ4()) {
+            if (HaveSendRecv2Zstd()) {
+                return CompressionType::Zstd;
+            } else if (HaveSendRecv2LZ4()) {
                 return CompressionType::LZ4;
             } else if (HaveSendRecv2Brotli()) {
                 return CompressionType::Brotli;
@@ -374,6 +378,10 @@
                 msg.send_v2_setup.flags = kSyncFlagLZ4;
                 break;
 
+            case CompressionType::Zstd:
+                msg.send_v2_setup.flags = kSyncFlagZstd;
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -421,6 +429,10 @@
                 msg.recv_v2_setup.flags |= kSyncFlagLZ4;
                 break;
 
+            case CompressionType::Zstd:
+                msg.recv_v2_setup.flags |= kSyncFlagZstd;
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -631,7 +643,8 @@
         syncsendbuf sbuf;
         sbuf.id = ID_DATA;
 
-        std::variant<std::monostate, NullEncoder, BrotliEncoder, LZ4Encoder> encoder_storage;
+        std::variant<std::monostate, NullEncoder, BrotliEncoder, LZ4Encoder, ZstdEncoder>
+                encoder_storage;
         Encoder* encoder = nullptr;
         switch (compression) {
             case CompressionType::None:
@@ -646,6 +659,10 @@
                 encoder = &encoder_storage.emplace<LZ4Encoder>(SYNC_DATA_MAX);
                 break;
 
+            case CompressionType::Zstd:
+                encoder = &encoder_storage.emplace<ZstdEncoder>(SYNC_DATA_MAX);
+                break;
+
             case CompressionType::Any:
                 LOG(FATAL) << "unexpected CompressionType::Any";
         }
@@ -928,6 +945,7 @@
     bool have_sendrecv_v2_;
     bool have_sendrecv_v2_brotli_;
     bool have_sendrecv_v2_lz4_;
+    bool have_sendrecv_v2_zstd_;
     bool have_sendrecv_v2_dry_run_send_;
 
     TransferLedger global_ledger_;
@@ -1133,7 +1151,8 @@
     uint64_t bytes_copied = 0;
 
     Block buffer(SYNC_DATA_MAX);
-    std::variant<std::monostate, NullDecoder, BrotliDecoder, LZ4Decoder> decoder_storage;
+    std::variant<std::monostate, NullDecoder, BrotliDecoder, LZ4Decoder, ZstdDecoder>
+            decoder_storage;
     Decoder* decoder = nullptr;
 
     std::span buffer_span(buffer.data(), buffer.size());
@@ -1150,6 +1169,10 @@
             decoder = &decoder_storage.emplace<LZ4Decoder>(buffer_span);
             break;
 
+        case CompressionType::Zstd:
+            decoder = &decoder_storage.emplace<ZstdDecoder>(buffer_span);
+            break;
+
         case CompressionType::Any:
             LOG(FATAL) << "unexpected CompressionType::Any";
     }