| Index: content/browser/service_worker/service_worker_context_watcher.cc
|
| diff --git a/content/browser/service_worker/service_worker_context_watcher.cc b/content/browser/service_worker/service_worker_context_watcher.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..45b0065c623ab65aedbbebb954d1a85142556401
|
| --- /dev/null
|
| +++ b/content/browser/service_worker/service_worker_context_watcher.cc
|
| @@ -0,0 +1,210 @@
|
| +// Copyright 2015 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_context_watcher.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/containers/scoped_ptr_hash_map.h"
|
| +#include "content/browser/service_worker/service_worker_context_observer.h"
|
| +#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
| +#include "content/browser/service_worker/service_worker_version.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace content {
|
| +namespace {
|
| +
|
| +bool IsStoppedAndRedundant(const ServiceWorkerVersionInfo& version_info) {
|
| + return version_info.running_status ==
|
| + content::ServiceWorkerVersion::STOPPED &&
|
| + version_info.status == content::ServiceWorkerVersion::REDUNDANT;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ServiceWorkerContextWatcher::ServiceWorkerContextWatcher(
|
| + scoped_refptr<ServiceWorkerContextWrapper> context,
|
| + const WorkerRegistrationUpdatedCallback& registration_callback,
|
| + const WorkerVersionUpdatedCallback& version_callback)
|
| + : context_(context),
|
| + registration_callback_(registration_callback),
|
| + version_callback_(version_callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::Start() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread,
|
| + this));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::Stop() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ServiceWorkerContextWatcher::StopOnIOThread, this));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + context_->context()->storage()->GetAllRegistrations(base::Bind(
|
| + &ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread, this));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
|
| + const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + context_->AddObserver(this);
|
| +
|
| + base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>
|
| + registration_info_map;
|
| + for (const auto& registration : stored_registrations)
|
| + StoreRegistrationInfo(registration, ®istration_info_map);
|
| + for (const auto& registration :
|
| + context_->context()->GetAllLiveRegistrationInfo()) {
|
| + StoreRegistrationInfo(registration, ®istration_info_map);
|
| + }
|
| + for (const auto& version : context_->context()->GetAllLiveVersionInfo())
|
| + StoreVersionInfo(version);
|
| +
|
| + std::vector<ServiceWorkerRegistrationInfo> registrations;
|
| + registrations.reserve(registration_info_map.size());
|
| + for (const auto& registration_id_info_pair : registration_info_map)
|
| + registrations.push_back(*registration_id_info_pair.second);
|
| +
|
| + std::vector<ServiceWorkerVersionInfo> versions;
|
| + versions.reserve(version_info_map_.size());
|
| +
|
| + for (auto version_it = version_info_map_.begin();
|
| + version_it != version_info_map_.end();) {
|
| + versions.push_back(*version_it->second);
|
| + if (IsStoppedAndRedundant(*version_it->second))
|
| + version_info_map_.erase(version_it++);
|
| + else
|
| + ++version_it;
|
| + }
|
| +
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(registration_callback_, registrations));
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(version_callback_, versions));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::StopOnIOThread() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + context_->RemoveObserver(this);
|
| +}
|
| +
|
| +ServiceWorkerContextWatcher::~ServiceWorkerContextWatcher() {
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::StoreRegistrationInfo(
|
| + const ServiceWorkerRegistrationInfo& registration_info,
|
| + base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>* info_map) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + if (registration_info.registration_id == kInvalidServiceWorkerRegistrationId)
|
| + return;
|
| + info_map->set(registration_info.registration_id,
|
| + scoped_ptr<ServiceWorkerRegistrationInfo>(
|
| + new ServiceWorkerRegistrationInfo(registration_info)));
|
| + StoreVersionInfo(registration_info.active_version);
|
| + StoreVersionInfo(registration_info.waiting_version);
|
| + StoreVersionInfo(registration_info.installing_version);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::StoreVersionInfo(
|
| + const ServiceWorkerVersionInfo& version_info) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + if (version_info.version_id == kInvalidServiceWorkerVersionId)
|
| + return;
|
| + version_info_map_.set(version_info.version_id,
|
| + scoped_ptr<ServiceWorkerVersionInfo>(
|
| + new ServiceWorkerVersionInfo(version_info)));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::SendRegistrationInfo(
|
| + int64 registration_id,
|
| + const GURL& pattern,
|
| + ServiceWorkerRegistrationInfo::DeleteFlag delete_flag) {
|
| + std::vector<ServiceWorkerRegistrationInfo> registrations;
|
| + registrations.push_back(
|
| + ServiceWorkerRegistrationInfo(pattern, registration_id, delete_flag));
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(registration_callback_, registrations));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::SendVersionInfo(
|
| + const ServiceWorkerVersionInfo& version_info) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + std::vector<ServiceWorkerVersionInfo> versions;
|
| + versions.push_back(version_info);
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(version_callback_, versions));
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64 registration_id,
|
| + const GURL& pattern) {
|
| + SendRegistrationInfo(registration_id, pattern,
|
| + ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnNewLiveVersion(int64 version_id,
|
| + int64 registration_id,
|
| + const GURL& script_url) {
|
| + if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id)) {
|
| + DCHECK_EQ(version->registration_id, registration_id);
|
| + DCHECK_EQ(version->script_url, script_url);
|
| + return;
|
| + }
|
| +
|
| + scoped_ptr<ServiceWorkerVersionInfo> version(new ServiceWorkerVersionInfo());
|
| + version->version_id = version_id;
|
| + version->registration_id = registration_id;
|
| + version->script_url = script_url;
|
| + SendVersionInfo(*version);
|
| + if (!IsStoppedAndRedundant(*version))
|
| + version_info_map_.set(version_id, version.Pass());
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnRunningStateChanged(
|
| + int64 version_id,
|
| + content::ServiceWorkerVersion::RunningStatus running_status) {
|
| + ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
|
| + DCHECK(version);
|
| + if (version->running_status == running_status)
|
| + return;
|
| + version->running_status = running_status;
|
| + SendVersionInfo(*version);
|
| + if (IsStoppedAndRedundant(*version))
|
| + version_info_map_.erase(version_id);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnVersionStateChanged(
|
| + int64 version_id,
|
| + content::ServiceWorkerVersion::Status status) {
|
| + ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
|
| + DCHECK(version);
|
| + if (version->status == status)
|
| + return;
|
| + version->status = status;
|
| + SendVersionInfo(*version);
|
| + if (IsStoppedAndRedundant(*version))
|
| + version_info_map_.erase(version_id);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnRegistrationStored(int64 registration_id,
|
| + const GURL& pattern) {
|
| + SendRegistrationInfo(registration_id, pattern,
|
| + ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
|
| +}
|
| +
|
| +void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64 registration_id,
|
| + const GURL& pattern) {
|
| + SendRegistrationInfo(registration_id, pattern,
|
| + ServiceWorkerRegistrationInfo::IS_DELETED);
|
| +}
|
| +
|
| +} // namespace content
|
|
|