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

Side by Side Diff: content/browser/service_worker/service_worker_storage.cc

Issue 62203007: Implement memory-persistent registration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix variable that we don't need anymore Created 7 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/service_worker/service_worker_storage.h"
6
7 #include <string>
8
9 #include "base/strings/string_util.h"
10 #include "content/browser/service_worker/service_worker_register_job.h"
11 #include "content/browser/service_worker/service_worker_registration.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "webkit/browser/quota/quota_manager.h"
14
15 namespace {
16 // This is temporary until we figure out how registration ids will be
17 // calculated.
18 int64 NextRegistrationId() {
19 static int64 worker_id = 0;
20 return worker_id++;
21 }
22 } // namespace
23
24 namespace content {
25
26 const base::FilePath::CharType kServiceWorkerDirectory[] =
27 FILE_PATH_LITERAL("ServiceWorker");
28
29 ServiceWorkerStorage::ServiceWorkerStorage(
30 const base::FilePath& path,
31 quota::QuotaManagerProxy* quota_manager_proxy)
32 : quota_manager_proxy_(quota_manager_proxy), weak_factory_(this) {
33 if (!path.empty())
34 path_ = path.Append(kServiceWorkerDirectory);
35 }
36
37 ServiceWorkerStorage::~ServiceWorkerStorage() {
38 for (PatternToRegistrationMap::const_iterator iter =
39 registration_by_pattern_.begin();
40 iter != registration_by_pattern_.end();
41 ++iter) {
42 iter->second->Shutdown();
43 }
44 registration_by_pattern_.clear();
45 }
46
47 void ServiceWorkerStorage::FindRegistrationForPattern(
48 const GURL& pattern,
49 const RegistrationCallback& callback) {
50 PatternToRegistrationMap::const_iterator match =
51 registration_by_pattern_.find(pattern);
52 if (match == registration_by_pattern_.end()) {
53 BrowserThread::PostTask(
54 BrowserThread::IO,
55 FROM_HERE,
56 base::Bind(callback,
57 REGISTRATION_NOT_FOUND,
58 scoped_refptr<ServiceWorkerRegistration>()));
59 return;
60 }
61 BrowserThread::PostTask(BrowserThread::IO,
62 FROM_HERE,
63 base::Bind(callback, REGISTRATION_OK, match->second));
64 }
65
66 void ServiceWorkerStorage::FindRegistrationForDocument(
67 const GURL& document_url,
68 const RegistrationCallback& callback) {
69 // TODO(alecflett): This needs to be synchronous in the fast path,
70 // but asynchronous in the slow path (when the patterns have to be
71 // loaded from disk). For now it is always pessimistically async.
72 for (PatternToRegistrationMap::const_iterator it =
73 registration_by_pattern_.begin();
74 it != registration_by_pattern_.end();
75 ++it) {
76 if (PatternMatches(it->first, document_url)) {
77 BrowserThread::PostTask(
78 BrowserThread::IO,
79 FROM_HERE,
80 base::Bind(callback,
81 REGISTRATION_OK,
82 scoped_refptr<ServiceWorkerRegistration>(it->second)));
83 return;
84 }
85 }
86 BrowserThread::PostTask(
87 BrowserThread::IO,
88 FROM_HERE,
89 base::Bind(callback,
90 REGISTRATION_NOT_FOUND,
91 scoped_refptr<ServiceWorkerRegistration>()));
92 }
93
94 void ServiceWorkerStorage::Register(const GURL& pattern,
95 const GURL& script_url,
96 const RegistrationCallback& callback) {
97 scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
98 weak_factory_.GetWeakPtr(),
99 base::Bind(&ServiceWorkerStorage::RegisterComplete,
100 weak_factory_.GetWeakPtr(),
101 callback)));
102 job->StartRegister(pattern, script_url);
103 registration_jobs_.push_back(job.release());
104 }
105
106 void ServiceWorkerStorage::Unregister(const GURL& pattern,
107 const UnregistrationCallback& callback) {
108 scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
109 weak_factory_.GetWeakPtr(),
110 base::Bind(&ServiceWorkerStorage::UnregisterComplete,
111 weak_factory_.GetWeakPtr(),
112 callback)));
113 job->StartUnregister(pattern);
114 registration_jobs_.push_back(job.release());
115 }
116
117 scoped_refptr<ServiceWorkerRegistration> ServiceWorkerStorage::RegisterInternal(
118 const GURL& pattern,
119 const GURL& script_url) {
120
121 PatternToRegistrationMap::const_iterator current(
122 registration_by_pattern_.find(pattern));
123 DCHECK(current == registration_by_pattern_.end() ||
124 current->second->script_url() == script_url);
125
126 if (current == registration_by_pattern_.end()) {
127 scoped_refptr<ServiceWorkerRegistration> registration(
128 new ServiceWorkerRegistration(
129 pattern, script_url, NextRegistrationId()));
130 // TODO(alecflett): version upgrade path.
131 registration_by_pattern_[pattern] = registration;
132 return registration;
133 }
134
135 return current->second;
136 }
137
138 void ServiceWorkerStorage::UnregisterInternal(const GURL& pattern) {
139 PatternToRegistrationMap::iterator match =
140 registration_by_pattern_.find(pattern);
141 if (match != registration_by_pattern_.end()) {
142 match->second->Shutdown();
143 registration_by_pattern_.erase(match);
144 }
145 }
146
147 bool ServiceWorkerStorage::PatternMatches(const GURL& pattern,
148 const GURL& url) {
149 // This is a really basic, naive
150 // TODO(alecflett): Formalize what pattern matches mean.
151 // Temporarily borrowed directly from appcache::Namespace::IsMatch().
152 // We have to escape '?' characters since MatchPattern also treats those
153 // as wildcards which we don't want here, we only do '*'s.
154 std::string pattern_spec(pattern.spec());
155 if (pattern.has_query())
156 ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?");
157 return MatchPattern(url.spec(), pattern_spec);
158 }
159
160 void ServiceWorkerStorage::EraseJob(ServiceWorkerRegisterJob* job) {
161 ScopedVector<ServiceWorkerRegisterJob>::iterator job_position =
162 registration_jobs_.begin();
163 for (; job_position != registration_jobs_.end(); ++job_position) {
164 if (*job_position == job) {
165 registration_jobs_.erase(job_position);
166 return;
167 }
168 }
169 NOTREACHED() << "Deleting non-existent job. ";
170 }
171
172 void ServiceWorkerStorage::UnregisterComplete(
173 const UnregistrationCallback& callback,
174 ServiceWorkerRegisterJob* job,
175 ServiceWorkerRegistrationStatus status,
176 ServiceWorkerRegistration* previous_registration) {
177 callback.Run(status);
178 EraseJob(job);
179 }
180
181 void ServiceWorkerStorage::RegisterComplete(
182 const RegistrationCallback& callback,
183 ServiceWorkerRegisterJob* job,
184 ServiceWorkerRegistrationStatus status,
185 ServiceWorkerRegistration* registration) {
186 callback.Run(status, registration);
187 EraseJob(job);
188 }
189
190 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698