Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: components/update_client/update_engine.cc

Issue 2835803002: Refactor the UpdateEngine and its actions in the component updater. (Closed)
Patch Set: feedback up to #6 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/update_client/update_engine.h ('k') | components/update_client/utils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/update_client/update_engine.cc
diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc
index b127befe91b3906c8b6277a1b9ad86ceb8886f34..afef9097097c21598b51bcd0e655cda99f66ee3e 100644
--- a/components/update_client/update_engine.cc
+++ b/components/update_client/update_engine.cc
@@ -4,19 +4,23 @@
#include "components/update_client/update_engine.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
#include "components/prefs/pref_service.h"
-#include "components/update_client/action_update_check.h"
+#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/update_checker.h"
#include "components/update_client/update_client_errors.h"
+#include "components/update_client/utils.h"
namespace update_client {
@@ -27,9 +31,7 @@ UpdateContext::UpdateContext(
const UpdateClient::CrxDataCallback& crx_data_callback,
const UpdateEngine::NotifyObserversCallback& notify_observers_callback,
const UpdateEngine::Callback& callback,
- UpdateChecker::Factory update_checker_factory,
- CrxDownloader::Factory crx_downloader_factory,
- PingManager* ping_manager)
+ CrxDownloader::Factory crx_downloader_factory)
: config(config),
is_foreground(is_foreground),
enabled_component_updates(config->EnabledComponentUpdates()),
@@ -37,12 +39,12 @@ UpdateContext::UpdateContext(
crx_data_callback(crx_data_callback),
notify_observers_callback(notify_observers_callback),
callback(callback),
- main_task_runner(base::ThreadTaskRunnerHandle::Get()),
blocking_task_runner(config->GetSequencedTaskRunner()),
- update_checker_factory(update_checker_factory),
- crx_downloader_factory(crx_downloader_factory),
- ping_manager(ping_manager),
- retry_after_sec(0) {}
+ crx_downloader_factory(crx_downloader_factory) {
+ for (const auto& id : ids)
+ components.insert(
+ std::make_pair(id, base::MakeUnique<Component>(*this, id)));
+}
UpdateContext::~UpdateContext() {}
@@ -63,20 +65,6 @@ UpdateEngine::~UpdateEngine() {
DCHECK(thread_checker_.CalledOnValidThread());
}
-bool UpdateEngine::GetUpdateState(const std::string& id,
- CrxUpdateItem* update_item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- for (const auto* context : update_contexts_) {
- const auto& update_items = context->update_items;
- const auto it = update_items.find(id);
- if (it != update_items.end()) {
- *update_item = *it->second.get();
- return true;
- }
- }
- return false;
-}
-
void UpdateEngine::Update(
bool is_foreground,
const std::vector<std::string>& ids,
@@ -90,29 +78,98 @@ void UpdateEngine::Update(
return;
}
- std::unique_ptr<UpdateContext> update_context(new UpdateContext(
+ const auto result = update_contexts_.insert(base::MakeUnique<UpdateContext>(
config_, is_foreground, ids, crx_data_callback,
- notify_observers_callback_, callback, update_checker_factory_,
- crx_downloader_factory_, ping_manager_));
+ notify_observers_callback_, callback, crx_downloader_factory_));
+
+ DCHECK(result.second);
- std::unique_ptr<ActionUpdateCheck> update_check_action(new ActionUpdateCheck(
- (*update_context->update_checker_factory)(config_, metadata_.get()),
- config_->GetBrowserVersion(), config_->ExtraRequestParams()));
+ const auto& it = result.first;
+ const auto& update_context = *it;
+ DCHECK(update_context);
- update_context->current_action = std::move(update_check_action);
- update_contexts_.insert(update_context.get());
+ // Calls out to get the corresponding CrxComponent data for the CRXs in this
+ // update context.
+ DCHECK_EQ(ids.size(), update_context->ids.size());
+ DCHECK_EQ(update_context->ids.size(), update_context->components.size());
+ std::vector<CrxComponent> crx_components;
+ update_context->crx_data_callback.Run(update_context->ids, &crx_components);
+ DCHECK_EQ(update_context->ids.size(), crx_components.size());
- update_context->current_action->Run(
- update_context.get(),
- base::Bind(&UpdateEngine::UpdateComplete, base::Unretained(this),
- update_context.get()));
+ for (size_t i = 0; i != update_context->ids.size(); ++i) {
+ const auto& id = update_context->ids[i];
+ const auto& crx_component = crx_components[i];
- ignore_result(update_context.release());
+ DCHECK_EQ(id, GetCrxComponentID(crx_component));
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ auto& component = *update_context->components.at(id);
+ component.set_on_demand(update_context->is_foreground);
+ component.set_crx_component(crx_component);
+ component.set_previous_version(crx_component.version);
+ component.set_previous_fp(crx_component.fingerprint);
+
+ // Handle |kNew| state. This will transition the components to |kChecking|.
+ component.Handle(base::Bind(&UpdateEngine::ComponentCheckingForUpdatesStart,
+ base::Unretained(this), it,
+ base::ConstRef(component)));
+ }
+}
+
+void UpdateEngine::ComponentCheckingForUpdatesStart(
+ const UpdateContextIterator& it,
+ const Component& component) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& update_context = *it;
+ DCHECK(update_context);
+
+ const auto id = component.id();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ // Handle |kChecking| state.
+ auto& mutable_component = *update_context->components.at(id);
+ mutable_component.Handle(base::Bind(
+ &UpdateEngine::ComponentCheckingForUpdatesComplete,
+ base::Unretained(this), it, base::ConstRef(mutable_component)));
+
+ ++update_context->num_components_ready_to_check;
+ if (update_context->num_components_ready_to_check <
+ update_context->ids.size()) {
+ return;
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::DoUpdateCheck, base::Unretained(this), it));
}
-void UpdateEngine::UpdateComplete(UpdateContext* update_context, Error error) {
+void UpdateEngine::DoUpdateCheck(const UpdateContextIterator& it) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(update_contexts_.find(update_context) != update_contexts_.end());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ update_context->update_checker =
+ update_checker_factory_(config_, metadata_.get());
+
+ update_context->update_checker->CheckForUpdates(
+ update_context->ids, update_context->components,
+ config_->ExtraRequestParams(), update_context->enabled_component_updates,
+ base::Bind(&UpdateEngine::UpdateCheckDone, base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateCheckDone(const UpdateContextIterator& it,
+ int error,
+ int retry_after_sec) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ update_context->retry_after_sec = retry_after_sec;
const int throttle_sec(update_context->retry_after_sec);
DCHECK_LE(throttle_sec, 24 * 60 * 60);
@@ -120,22 +177,161 @@ void UpdateEngine::UpdateComplete(UpdateContext* update_context, Error error) {
// Only positive values for throttle_sec are effective. 0 means that no
// throttling occurs and has the effect of resetting the member.
// Negative values are not trusted and are ignored.
- if (throttle_sec >= 0)
+ if (throttle_sec >= 0) {
throttle_updates_until_ =
- throttle_sec
- ? base::TimeTicks::Now() +
- base::TimeDelta::FromSeconds(throttle_sec)
- : base::TimeTicks();
+ throttle_sec ? base::TimeTicks::Now() +
+ base::TimeDelta::FromSeconds(throttle_sec)
+ : base::TimeTicks();
+ }
+
+ update_context->update_check_error = error;
- auto callback = update_context->callback;
+ for (const auto& id : update_context->ids) {
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ auto& component = *update_context->components.at(id);
+ component.UpdateCheckComplete();
+ }
+}
+
+void UpdateEngine::ComponentCheckingForUpdatesComplete(
+ const UpdateContextIterator& it,
+ const Component& component) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& update_context = *it;
+ DCHECK(update_context);
+
+ ++update_context->num_components_checked;
+ if (update_context->num_components_checked < update_context->ids.size()) {
+ return;
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&UpdateEngine::UpdateCheckComplete,
+ base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateCheckComplete(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& update_context = *it;
+ DCHECK(update_context);
+
+ if (update_context->update_check_error) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::UpdateComplete, base::Unretained(this), it,
+ Error::UPDATE_CHECK_ERROR));
+ return;
+ }
- update_contexts_.erase(update_context);
- delete update_context;
+ for (const auto& id : update_context->ids)
+ update_context->component_queue.push(id);
- callback.Run(error);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
+void UpdateEngine::HandleComponent(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ auto& queue = update_context->component_queue;
+
+ if (queue.empty()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&UpdateEngine::UpdateComplete,
+ base::Unretained(this), it, Error::NONE));
+ return;
+ }
+
+ const auto& id = queue.front();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+ DCHECK(component);
+
+ auto& next_update_delay = (*it)->next_update_delay;
+ if (!next_update_delay.is_zero() && component->IsUpdateAvailable()) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it),
+ next_update_delay);
+
+ next_update_delay = base::TimeDelta();
+
+ notify_observers_callback_.Run(
+ UpdateClient::Observer::Events::COMPONENT_WAIT, id);
+ return;
+ }
+
+ component->Handle(base::Bind(&UpdateEngine::HandleComponentComplete,
+ base::Unretained(this), it));
+}
+
+void UpdateEngine::HandleComponentComplete(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ auto& queue = update_context->component_queue;
+ DCHECK(!queue.empty());
+
+ const auto& id = queue.front();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+ DCHECK(component);
+
+ if (component->IsHandled()) {
+ (*it)->next_update_delay = component->GetUpdateDuration();
+
+ // Only ping when the server response included an update for this component.
+ if (component->CanPing()) {
+ ping_manager_->SendPing(*component);
+ }
+
+ queue.pop();
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateComplete(const UpdateContextIterator& it,
+ Error error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(update_context->callback, error));
+
+ update_contexts_.erase(it);
+}
+
+bool UpdateEngine::GetUpdateState(const std::string& id,
+ CrxUpdateItem* update_item) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ for (const auto& context : update_contexts_) {
+ const auto it = context->components.find(id);
+ if (it != context->components.end()) {
+ *update_item = it->second->GetCrxUpdateItem();
+ return true;
+ }
+ }
+ return false;
}
bool UpdateEngine::IsThrottled(bool is_foreground) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (is_foreground || throttle_updates_until_.is_null())
return false;
@@ -147,4 +343,33 @@ bool UpdateEngine::IsThrottled(bool is_foreground) const {
now < throttle_updates_until_;
}
+void UpdateEngine::SendUninstallPing(const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto result = update_contexts_.insert(base::MakeUnique<UpdateContext>(
+ config_, false, std::vector<std::string>{id},
+ UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
+ callback, nullptr));
+
+ DCHECK(result.second);
+
+ const auto& it = result.first;
+ const auto& update_context = *it;
+ DCHECK(update_context);
+ DCHECK_EQ(1u, update_context->ids.size());
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+
+ component->Uninstall(version, reason);
+
+ update_context->component_queue.push(id);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
} // namespace update_client
« no previous file with comments | « components/update_client/update_engine.h ('k') | components/update_client/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698