This source file includes following definitions.
- RunSoon
- quota_manager_proxy_
- FindRegistrationForPattern
- FindRegistrationForDocument
- GetAllRegistrations
- FindRegistrationForId
- StoreRegistration
- DeleteRegistration
- NewRegistrationId
- NewVersionId
- PatternMatches
#include "content/browser/service_worker/service_worker_storage.h"
#include <string>
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/browser/quota/quota_manager_proxy.h"
namespace content {
namespace {
void RunSoon(const base::Closure& closure) {
base::MessageLoop::current()->PostTask(FROM_HERE, closure);
}
const base::FilePath::CharType kServiceWorkerDirectory[] =
FILE_PATH_LITERAL("ServiceWorker");
}
ServiceWorkerStorage::ServiceWorkerStorage(
const base::FilePath& path,
quota::QuotaManagerProxy* quota_manager_proxy)
: last_registration_id_(0),
last_version_id_(0),
quota_manager_proxy_(quota_manager_proxy) {
if (!path.empty())
path_ = path.Append(kServiceWorkerDirectory);
}
ServiceWorkerStorage::~ServiceWorkerStorage() {
for (PatternToRegistrationMap::const_iterator iter =
registration_by_pattern_.begin();
iter != registration_by_pattern_.end();
++iter) {
iter->second->Shutdown();
}
registration_by_pattern_.clear();
}
void ServiceWorkerStorage::FindRegistrationForPattern(
const GURL& pattern,
const FindRegistrationCallback& callback) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NOT_FOUND;
scoped_refptr<ServiceWorkerRegistration> found;
PatternToRegistrationMap::const_iterator match =
registration_by_pattern_.find(pattern);
if (match != registration_by_pattern_.end()) {
status = SERVICE_WORKER_OK;
found = match->second;
}
RunSoon(base::Bind(callback, status, found));
}
void ServiceWorkerStorage::FindRegistrationForDocument(
const GURL& document_url,
const FindRegistrationCallback& callback) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NOT_FOUND;
scoped_refptr<ServiceWorkerRegistration> found;
for (PatternToRegistrationMap::const_iterator it =
registration_by_pattern_.begin();
it != registration_by_pattern_.end();
++it) {
if (PatternMatches(it->first, document_url)) {
status = SERVICE_WORKER_OK;
found = it->second;
break;
}
}
RunSoon(base::Bind(callback, status, found));
}
void ServiceWorkerStorage::GetAllRegistrations(
const GetAllRegistrationInfosCallback& callback) {
std::vector<ServiceWorkerRegistrationInfo> registrations;
for (PatternToRegistrationMap::const_iterator it =
registration_by_pattern_.begin();
it != registration_by_pattern_.end();
++it) {
ServiceWorkerRegistration* registration(it->second.get());
registrations.push_back(registration->GetInfo());
}
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, base::Bind(callback, registrations));
}
void ServiceWorkerStorage::FindRegistrationForId(
int64 registration_id,
const FindRegistrationCallback& callback) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NOT_FOUND;
scoped_refptr<ServiceWorkerRegistration> found;
for (PatternToRegistrationMap::const_iterator it =
registration_by_pattern_.begin();
it != registration_by_pattern_.end();
++it) {
if (registration_id == it->second->id()) {
status = SERVICE_WORKER_OK;
found = it->second;
break;
}
}
RunSoon(base::Bind(callback, status, found));
}
void ServiceWorkerStorage::StoreRegistration(
ServiceWorkerRegistration* registration,
const StatusCallback& callback) {
DCHECK(registration);
PatternToRegistrationMap::const_iterator current(
registration_by_pattern_.find(registration->pattern()));
if (current != registration_by_pattern_.end() &&
current->second->script_url() != registration->script_url()) {
RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_EXISTS));
return;
}
registration_by_pattern_[registration->pattern()] = registration;
RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
}
void ServiceWorkerStorage::DeleteRegistration(
const GURL& pattern,
const StatusCallback& callback) {
PatternToRegistrationMap::iterator match =
registration_by_pattern_.find(pattern);
if (match == registration_by_pattern_.end()) {
RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
return;
}
registration_by_pattern_.erase(match);
RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
}
int64 ServiceWorkerStorage::NewRegistrationId() {
return ++last_registration_id_;
}
int64 ServiceWorkerStorage::NewVersionId() {
return ++last_version_id_;
}
bool ServiceWorkerStorage::PatternMatches(const GURL& pattern,
const GURL& url) {
std::string pattern_spec(pattern.spec());
if (pattern.has_query())
ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?");
return MatchPattern(url.spec(), pattern_spec);
}
}