Commit cb4431a3 authored by Sorin Jianu's avatar Sorin Jianu Committed by Commit Bot

Allow for Chrome components to be not present while an update check occurs.

Bug: 837371

Change-Id: Ifc2aa0c3b9a8e75d44dad32136d172d58380f1b4
Reviewed-on: https://chromium-review.googlesource.com/1033468Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Commit-Queue: Sorin Jianu <sorin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554870}
parent 9db896d5
......@@ -345,8 +345,13 @@ void Component::StateNew::DoHandle() {
DCHECK(thread_checker_.CalledOnValidThread());
auto& component = State::component();
TransitionState(std::make_unique<StateChecking>(&component));
if (component.crx_component()) {
TransitionState(std::make_unique<StateChecking>(&component));
} else {
component.error_code_ = static_cast<int>(Error::CRX_NOT_FOUND);
component.error_category_ = static_cast<int>(ErrorCategory::kServiceError);
TransitionState(std::make_unique<StateUpdateError>(&component));
}
}
Component::StateChecking::StateChecking(Component* component)
......
......@@ -17,6 +17,7 @@ enum class Error {
RETRY_LATER = 3,
SERVICE_ERROR = 4,
UPDATE_CHECK_ERROR = 5,
CRX_NOT_FOUND = 6,
};
// These errors are sent in pings. Add new values only to the bottom of
......
......@@ -97,8 +97,6 @@ void UpdateEngine::Update(bool is_foreground,
// 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<std::unique_ptr<CrxComponent>> crx_components =
std::move(update_context->crx_data_callback).Run(update_context->ids);
DCHECK_EQ(update_context->ids.size(), crx_components.size());
......@@ -106,20 +104,37 @@ void UpdateEngine::Update(bool is_foreground,
for (size_t i = 0; i != update_context->ids.size(); ++i) {
const auto& id = update_context->ids[i];
DCHECK_EQ(id, GetCrxComponentID(*crx_components[i]));
DCHECK_EQ(1u, update_context->components.count(id));
DCHECK(update_context->components.at(id));
DCHECK(update_context->components[id]->state() == ComponentState::kNew);
auto& crx_component = crx_components[i];
if (crx_component) {
// This component can be checked for updates.
DCHECK_EQ(id, GetCrxComponentID(*crx_component));
auto& component = update_context->components[id];
component->set_crx_component(std::move(crx_component));
component->set_previous_version(component->crx_component()->version);
component->set_previous_fp(component->crx_component()->fingerprint);
update_context->components_to_check_for_updates.push_back(id);
} else {
// |CrxDataCallback| did not return a CrxComponent instance for this
// component, which most likely, has been uninstalled. This component
// is going to be transitioned to an error state when the its |Handle|
// method is called later on by the engine.
update_context->component_queue.push(id);
}
}
auto& component = *update_context->components.at(id);
component.set_crx_component(std::move(crx_components[i]));
component.set_previous_version(component.crx_component()->version);
component.set_previous_fp(component.crx_component()->fingerprint);
if (update_context->components_to_check_for_updates.empty()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&UpdateEngine::HandleComponent,
base::Unretained(this), update_context));
return;
}
// Handle |kNew| state. This will transition the components to |kChecking|.
component.Handle(
for (const auto& id : update_context->components_to_check_for_updates)
update_context->components[id]->Handle(
base::BindOnce(&UpdateEngine::ComponentCheckingForUpdatesStart,
base::Unretained(this), update_context, id));
}
}
void UpdateEngine::ComponentCheckingForUpdatesStart(
......@@ -139,7 +154,7 @@ void UpdateEngine::ComponentCheckingForUpdatesStart(
++update_context->num_components_ready_to_check;
if (update_context->num_components_ready_to_check <
update_context->ids.size()) {
update_context->components_to_check_for_updates.size()) {
return;
}
......@@ -156,7 +171,8 @@ void UpdateEngine::DoUpdateCheck(scoped_refptr<UpdateContext> update_context) {
update_checker_factory_(config_, metadata_.get());
update_context->update_checker->CheckForUpdates(
update_context->session_id, update_context->ids,
update_context->session_id,
update_context->components_to_check_for_updates,
update_context->components, config_->ExtraRequestParams(),
update_context->enabled_component_updates,
base::BindOnce(&UpdateEngine::UpdateCheckDone, base::Unretained(this),
......@@ -186,7 +202,7 @@ void UpdateEngine::UpdateCheckDone(scoped_refptr<UpdateContext> update_context,
update_context->update_check_error = error;
for (const auto& id : update_context->ids) {
for (const auto& id : update_context->components_to_check_for_updates) {
DCHECK_EQ(1u, update_context->components.count(id));
DCHECK(update_context->components.at(id));
......@@ -201,7 +217,8 @@ void UpdateEngine::ComponentCheckingForUpdatesComplete(
DCHECK(update_context);
++update_context->num_components_checked;
if (update_context->num_components_checked < update_context->ids.size()) {
if (update_context->num_components_checked <
update_context->components_to_check_for_updates.size()) {
return;
}
......@@ -215,7 +232,7 @@ void UpdateEngine::UpdateCheckComplete(
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
for (const auto& id : update_context->ids)
for (const auto& id : update_context->components_to_check_for_updates)
update_context->component_queue.push(id);
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -312,7 +329,7 @@ bool UpdateEngine::GetUpdateState(const std::string& id,
for (const auto& context : update_contexts_) {
const auto& components = context.second->components;
const auto it = components.find(id);
if (it != components.end()) {
if (it != components.end() && it->second->crx_component()) {
*update_item = it->second->GetCrxUpdateItem();
return true;
}
......
......@@ -157,10 +157,18 @@ struct UpdateContext : public base::RefCounted<UpdateContext> {
// The time in seconds to wait until doing further update checks.
int retry_after_sec = 0;
// Contains the ids of the components to check for updates. It is possible
// for a component to be uninstalled after it has been added in this context
// but before an update check is made. When this happens, the component won't
// have a CrxComponent instance, therefore, it can't be included in an
// update check.
std::vector<std::string> components_to_check_for_updates;
int update_check_error = 0;
size_t num_components_ready_to_check = 0;
size_t num_components_checked = 0;
// Contains the ids of the components that the state machine must handle.
base::queue<std::string> component_queue;
// The time to wait before handling the update for a component.
......
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