diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp index d66d40065..daa21d254 100644 --- a/adb/client/adb_install.cpp +++ b/adb/client/adb_install.cpp @@ -301,7 +301,7 @@ static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy) } template -static int msBetween(TimePoint start, TimePoint end) { +static int ms_between(TimePoint start, TimePoint end) { return std::chrono::duration_cast(end - start).count(); } @@ -349,7 +349,7 @@ static int install_app_incremental(int argc, const char** argv, bool wait, bool } const auto end = clock::now(); - printf("Install command complete in %d ms\n", msBetween(start, end)); + printf("Install command complete in %d ms\n", ms_between(start, end)); if (wait) { (*server_process).wait(); @@ -358,9 +358,9 @@ static int install_app_incremental(int argc, const char** argv, bool wait, bool return 0; } -static std::pair> calculateInstallMode( - InstallMode modeFromArgs, bool fastdeploy, CmdlineOption incrementalRequest) { - if (incrementalRequest == CmdlineOption::Enable) { +static std::pair> calculate_install_mode( + InstallMode modeFromArgs, bool fastdeploy, CmdlineOption incremental_request) { + if (incremental_request == CmdlineOption::Enable) { if (fastdeploy) { error_exit( "--incremental and --fast-deploy options are incompatible. " @@ -369,30 +369,30 @@ static std::pair> calculateInstallMode( } if (modeFromArgs != INSTALL_DEFAULT) { - if (incrementalRequest == CmdlineOption::Enable) { + if (incremental_request == CmdlineOption::Enable) { error_exit("--incremental is not compatible with other installation modes"); } return {modeFromArgs, std::nullopt}; } - if (incrementalRequest != CmdlineOption::Disable && !is_abb_exec_supported()) { - if (incrementalRequest == CmdlineOption::None) { - incrementalRequest = CmdlineOption::Disable; + if (incremental_request != CmdlineOption::Disable && !is_abb_exec_supported()) { + if (incremental_request == CmdlineOption::None) { + incremental_request = CmdlineOption::Disable; } else { error_exit("Device doesn't support incremental installations"); } } - if (incrementalRequest == CmdlineOption::None) { + if (incremental_request == CmdlineOption::None) { // check if the host is ok with incremental by default if (const char* incrementalFromEnv = getenv("ADB_INSTALL_DEFAULT_INCREMENTAL")) { using namespace android::base; auto val = ParseBool(incrementalFromEnv); if (val == ParseBoolResult::kFalse) { - incrementalRequest = CmdlineOption::Disable; + incremental_request = CmdlineOption::Disable; } } } - if (incrementalRequest == CmdlineOption::None) { + if (incremental_request == CmdlineOption::None) { // still ok: let's see if the device allows using incremental by default // it starts feeling like we're looking for an excuse to not to use incremental... std::string error; @@ -408,17 +408,17 @@ static std::pair> calculateInstallMode( using namespace android::base; auto val = ParseBool(buf); if (val == ParseBoolResult::kFalse) { - incrementalRequest = CmdlineOption::Disable; + incremental_request = CmdlineOption::Disable; } } } - if (incrementalRequest == CmdlineOption::Enable) { + if (incremental_request == CmdlineOption::Enable) { // explicitly requested - no fallback return {INSTALL_INCREMENTAL, std::nullopt}; } const auto bestMode = best_install_mode(); - if (incrementalRequest == CmdlineOption::None) { + if (incremental_request == CmdlineOption::None) { // no opinion - use incremental, fallback to regular on a failure. return {INSTALL_INCREMENTAL, bestMode}; } @@ -426,57 +426,75 @@ static std::pair> calculateInstallMode( return {bestMode, std::nullopt}; } -int install_app(int argc, const char** argv) { - std::vector processedArgIndices; - InstallMode installMode = INSTALL_DEFAULT; - bool use_fastdeploy = false; - bool is_reinstall = false; - bool wait = false; - auto incremental_request = CmdlineOption::None; - FastDeploy_AgentUpdateStrategy agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; +static std::vector parse_install_mode(std::vector argv, + InstallMode* install_mode, + CmdlineOption* incremental_request, + bool* incremental_wait) { + *install_mode = INSTALL_DEFAULT; + *incremental_request = CmdlineOption::None; + *incremental_wait = false; - for (int i = 1; i < argc; i++) { - if (argv[i] == "--streaming"sv) { - processedArgIndices.push_back(i); - installMode = INSTALL_STREAM; - } else if (argv[i] == "--no-streaming"sv) { - processedArgIndices.push_back(i); - installMode = INSTALL_PUSH; - } else if (argv[i] == "-r"sv) { - // Note that this argument is not added to processedArgIndices because it - // must be passed through to pm - is_reinstall = true; - } else if (argv[i] == "--fastdeploy"sv) { - processedArgIndices.push_back(i); - use_fastdeploy = true; - } else if (argv[i] == "--no-fastdeploy"sv) { - processedArgIndices.push_back(i); - use_fastdeploy = false; - } else if (argv[i] == "--force-agent"sv) { - processedArgIndices.push_back(i); - agent_update_strategy = FastDeploy_AgentUpdateAlways; - } else if (argv[i] == "--date-check-agent"sv) { - processedArgIndices.push_back(i); - agent_update_strategy = FastDeploy_AgentUpdateNewerTimeStamp; - } else if (argv[i] == "--version-check-agent"sv) { - processedArgIndices.push_back(i); - agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; - } else if (strlen(argv[i]) >= "--incr"sv.size() && "--incremental"sv.starts_with(argv[i])) { - processedArgIndices.push_back(i); - incremental_request = CmdlineOption::Enable; - } else if (strlen(argv[i]) >= "--no-incr"sv.size() && - "--no-incremental"sv.starts_with(argv[i])) { - processedArgIndices.push_back(i); - incremental_request = CmdlineOption::Disable; - } else if (argv[i] == "--wait"sv) { - processedArgIndices.push_back(i); - wait = true; + std::vector passthrough; + for (auto&& arg : argv) { + if (arg == "--streaming"sv) { + *install_mode = INSTALL_STREAM; + } else if (arg == "--no-streaming"sv) { + *install_mode = INSTALL_PUSH; + } else if (strlen(arg) >= "--incr"sv.size() && "--incremental"sv.starts_with(arg)) { + *incremental_request = CmdlineOption::Enable; + } else if (strlen(arg) >= "--no-incr"sv.size() && "--no-incremental"sv.starts_with(arg)) { + *incremental_request = CmdlineOption::Disable; + } else if (arg == "--wait"sv) { + *incremental_wait = true; + } else { + passthrough.push_back(arg); } } + return passthrough; +} - auto [primaryMode, fallbackMode] = - calculateInstallMode(installMode, use_fastdeploy, incremental_request); - if ((primaryMode == INSTALL_STREAM || fallbackMode.value_or(INSTALL_PUSH) == INSTALL_STREAM) && +static std::vector parse_fast_deploy_mode( + std::vector argv, bool* use_fastdeploy, + FastDeploy_AgentUpdateStrategy* agent_update_strategy) { + *use_fastdeploy = false; + *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; + + std::vector passthrough; + for (auto&& arg : argv) { + if (arg == "--fastdeploy"sv) { + *use_fastdeploy = true; + } else if (arg == "--no-fastdeploy"sv) { + *use_fastdeploy = false; + } else if (arg == "--force-agent"sv) { + *agent_update_strategy = FastDeploy_AgentUpdateAlways; + } else if (arg == "--date-check-agent"sv) { + *agent_update_strategy = FastDeploy_AgentUpdateNewerTimeStamp; + } else if (arg == "--version-check-agent"sv) { + *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; + } else { + passthrough.push_back(arg); + } + } + return passthrough; +} + +int install_app(int argc, const char** argv) { + InstallMode install_mode = INSTALL_DEFAULT; + auto incremental_request = CmdlineOption::None; + bool incremental_wait = false; + + bool use_fastdeploy = false; + FastDeploy_AgentUpdateStrategy agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; + + auto unused_argv = parse_install_mode({argv, argv + argc}, &install_mode, &incremental_request, + &incremental_wait); + auto passthrough_argv = + parse_fast_deploy_mode(std::move(unused_argv), &use_fastdeploy, &agent_update_strategy); + + auto [primary_mode, fallback_mode] = + calculate_install_mode(install_mode, use_fastdeploy, incremental_request); + if ((primary_mode == INSTALL_STREAM || + fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) && best_install_mode() == INSTALL_PUSH) { error_exit("Attempting to use streaming install on unsupported device"); } @@ -490,19 +508,12 @@ int install_app(int argc, const char** argv) { } fastdeploy_set_agent_update_strategy(agent_update_strategy); - std::vector passthrough_argv; - for (int i = 0; i < argc; i++) { - if (std::find(processedArgIndices.begin(), processedArgIndices.end(), i) == - processedArgIndices.end()) { - passthrough_argv.push_back(argv[i]); - } - } if (passthrough_argv.size() < 2) { error_exit("install requires an apk argument"); } - auto runInstallMode = [&](InstallMode installMode, bool silent) { - switch (installMode) { + auto run_install_mode = [&](InstallMode install_mode, bool silent) { + switch (install_mode) { case INSTALL_PUSH: return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(), use_fastdeploy); @@ -511,20 +522,20 @@ int install_app(int argc, const char** argv) { use_fastdeploy); case INSTALL_INCREMENTAL: return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(), - wait, silent); + incremental_wait, silent); case INSTALL_DEFAULT: default: - return 1; + error_exit("invalid install mode"); } }; - auto res = runInstallMode(primaryMode, fallbackMode.has_value()); - if (res && fallbackMode.value_or(primaryMode) != primaryMode) { - res = runInstallMode(*fallbackMode, false); + auto res = run_install_mode(primary_mode, fallback_mode.has_value()); + if (res && fallback_mode.value_or(primary_mode) != primary_mode) { + res = run_install_mode(*fallback_mode, false); } return res; } -int install_multiple_app(int argc, const char** argv) { +static int install_multiple_app_streamed(int argc, const char** argv) { // Find all APK arguments starting at end. // All other arguments passed through verbatim. int first_apk = -1; @@ -550,7 +561,6 @@ int install_multiple_app(int argc, const char** argv) { if (first_apk == -1) error_exit("need APK file on command line"); const bool use_abb_exec = is_abb_exec_supported(); - const std::string install_cmd = use_abb_exec ? "package" : best_install_mode() == INSTALL_PUSH ? "exec:pm" : "exec:cmd package"; @@ -673,6 +683,44 @@ finalize_session: return EXIT_SUCCESS; } +int install_multiple_app(int argc, const char** argv) { + InstallMode install_mode = INSTALL_DEFAULT; + auto incremental_request = CmdlineOption::None; + bool incremental_wait = false; + bool use_fastdeploy = false; + + auto passthrough_argv = parse_install_mode({argv + 1, argv + argc}, &install_mode, + &incremental_request, &incremental_wait); + + auto [primary_mode, fallback_mode] = + calculate_install_mode(install_mode, use_fastdeploy, incremental_request); + if ((primary_mode == INSTALL_STREAM || + fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) && + best_install_mode() == INSTALL_PUSH) { + error_exit("Attempting to use streaming install on unsupported device"); + } + + auto run_install_mode = [&](InstallMode install_mode, bool silent) { + switch (install_mode) { + case INSTALL_PUSH: + case INSTALL_STREAM: + return install_multiple_app_streamed(passthrough_argv.size(), + passthrough_argv.data()); + case INSTALL_INCREMENTAL: + return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(), + incremental_wait, silent); + case INSTALL_DEFAULT: + default: + error_exit("invalid install mode"); + } + }; + auto res = run_install_mode(primary_mode, fallback_mode.has_value()); + if (res && fallback_mode.value_or(primary_mode) != primary_mode) { + res = run_install_mode(*fallback_mode, false); + } + return res; +} + int install_multi_package(int argc, const char** argv) { // Find all APK arguments starting at end. // All other arguments passed through verbatim.