Commit 25bd437f authored by Amin Hassani's avatar Amin Hassani Committed by Commit Bot

Make dlcservice_client use per-DLC signal

We want to move away from OnInstallStatus signal and instead move to a
per-DLC signal DlcStateChanged. This new signal is designed to make it
much easier for clients to monitor the state of a DLC.

BUG=chromium:1071260
TEST=./testing/xvfb.py ./out/Default/unit_tests --gtest_filter=Dlc*

Change-Id: Ibc042670afb5ec1fa9183bb20833d12c911ec94f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2213892
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Auto-Submit: Amin Hassani <ahassani@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772252}
parent 9b890006
...@@ -122,7 +122,7 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -122,7 +122,7 @@ class DlcserviceClientImpl : public DlcserviceClient {
progress_callback_holder_ = std::move(progress_callback); progress_callback_holder_ = std::move(progress_callback);
install_callback_holder_ = std::move(install_callback); install_callback_holder_ = std::move(install_callback);
install_field_holder_ = dlc_id; dlc_id_holder_ = dlc_id;
VLOG(1) << "Requesting to install DLC(s)."; VLOG(1) << "Requesting to install DLC(s).";
dlcservice_proxy_->CallMethodWithErrorResponse( dlcservice_proxy_->CallMethodWithErrorResponse(
...@@ -171,8 +171,8 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -171,8 +171,8 @@ class DlcserviceClientImpl : public DlcserviceClient {
weak_ptr_factory_.GetWeakPtr(), std::move(callback))); weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} }
void OnInstallStatusForTest(dbus::Signal* signal) override { void DlcStateChangedForTest(dbus::Signal* signal) override {
OnInstallStatus(signal); DlcStateChanged(signal);
} }
void Init(dbus::Bus* bus) { void Init(dbus::Bus* bus) {
...@@ -180,10 +180,10 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -180,10 +180,10 @@ class DlcserviceClientImpl : public DlcserviceClient {
dlcservice::kDlcServiceServiceName, dlcservice::kDlcServiceServiceName,
dbus::ObjectPath(dlcservice::kDlcServiceServicePath)); dbus::ObjectPath(dlcservice::kDlcServiceServicePath));
dlcservice_proxy_->ConnectToSignal( dlcservice_proxy_->ConnectToSignal(
dlcservice::kDlcServiceInterface, dlcservice::kOnInstallStatusSignal, dlcservice::kDlcServiceInterface, dlcservice::kDlcStateChangedSignal,
base::BindRepeating(&DlcserviceClientImpl::OnInstallStatus, base::BindRepeating(&DlcserviceClientImpl::DlcStateChanged,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&DlcserviceClientImpl::OnInstallStatusConnected, base::BindOnce(&DlcserviceClientImpl::DlcStateChangedConnected,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
...@@ -198,7 +198,7 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -198,7 +198,7 @@ class DlcserviceClientImpl : public DlcserviceClient {
// |Install()| // |Install()|
install_callback_holder_.reset(); install_callback_holder_.reset();
progress_callback_holder_.reset(); progress_callback_holder_.reset();
install_field_holder_.reset(); dlc_id_holder_.reset();
} }
void EnqueueTask(base::OnceClosure task) { void EnqueueTask(base::OnceClosure task) {
...@@ -213,57 +213,59 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -213,57 +213,59 @@ class DlcserviceClientImpl : public DlcserviceClient {
} }
} }
void SendProgress(const dlcservice::InstallStatus& install_status) { void SendProgress(double progress) {
const double progress = install_status.progress();
VLOG(2) << "Install in progress: " << progress; VLOG(2) << "Install in progress: " << progress;
if (progress_callback_holder_.has_value()) if (progress_callback_holder_.has_value())
progress_callback_holder_.value().Run(progress); progress_callback_holder_.value().Run(progress);
} }
void SendCompleted(const dlcservice::InstallStatus& install_status) { void SendCompleted(const dlcservice::DlcState& dlc_state) {
// TODO(crbug.com/1078556): We should not be getting the DLC ID from the if (!install_callback_holder_.has_value() || !dlc_id_holder_.has_value())
// module list returned by the signal. return;
std::string dlc_id, root_path;
if (install_status.dlc_module_list().dlc_module_infos_size() > 0) { if (dlc_id_holder_ != dlc_state.id()) {
auto dlc_info = install_status.dlc_module_list().dlc_module_infos(0); // We are not interested in this DLC. Some other process might be
dlc_id = dlc_info.dlc_id(); // installing it.
root_path = dlc_info.dlc_root(); return;
} }
InstallResult install_result = { if (dlc_state.state() == dlcservice::DlcState::NOT_INSTALLED) {
.error = install_status.error_code(), LOG(ERROR) << "Failed to install DLC " << dlc_state.id()
.dlc_id = dlc_id, << " with error code: " << dlc_state.last_error_code();
.root_path = root_path,
}; } else {
std::move(install_callback_holder_.value()).Run(install_result); VLOG(1) << "DLC " << dlc_state.id() << " installed successfully.";
if (dlc_state.last_error_code() != dlcservice::kErrorNone) {
LOG(WARNING) << "DLC installation was sucessful but non-success "
<< "error code: " << dlc_state.last_error_code();
}
} }
void OnInstallStatus(dbus::Signal* signal) { InstallResult result = {
if (!install_callback_holder_.has_value()) .error = dlc_state.last_error_code(),
return; .dlc_id = dlc_state.id(),
.root_path = dlc_state.root_path(),
};
std::move(install_callback_holder_.value()).Run(result);
}
dlcservice::InstallStatus install_status; void DlcStateChanged(dbus::Signal* signal) {
if (!dbus::MessageReader(signal).PopArrayOfBytesAsProto(&install_status)) { dlcservice::DlcState dlc_state;
if (!dbus::MessageReader(signal).PopArrayOfBytesAsProto(&dlc_state)) {
LOG(ERROR) << "Failed to parse proto as install status."; LOG(ERROR) << "Failed to parse proto as install status.";
return; return;
} }
switch (install_status.status()) { switch (dlc_state.state()) {
case dlcservice::Status::COMPLETED: case dlcservice::DlcState::NOT_INSTALLED:
VLOG(1) << "DLC(s) install successful."; case dlcservice::DlcState::INSTALLED:
SendCompleted(install_status); SendCompleted(dlc_state);
break; break;
case dlcservice::Status::RUNNING: { case dlcservice::DlcState::INSTALLING:
SendProgress(install_status); SendProgress(dlc_state.progress());
// Need to return here since we don't want to try starting another // Need to return here since we don't want to try starting another
// pending install from the queue (would waste time checking). // pending install from the queue (would waste time checking).
return; return;
}
case dlcservice::Status::FAILED:
LOG(ERROR) << "Failed to install with error code: "
<< install_status.error_code();
SendCompleted(install_status);
break;
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -274,10 +276,10 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -274,10 +276,10 @@ class DlcserviceClientImpl : public DlcserviceClient {
CheckAndRunPendingTask(); CheckAndRunPendingTask();
} }
void OnInstallStatusConnected(const std::string& interface, void DlcStateChangedConnected(const std::string& interface,
const std::string& signal, const std::string& signal,
bool success) { bool success) {
LOG_IF(ERROR, !success) << "Failed to connect to install status signal."; LOG_IF(ERROR, !success) << "Failed to connect to DlcStateChanged signal.";
} }
void OnInstall(dbus::Response* response, dbus::ErrorResponse* err_response) { void OnInstall(dbus::Response* response, dbus::ErrorResponse* err_response) {
...@@ -286,7 +288,7 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -286,7 +288,7 @@ class DlcserviceClientImpl : public DlcserviceClient {
// Perform DCHECKs only when an error occurs, platform dlcservice currently // Perform DCHECKs only when an error occurs, platform dlcservice currently
// sends a signal prior to DBus method callback on quick install scenarios. // sends a signal prior to DBus method callback on quick install scenarios.
DCHECK(install_field_holder_.has_value()); DCHECK(dlc_id_holder_.has_value());
DCHECK(install_callback_holder_.has_value()); DCHECK(install_callback_holder_.has_value());
DCHECK(progress_callback_holder_.has_value()); DCHECK(progress_callback_holder_.has_value());
...@@ -294,13 +296,14 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -294,13 +296,14 @@ class DlcserviceClientImpl : public DlcserviceClient {
if (err == dlcservice::kErrorBusy) { if (err == dlcservice::kErrorBusy) {
EnqueueTask(base::BindOnce(&DlcserviceClientImpl::Install, EnqueueTask(base::BindOnce(&DlcserviceClientImpl::Install,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
std::move(install_field_holder_.value()), std::move(dlc_id_holder_.value()),
std::move(install_callback_holder_.value()), std::move(install_callback_holder_.value()),
std::move(progress_callback_holder_.value()))); std::move(progress_callback_holder_.value())));
} else { } else {
dlcservice::InstallStatus install_status; dlcservice::DlcState dlc_state;
install_status.set_error_code(err); dlc_state.set_id(dlc_id_holder_.value());
SendCompleted(install_status); dlc_state.set_last_error_code(err);
SendCompleted(dlc_state);
} }
CheckAndRunPendingTask(); CheckAndRunPendingTask();
} }
...@@ -347,8 +350,8 @@ class DlcserviceClientImpl : public DlcserviceClient { ...@@ -347,8 +350,8 @@ class DlcserviceClientImpl : public DlcserviceClient {
// The cached callback to call on during progress of |Install()|. // The cached callback to call on during progress of |Install()|.
base::Optional<ProgressCallback> progress_callback_holder_; base::Optional<ProgressCallback> progress_callback_holder_;
// The cached field of string (DLC ID) for retrying call to install. // The cached DLC ID for retrying call to install.
base::Optional<std::string> install_field_holder_; base::Optional<std::string> dlc_id_holder_;
// A list of postponed installs to dlcservice. // A list of postponed installs to dlcservice.
std::deque<base::OnceClosure> pending_tasks_; std::deque<base::OnceClosure> pending_tasks_;
......
...@@ -99,7 +99,7 @@ class COMPONENT_EXPORT(DLCSERVICE_CLIENT) DlcserviceClient { ...@@ -99,7 +99,7 @@ class COMPONENT_EXPORT(DLCSERVICE_CLIENT) DlcserviceClient {
virtual void GetExistingDlcs(GetExistingDlcsCallback callback) = 0; virtual void GetExistingDlcs(GetExistingDlcsCallback callback) = 0;
// During testing, can be used to mimic signals received back from dlcservice. // During testing, can be used to mimic signals received back from dlcservice.
virtual void OnInstallStatusForTest(dbus::Signal* signal) = 0; virtual void DlcStateChangedForTest(dbus::Signal* signal) = 0;
// Creates and initializes the global instance. |bus| must not be nullptr. // Creates and initializes the global instance. |bus| must not be nullptr.
static void Initialize(dbus::Bus* bus); static void Initialize(dbus::Bus* bus);
......
...@@ -303,13 +303,13 @@ TEST_F(DlcserviceClientTest, InstallProgressTest) { ...@@ -303,13 +303,13 @@ TEST_F(DlcserviceClientTest, InstallProgressTest) {
EXPECT_EQ(0u, counter.load()); EXPECT_EQ(0u, counter.load());
dbus::Signal signal("com.example.Interface", "SomeSignal"); dbus::Signal signal("com.example.Interface", "SomeSignal");
dlcservice::InstallStatus install_status; dlcservice::DlcState dlc_state;
install_status.set_status(dlcservice::Status::RUNNING); dlc_state.set_state(dlcservice::DlcState::INSTALLING);
dbus::MessageWriter writer(&signal); dbus::MessageWriter writer(&signal);
writer.AppendProtoAsArrayOfBytes(install_status); writer.AppendProtoAsArrayOfBytes(dlc_state);
client_->OnInstallStatusForTest(&signal); client_->DlcStateChangedForTest(&signal);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, counter.load()); EXPECT_EQ(1u, counter.load());
} }
...@@ -358,14 +358,14 @@ TEST_F(DlcserviceClientTest, PendingTaskTest) { ...@@ -358,14 +358,14 @@ TEST_F(DlcserviceClientTest, PendingTaskTest) {
EXPECT_EQ(0u, counter.load()); EXPECT_EQ(0u, counter.load());
dbus::Signal signal("com.example.Interface", "SomeSignal"); dbus::Signal signal("com.example.Interface", "SomeSignal");
dlcservice::InstallStatus install_status; dlcservice::DlcState dlc_state;
install_status.set_status(dlcservice::Status::COMPLETED); dlc_state.set_state(dlcservice::DlcState::INSTALLED);
dbus::MessageWriter writer(&signal); dbus::MessageWriter writer(&signal);
writer.AppendProtoAsArrayOfBytes(install_status); writer.AppendProtoAsArrayOfBytes(dlc_state);
for (size_t i = 1; i < 100; ++i) { for (size_t i = 1; i < 100; ++i) {
client_->OnInstallStatusForTest(&signal); client_->DlcStateChangedForTest(&signal);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(i <= kLoopCount ? i : kLoopCount, counter.load()); EXPECT_EQ(i <= kLoopCount ? i : kLoopCount, counter.load());
} }
......
...@@ -48,7 +48,7 @@ void FakeDlcserviceClient::GetExistingDlcs(GetExistingDlcsCallback callback) { ...@@ -48,7 +48,7 @@ void FakeDlcserviceClient::GetExistingDlcs(GetExistingDlcsCallback callback) {
dlcs_with_content_)); dlcs_with_content_));
} }
void FakeDlcserviceClient::OnInstallStatusForTest(dbus::Signal* signal) { void FakeDlcserviceClient::DlcStateChangedForTest(dbus::Signal* signal) {
NOTREACHED(); NOTREACHED();
} }
......
...@@ -30,7 +30,7 @@ class COMPONENT_EXPORT(DLCSERVICE_CLIENT) FakeDlcserviceClient ...@@ -30,7 +30,7 @@ class COMPONENT_EXPORT(DLCSERVICE_CLIENT) FakeDlcserviceClient
// Purging removes the DLC entirely from disk. // Purging removes the DLC entirely from disk.
void Purge(const std::string& dlc_id, PurgeCallback callback) override; void Purge(const std::string& dlc_id, PurgeCallback callback) override;
void GetExistingDlcs(GetExistingDlcsCallback callback) override; void GetExistingDlcs(GetExistingDlcsCallback callback) override;
void OnInstallStatusForTest(dbus::Signal* signal) override; void DlcStateChangedForTest(dbus::Signal* signal) override;
// Setters: // Setters:
// TODO(hsuregan/kimjae): Convert setters and at tests that use them to // TODO(hsuregan/kimjae): Convert setters and at tests that use them to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment