diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp index 16fa215d4..32e9512ff 100644 --- a/adb/client/adb_install.cpp +++ b/adb/client/adb_install.cpp @@ -16,6 +16,7 @@ #include "adb_install.h" +#include #include #include #include @@ -40,18 +41,31 @@ static constexpr int kFastDeployMinApi = 24; #endif +namespace { + +enum InstallMode { + INSTALL_DEFAULT, + INSTALL_PUSH, + INSTALL_STREAM, +}; + +} + static bool can_use_feature(const char* feature) { FeatureSet features; std::string error; if (!adb_get_feature_set(&features, &error)) { fprintf(stderr, "error: %s\n", error.c_str()); - return true; + return false; } return CanUseFeature(features, feature); } -static bool use_legacy_install() { - return !can_use_feature(kFeatureCmd); +static InstallMode best_install_mode() { + if (can_use_feature(kFeatureCmd)) { + return INSTALL_STREAM; + } + return INSTALL_PUSH; } static bool is_apex_supported() { @@ -112,7 +126,7 @@ static int uninstall_app_legacy(int argc, const char** argv) { } int uninstall_app(int argc, const char** argv) { - if (use_legacy_install()) { + if (best_install_mode() == INSTALL_PUSH) { return uninstall_app_legacy(argc, argv); } return uninstall_app_streamed(argc, argv); @@ -200,32 +214,49 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy return 1; } +#ifdef __linux__ + posix_fadvise(local_fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); +#endif + + const bool use_abb = can_use_feature(kFeatureAbb); std::string error; - std::string cmd = "exec:cmd package"; + std::vector cmd_args = {use_abb ? "package" : "exec:cmd package"}; + cmd_args.reserve(argc + 3); // don't copy the APK name, but, copy the rest of the arguments as-is while (argc-- > 1) { - cmd += " " + escape_arg(std::string(*argv++)); + if (use_abb) { + cmd_args.push_back(*argv++); + } else { + cmd_args.push_back(escape_arg(*argv++)); + } } // add size parameter [required for streaming installs] // do last to override any user specified value - cmd += " " + android::base::StringPrintf("-S %" PRIu64, static_cast(sb.st_size)); + cmd_args.push_back("-S"); + cmd_args.push_back( + android::base::StringPrintf("%" PRIu64, static_cast(sb.st_size))); if (is_apex) { - cmd += " --apex"; + cmd_args.push_back("--apex"); } - unique_fd remote_fd(adb_connect(cmd, &error)); + unique_fd remote_fd; + if (use_abb) { + remote_fd = send_abb_exec_command(cmd_args, &error); + } else { + remote_fd.reset(adb_connect(android::base::Join(cmd_args, " "), &error)); + } if (remote_fd < 0) { fprintf(stderr, "adb: connect error for write: %s\n", error.c_str()); return 1; } - char buf[BUFSIZ]; copy_to_file(local_fd.get(), remote_fd.get()); - read_status_line(remote_fd.get(), buf, sizeof(buf)); + char buf[BUFSIZ]; + read_status_line(remote_fd.get(), buf, sizeof(buf)); if (!strncmp("Success", buf, 7)) { fputs(buf, stdout); return 0; @@ -256,8 +287,7 @@ static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy, int result = -1; std::vector apk_file = {argv[last_apk]}; - std::string apk_dest = - "/data/local/tmp/" + android::base::Basename(argv[last_apk]); + std::string apk_dest = "/data/local/tmp/" + android::base::Basename(argv[last_apk]); if (use_fastdeploy == true) { #if defined(ENABLE_FASTDEPLOY) @@ -292,11 +322,7 @@ cleanup_apk: int install_app(int argc, const char** argv) { std::vector processedArgIndicies; - enum installMode { - INSTALL_DEFAULT, - INSTALL_PUSH, - INSTALL_STREAM - } installMode = INSTALL_DEFAULT; + InstallMode installMode = INSTALL_DEFAULT; bool use_fastdeploy = false; bool is_reinstall = false; bool use_localagent = false; @@ -337,14 +363,10 @@ int install_app(int argc, const char** argv) { } if (installMode == INSTALL_DEFAULT) { - if (use_legacy_install()) { - installMode = INSTALL_PUSH; - } else { - installMode = INSTALL_STREAM; - } + installMode = best_install_mode(); } - if (installMode == INSTALL_STREAM && use_legacy_install() == true) { + if (installMode == INSTALL_STREAM && best_install_mode() == INSTALL_PUSH) { error_exit("Attempting to use streaming install on unsupported device"); } @@ -419,7 +441,7 @@ int install_multiple_app(int argc, const char** argv) { if (first_apk == -1) error_exit("need APK file on command line"); std::string install_cmd; - if (use_legacy_install()) { + if (best_install_mode() == INSTALL_PUSH) { install_cmd = "exec:pm"; } else { install_cmd = "exec:cmd package"; @@ -542,7 +564,7 @@ int install_multi_package(int argc, const char** argv) { if (first_package == -1) error_exit("need APK or APEX files on command line"); - if (use_legacy_install()) { + if (best_install_mode() == INSTALL_PUSH) { fprintf(stderr, "adb: multi-package install is not supported on this device\n"); return EXIT_FAILURE; } diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp index 3c03eb24d..4eb4eb4d2 100644 --- a/adb/client/commandline.cpp +++ b/adb/client/commandline.cpp @@ -355,7 +355,7 @@ static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int o } void copy_to_file(int inFd, int outFd) { - std::vector buf(32 * 1024); + std::vector buf(64 * 1024); int len; long total = 0; int old_stdin_mode = -1; diff --git a/adb/client/commandline.h b/adb/client/commandline.h index 6cfd4f791..cd5933a16 100644 --- a/adb/client/commandline.h +++ b/adb/client/commandline.h @@ -17,7 +17,11 @@ #ifndef COMMANDLINE_H #define COMMANDLINE_H +#include + #include "adb.h" +#include "adb_client.h" +#include "adb_unique_fd.h" // Callback used to handle the standard streams (stdout and stderr) sent by the // device's upon receiving a command. @@ -105,4 +109,17 @@ int send_shell_command( const std::string& command, bool disable_shell_protocol = false, StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK); +// Connects to the device "abb" service with |command| and returns the fd. +template +unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) { + std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER); + + unique_fd fd(adb_connect(service_string, error)); + if (fd < 0) { + fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str()); + return unique_fd{}; + } + return fd; +} + #endif // COMMANDLINE_H diff --git a/adb/daemon/abb.cpp b/adb/daemon/abb.cpp index 425438eb2..17c25e88b 100644 --- a/adb/daemon/abb.cpp +++ b/adb/daemon/abb.cpp @@ -24,6 +24,7 @@ #include "adb_io.h" #include "adb_utils.h" #include "shell_service.h" +#include "sysdeps.h" namespace { @@ -69,6 +70,11 @@ std::vector parseCmdArgs(std::string_view args) { } // namespace static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) { + int max_buf = LINUX_MAX_SOCKET_SIZE; + adb_setsockopt(in, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); + adb_setsockopt(out, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); + adb_setsockopt(err, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); + AdbFdTextOutput oin(out); AdbFdTextOutput oerr(err); return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(), @@ -98,6 +104,8 @@ int main(int argc, char* const argv[]) { } unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol); + int max_buf = LINUX_MAX_SOCKET_SIZE; + adb_setsockopt(result, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); if (android::base::SendFileDescriptors(fd, "", 1, result.get()) != 1) { PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data; break; diff --git a/adb/daemon/abb_service.cpp b/adb/daemon/abb_service.cpp index a43527982..e1df4a591 100644 --- a/adb/daemon/abb_service.cpp +++ b/adb/daemon/abb_service.cpp @@ -53,14 +53,13 @@ unique_fd AbbProcess::sendCommand(std::string_view command) { return error_fd; } - if (!SendProtocolString(socket_fd_, std::string(command))) { + if (!SendProtocolString(socket_fd_, command)) { PLOG(ERROR) << "failed to send command to abb"; socket_fd_.reset(); continue; } unique_fd fd; - std::string error; char buf; if (android::base::ReceiveFileDescriptors(socket_fd_, &buf, 1, &fd) != 1) { PLOG(ERROR) << "failed to receive FD from abb";