adb: add interfaces for Encoder/Decoder.
More groundwork to support more compression algorithms.
Bug: https://issuetracker.google.com/150827486
Test: python3 -m unittest test_device.FileOperationsTest{Uncompressed,Brotli}
Change-Id: I638493083b83e3f6c6854b631471e9d6b50bd79f
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 04b250d..9078ae9 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -129,20 +129,20 @@
" reverse --remove-all remove all reverse socket connections from device\n"
"\n"
"file transfer:\n"
- " push [--sync] [-zZ] LOCAL... REMOTE\n"
+ " push [--sync] [-z ALGORITHM] [-Z] LOCAL... REMOTE\n"
" copy local files/directories to device\n"
" --sync: only push files that are newer on the host than the device\n"
- " -z: enable compression\n"
+ " -z: enable compression with a specified algorithm (any, none, brotli)\n"
" -Z: disable compression\n"
- " pull [-azZ] REMOTE... LOCAL\n"
+ " pull [-a] [-z ALGORITHM] [-Z] REMOTE... LOCAL\n"
" copy files/dirs from device\n"
" -a: preserve file timestamp and mode\n"
- " -z: enable compression\n"
+ " -z: enable compression with a specified algorithm (any, none, brotli)\n"
" -Z: disable compression\n"
- " sync [-lzZ] [all|data|odm|oem|product|system|system_ext|vendor]\n"
+ " sync [-l] [-z ALGORITHM] [-Z] [all|data|odm|oem|product|system|system_ext|vendor]\n"
" sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
" -l: list files that would be copied, but don't copy them\n"
- " -z: enable compression\n"
+ " -z: enable compression with a specified algorithm (any, none, brotli)\n"
" -Z: disable compression\n"
"\n"
"shell:\n"
@@ -1314,12 +1314,34 @@
return 0;
}
+static CompressionType parse_compression_type(const std::string& str, bool allow_numbers) {
+ if (allow_numbers) {
+ if (str == "0") {
+ return CompressionType::None;
+ } else if (str == "1") {
+ return CompressionType::Any;
+ }
+ }
+
+ if (str == "any") {
+ return CompressionType::Any;
+ } else if (str == "none") {
+ return CompressionType::None;
+ }
+
+ if (str == "brotli") {
+ return CompressionType::Brotli;
+ }
+
+ error_exit("unexpected compression type %s", str.c_str());
+}
+
static void parse_push_pull_args(const char** arg, int narg, std::vector<const char*>* srcs,
- const char** dst, bool* copy_attrs, bool* sync, bool* compressed) {
+ const char** dst, bool* copy_attrs, bool* sync,
+ CompressionType* compression) {
*copy_attrs = false;
- const char* adb_compression = getenv("ADB_COMPRESSION");
- if (adb_compression && strcmp(adb_compression, "0") == 0) {
- *compressed = false;
+ if (const char* adb_compression = getenv("ADB_COMPRESSION")) {
+ *compression = parse_compression_type(adb_compression, true);
}
srcs->clear();
@@ -1333,13 +1355,13 @@
} else if (!strcmp(*arg, "-a")) {
*copy_attrs = true;
} else if (!strcmp(*arg, "-z")) {
- if (compressed != nullptr) {
- *compressed = true;
+ if (narg < 2) {
+ error_exit("-z requires an argument");
}
+ *compression = parse_compression_type(*++arg, false);
+ --narg;
} else if (!strcmp(*arg, "-Z")) {
- if (compressed != nullptr) {
- *compressed = false;
- }
+ *compression = CompressionType::None;
} else if (!strcmp(*arg, "--sync")) {
if (sync != nullptr) {
*sync = true;
@@ -1894,22 +1916,22 @@
} else if (!strcmp(argv[0], "push")) {
bool copy_attrs = false;
bool sync = false;
- bool compressed = true;
+ CompressionType compression = CompressionType::Any;
std::vector<const char*> srcs;
const char* dst = nullptr;
- parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs, &sync, &compressed);
+ parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs, &sync, &compression);
if (srcs.empty() || !dst) error_exit("push requires an argument");
- return do_sync_push(srcs, dst, sync, compressed) ? 0 : 1;
+ return do_sync_push(srcs, dst, sync, compression) ? 0 : 1;
} else if (!strcmp(argv[0], "pull")) {
bool copy_attrs = false;
- bool compressed = true;
+ CompressionType compression = CompressionType::Any;
std::vector<const char*> srcs;
const char* dst = ".";
- parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs, nullptr, &compressed);
+ parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs, nullptr, &compression);
if (srcs.empty()) error_exit("pull requires an argument");
- return do_sync_pull(srcs, dst, copy_attrs, compressed) ? 0 : 1;
+ return do_sync_pull(srcs, dst, copy_attrs, compression) ? 0 : 1;
} else if (!strcmp(argv[0], "install")) {
if (argc < 2) error_exit("install requires an argument");
return install_app(argc, argv);
@@ -1925,27 +1947,26 @@
} else if (!strcmp(argv[0], "sync")) {
std::string src;
bool list_only = false;
- bool compressed = true;
+ CompressionType compression = CompressionType::Any;
- const char* adb_compression = getenv("ADB_COMPRESSION");
- if (adb_compression && strcmp(adb_compression, "0") == 0) {
- compressed = false;
+ if (const char* adb_compression = getenv("ADB_COMPRESSION"); adb_compression) {
+ compression = parse_compression_type(adb_compression, true);
}
int opt;
- while ((opt = getopt(argc, const_cast<char**>(argv), "lzZ")) != -1) {
+ while ((opt = getopt(argc, const_cast<char**>(argv), "lz:Z")) != -1) {
switch (opt) {
case 'l':
list_only = true;
break;
case 'z':
- compressed = true;
+ compression = parse_compression_type(optarg, false);
break;
case 'Z':
- compressed = false;
+ compression = CompressionType::None;
break;
default:
- error_exit("usage: adb sync [-lzZ] [PARTITION]");
+ error_exit("usage: adb sync [-l] [-z ALGORITHM] [-Z] [PARTITION]");
}
}
@@ -1954,7 +1975,7 @@
} else if (optind + 1 == argc) {
src = argv[optind];
} else {
- error_exit("usage: adb sync [-lzZ] [PARTITION]");
+ error_exit("usage: adb sync [-l] [-z ALGORITHM] [-Z] [PARTITION]");
}
std::vector<std::string> partitions{"data", "odm", "oem", "product",
@@ -1965,7 +1986,7 @@
std::string src_dir{product_file(partition)};
if (!directory_exists(src_dir)) continue;
found = true;
- if (!do_sync_sync(src_dir, "/" + partition, list_only, compressed)) return 1;
+ if (!do_sync_sync(src_dir, "/" + partition, list_only, compression)) return 1;
}
}
if (!found) error_exit("don't know how to sync %s partition", src.c_str());