| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/updater/ipc/update_service_proxy.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/files/file_path.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/sequence_checker.h" |
| #include "base/types/expected.h" |
| #include "base/version.h" |
| #include "chrome/updater/constants.h" |
| #include "chrome/updater/registration_data.h" |
| #include "chrome/updater/update_service.h" |
| #include "components/policy/core/common/policy_types.h" |
| |
| namespace updater { |
| namespace { |
| |
| bool CanRetry(int try_count) { |
| return try_count < 3; |
| } |
| |
| template <typename T> |
| using DoneFunc = |
| void (*)(scoped_refptr<UpdateServiceProxy>, |
| base::RepeatingCallback<void( |
| base::OnceCallback<void(base::expected<T, RpcError>)>)> call, |
| base::OnceCallback<void(T)>, |
| T, |
| int, |
| base::expected<T, RpcError>); |
| |
| template <typename T> |
| void CallDone(scoped_refptr<UpdateServiceProxy> proxy, |
| base::RepeatingCallback<void( |
| base::OnceCallback<void(base::expected<T, RpcError>)>)> call, |
| base::OnceCallback<void(T)> callback, |
| T default_response, |
| int try_count, |
| base::expected<T, RpcError> result) { |
| if (!result.has_value() && CanRetry(try_count)) { |
| call.Run(base::BindOnce(static_cast<DoneFunc<T>>(&CallDone), proxy, call, |
| std::move(callback), default_response, |
| try_count + 1)); |
| return; |
| } |
| std::move(callback).Run(result.value_or(default_response)); |
| } |
| |
| } // namespace |
| |
| UpdateServiceProxy::UpdateServiceProxy( |
| scoped_refptr<UpdateServiceProxyImpl> proxy) |
| : proxy_(proxy) {} |
| |
| void UpdateServiceProxy::GetVersion( |
| base::OnceCallback<void(const base::Version&)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating(&UpdateServiceProxyImpl::GetVersion, proxy_); |
| call.Run(base::BindOnce( |
| static_cast<DoneFunc<base::Version>>(&CallDone), |
| base::WrapRefCounted(this), call, |
| base::BindOnce( |
| [](base::OnceCallback<void(const base::Version&)> callback, |
| base::Version version) { std::move(callback).Run(version); }, |
| std::move(callback)), |
| base::Version(), 1)); |
| } |
| |
| void UpdateServiceProxy::FetchPolicies(policy::PolicyFetchReason reason, |
| base::OnceCallback<void(int)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating(&UpdateServiceProxyImpl::FetchPolicies, |
| proxy_, reason); |
| call.Run(base::BindOnce(static_cast<DoneFunc<int>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| kErrorIpcDisconnect, 1)); |
| } |
| |
| void UpdateServiceProxy::RegisterApp(const RegistrationRequest& request, |
| base::OnceCallback<void(int)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating(&UpdateServiceProxyImpl::RegisterApp, proxy_, |
| request); |
| call.Run(base::BindOnce(static_cast<DoneFunc<int>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| kErrorIpcDisconnect, 1)); |
| } |
| |
| void UpdateServiceProxy::GetAppStates( |
| base::OnceCallback<void(const std::vector<AppState>&)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = |
| base::BindRepeating(&UpdateServiceProxyImpl::GetAppStates, proxy_); |
| call.Run(base::BindOnce( |
| static_cast<DoneFunc<std::vector<AppState>>>(&CallDone), |
| base::WrapRefCounted(this), call, |
| base::BindOnce( |
| [](base::OnceCallback<void(const std::vector<AppState>&)> callback, |
| std::vector<AppState> value) { std::move(callback).Run(value); }, |
| std::move(callback)), |
| std::vector<AppState>(), 1)); |
| } |
| |
| void UpdateServiceProxy::RunPeriodicTasks(base::OnceClosure callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = |
| base::BindRepeating(&UpdateServiceProxyImpl::RunPeriodicTasks, proxy_); |
| call.Run(base::BindOnce( |
| static_cast<DoneFunc<int>>(&CallDone), base::WrapRefCounted(this), call, |
| base::BindOnce([](base::OnceClosure callback, |
| int /*result*/) { std::move(callback).Run(); }, |
| std::move(callback)), |
| kErrorIpcDisconnect, 1)); |
| } |
| |
| void UpdateServiceProxy::CheckForUpdate( |
| const std::string& app_id, |
| UpdateService::Priority priority, |
| PolicySameVersionUpdate policy_same_version_update, |
| const std::string& language, |
| base::RepeatingCallback<void(const UpdateState&)> state_update, |
| base::OnceCallback<void(Result)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating( |
| &UpdateServiceProxyImpl::CheckForUpdate, proxy_, app_id, priority, |
| policy_same_version_update, language, state_update); |
| call.Run( |
| base::BindOnce(static_cast<DoneFunc<UpdateService::Result>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| UpdateService::Result::kIPCConnectionFailed, 1)); |
| } |
| |
| void UpdateServiceProxy::Update( |
| const std::string& app_id, |
| const std::string& install_data_index, |
| Priority priority, |
| PolicySameVersionUpdate policy_same_version_update, |
| const std::string& language, |
| base::RepeatingCallback<void(const UpdateState&)> state_update, |
| base::OnceCallback<void(Result)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating( |
| &UpdateServiceProxyImpl::Update, proxy_, app_id, install_data_index, |
| priority, policy_same_version_update, language, state_update); |
| call.Run( |
| base::BindOnce(static_cast<DoneFunc<UpdateService::Result>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| UpdateService::Result::kIPCConnectionFailed, 1)); |
| } |
| |
| void UpdateServiceProxy::UpdateAll( |
| base::RepeatingCallback<void(const UpdateState&)> state_update, |
| base::OnceCallback<void(Result)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating(&UpdateServiceProxyImpl::UpdateAll, proxy_, |
| state_update); |
| call.Run( |
| base::BindOnce(static_cast<DoneFunc<UpdateService::Result>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| UpdateService::Result::kIPCConnectionFailed, 1)); |
| } |
| |
| void UpdateServiceProxy::Install( |
| const RegistrationRequest& registration, |
| const std::string& client_install_data, |
| const std::string& install_data_index, |
| Priority priority, |
| const std::string& language, |
| base::RepeatingCallback<void(const UpdateState&)> state_update, |
| base::OnceCallback<void(Result)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = |
| base::BindRepeating(&UpdateServiceProxyImpl::Install, proxy_, |
| registration, client_install_data, install_data_index, |
| priority, language, state_update); |
| call.Run( |
| base::BindOnce(static_cast<DoneFunc<UpdateService::Result>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| UpdateService::Result::kIPCConnectionFailed, 1)); |
| } |
| |
| void UpdateServiceProxy::CancelInstalls(const std::string& app_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| proxy_->CancelInstalls(app_id); |
| } |
| |
| void UpdateServiceProxy::RunInstaller( |
| const std::string& app_id, |
| const base::FilePath& installer_path, |
| const std::string& install_args, |
| const std::string& install_data, |
| const std::string& install_settings, |
| const std::string& language, |
| base::RepeatingCallback<void(const UpdateState&)> state_update, |
| base::OnceCallback<void(Result)> callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| auto call = base::BindRepeating( |
| &UpdateServiceProxyImpl::RunInstaller, proxy_, app_id, installer_path, |
| install_args, install_data, install_settings, language, state_update); |
| call.Run( |
| base::BindOnce(static_cast<DoneFunc<UpdateService::Result>>(&CallDone), |
| base::WrapRefCounted(this), call, std::move(callback), |
| UpdateService::Result::kIPCConnectionFailed, 1)); |
| } |
| |
| UpdateServiceProxy::~UpdateServiceProxy() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| } |
| |
| } // namespace updater |