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

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: Address kinuko's comments 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
39 void ServiceWorkerStorage::Shutdown() {
40 for (PatternToRegistrationMap::const_iterator iter =
41 registration_by_pattern_.begin();
42 iter != registration_by_pattern_.end();
43 ++iter) {
44 iter->second->Shutdown();
45 }
46 registration_by_pattern_.clear();
47 }
48
49 void ServiceWorkerStorage::FindRegistrationForPattern(
50 const GURL& pattern,
51 const RegistrationCallback& callback) {
52 PatternToRegistrationMap::const_iterator match =
53 registration_by_pattern_.find(pattern);
54 if (match == registration_by_pattern_.end()) {
55 BrowserThread::PostTask(
56 BrowserThread::IO,
57 FROM_HERE,
58 base::Bind(callback,
59 REGISTRATION_NOT_FOUND,
60 scoped_refptr<ServiceWorkerRegistration>()));
61 return;
62 }
63 BrowserThread::PostTask(BrowserThread::IO,
64 FROM_HERE,
65 base::Bind(callback, REGISTRATION_OK, match->second));
66 }
67
68 void ServiceWorkerStorage::FindRegistrationForDocument(
69 const GURL& document_url,
70 const RegistrationCallback& callback) {
71 // TODO(alecflett): This needs to be synchronous in the fast path,
72 // but asynchronous in the slow path (when the patterns have to be
73 // loaded from disk). For now it is always pessimistically async.
74 for (PatternToRegistrationMap::const_iterator it =
75 registration_by_pattern_.begin();
76 it != registration_by_pattern_.end();
77 ++it) {
78 if (PatternMatches(it->first, document_url)) {
79 BrowserThread::PostTask(
80 BrowserThread::IO,
81 FROM_HERE,
82 base::Bind(callback,
83 REGISTRATION_OK,
84 scoped_refptr<ServiceWorkerRegistration>(it->second)));
85 return;
86 }
87 }
88 BrowserThread::PostTask(
89 BrowserThread::IO,
90 FROM_HERE,
91 base::Bind(callback,
92 REGISTRATION_NOT_FOUND,
93 scoped_refptr<ServiceWorkerRegistration>()));
94 }
95
96 void ServiceWorkerStorage::Register(const GURL& pattern,
97 const GURL& script_url,
98 const RegistrationCallback& callback) {
99 scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
100 weak_factory_.GetWeakPtr(),
101 base::Bind(&ServiceWorkerStorage::RegisterComplete,
102 weak_factory_.GetWeakPtr(),
103 callback)));
104 job->StartRegister(pattern, script_url);
105 registration_jobs_.push_back(job.release());
kinuko 2013/12/04 13:04:29 We use multiple async calls to FindRegistration an
alecflett 2013/12/06 05:43:33 ultimately registration_jobs_ will evolve to handl
kinuko 2013/12/06 15:24:49 Ah, my comment was probably not clear enough, I'm
106 }
107
108 void ServiceWorkerStorage::Unregister(const GURL& pattern,
109 const UnregistrationCallback& callback) {
110 scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
111 weak_factory_.GetWeakPtr(),
112 base::Bind(&ServiceWorkerStorage::UnregisterComplete,
113 weak_factory_.GetWeakPtr(),
114 callback)));
115 job->StartUnregister(pattern);
116 registration_jobs_.push_back(job.release());
117 }
118
119 scoped_refptr<ServiceWorkerRegistration> ServiceWorkerStorage::RegisterInternal(
120 const GURL& pattern,
121 const GURL& script_url) {
122
123 PatternToRegistrationMap::const_iterator current(
124 registration_by_pattern_.find(pattern));
125 DCHECK(current == registration_by_pattern_.end() ||
126 current->second->script_url() == script_url);
127
128 if (current == registration_by_pattern_.end()) {
129 scoped_refptr<ServiceWorkerRegistration> registration(
130 new ServiceWorkerRegistration(
131 pattern, script_url, NextRegistrationId()));
132 // TODO(alecflett): version upgrade path.
133 registration_by_pattern_[pattern] = registration;
134 return registration;
135 }
136
137 return current->second;
138 }
139
140 void ServiceWorkerStorage::UnregisterInternal(const GURL& pattern) {
141 PatternToRegistrationMap::const_iterator match =
142 registration_by_pattern_.find(pattern);
143 if (match != registration_by_pattern_.end()) {
144 match->second->Shutdown();
145 registration_by_pattern_.erase(match);
146 }
147 }
148
149 bool ServiceWorkerStorage::PatternMatches(const GURL& pattern,
150 const GURL& url) {
151 // This is a really basic, naive
152 // TODO(alecflett): Formalize what pattern matches mean.
153 // Temporarily borrowed directly from appcache::Namespace::IsMatch().
154 // We have to escape '?' characters since MatchPattern also treats those
155 // as wildcards which we don't want here, we only do '*'s.
156 std::string pattern_spec(pattern.spec());
157 if (pattern.has_query())
158 ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?");
159 return MatchPattern(url.spec(), pattern_spec);
160 }
161
162 void ServiceWorkerStorage::EraseJob(ServiceWorkerRegisterJob* job) {
163 ScopedVector<ServiceWorkerRegisterJob>::iterator job_position =
164 registration_jobs_.begin();
165 bool found = false;
166 for (; job_position != registration_jobs_.end(); ++job_position) {
167 if (*job_position == job) {
168 found = true;
169 registration_jobs_.erase(job_position);
170 return;
171 }
172 }
173 NOTREACHED() << "Deleting non-existent job. ";
174 }
175
176 void ServiceWorkerStorage::UnregisterComplete(
177 const UnregistrationCallback& callback,
178 ServiceWorkerRegisterJob* job,
179 ServiceWorkerRegistrationStatus status,
180 ServiceWorkerRegistration* previous_registration) {
181 callback.Run(status);
182 EraseJob(job);
183 }
184
185 void ServiceWorkerStorage::RegisterComplete(
186 const RegistrationCallback& callback,
187 ServiceWorkerRegisterJob* job,
188 ServiceWorkerRegistrationStatus status,
189 ServiceWorkerRegistration* registration) {
190 callback.Run(status, registration);
191 EraseJob(job);
192 }
193
194 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698