blob: 1156b0e4159ad6d0f5ef963cc66603e9c265685f [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/service_worker/service_worker_update_checker.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_version.h"
namespace content {
ServiceWorkerUpdateChecker::ServiceWorkerUpdateChecker(
std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare,
scoped_refptr<ServiceWorkerVersion> version_to_update,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
: scripts_to_compare_(std::move(scripts_to_compare)),
version_to_update_(std::move(version_to_update)),
loader_factory_(std::move(loader_factory)),
weak_factory_(this) {}
ServiceWorkerUpdateChecker::~ServiceWorkerUpdateChecker() = default;
void ServiceWorkerUpdateChecker::Start(UpdateStatusCallback callback) {
DCHECK(!scripts_to_compare_.empty());
callback_ = std::move(callback);
CheckOneScript();
}
void ServiceWorkerUpdateChecker::OnOneUpdateCheckFinished(
bool is_script_changed) {
running_checker_.reset();
if (is_script_changed) {
// Found an updated script. Stop the comparison of scripts here and
// return to ServiceWorkerRegisterJob to continue the update.
// Note that running |callback_| will delete |this|.
std::move(callback_).Run(true);
return;
}
CheckOneScript();
}
void ServiceWorkerUpdateChecker::CheckOneScript() {
DCHECK_LE(scripts_compared_, scripts_to_compare_.size());
if (scripts_compared_ == scripts_to_compare_.size()) {
// None of the scripts that went through the comparison had any updates.
// Note that running |callback_| will delete |this|.
std::move(callback_).Run(false);
return;
}
ServiceWorkerDatabase::ResourceRecord script =
scripts_to_compare_[scripts_compared_++];
DCHECK_NE(kInvalidServiceWorkerResourceId, script.resource_id)
<< "All the target scripts should be stored in the storage.";
bool is_main_script = script.url == version_to_update_->script_url();
ServiceWorkerStorage* storage = version_to_update_->context()->storage();
// We need two identical readers for comparing and reading the resource for
// |script.resource_id| from the storage.
auto compare_reader = storage->CreateResponseReader(script.resource_id);
auto copy_reader = storage->CreateResponseReader(script.resource_id);
auto writer = storage->CreateResponseWriter(storage->NewResourceId());
running_checker_ = std::make_unique<ServiceWorkerSingleScriptUpdateChecker>(
script.url, is_main_script, loader_factory_, std::move(compare_reader),
std::move(copy_reader), std::move(writer),
base::BindOnce(&ServiceWorkerUpdateChecker::OnOneUpdateCheckFinished,
weak_factory_.GetWeakPtr()));
}
} // namespace content