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

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: More 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 content {
16
17 const base::FilePath::CharType kServiceWorkerDirectory[] =
18 FILE_PATH_LITERAL("ServiceWorker");
19
20 ServiceWorkerStorage::ServiceWorkerStorage(
21 const base::FilePath& path,
22 quota::QuotaManagerProxy* quota_manager_proxy)
23 : quota_manager_proxy_(quota_manager_proxy), weak_factory_(this) {
24 if (!path.empty())
25 path_ = path.Append(kServiceWorkerDirectory);
26 }
27
28 ServiceWorkerStorage::~ServiceWorkerStorage() {}
29
30 void ServiceWorkerStorage::Shutdown() {
31 for (PatternToRegistrationMap::const_iterator iter =
32 registration_by_pattern_.begin();
33 iter != registration_by_pattern_.end();
34 ++iter) {
35 iter->second->Shutdown();
36 }
37 registration_by_pattern_.clear();
38 }
39
40 void ServiceWorkerStorage::FindRegistrationForPattern(
41 const GURL& pattern,
42 const RegistrationCallback& callback) {
43 PatternToRegistrationMap::const_iterator match =
44 registration_by_pattern_.find(pattern);
45 if (match == registration_by_pattern_.end()) {
46 BrowserThread::PostTask(
47 BrowserThread::IO,
48 FROM_HERE,
49 base::Bind(
50 callback,
51 REGISTRATION_NOT_FOUND,
52 static_cast<scoped_refptr<ServiceWorkerRegistration> >(NULL)));
kinuko 2013/11/27 03:45:23 Just passing scoped_refptr<ServiceWorkerRegistrati
alecflett 2013/12/02 16:11:35 Done.
53 return;
54 }
55 BrowserThread::PostTask(BrowserThread::IO,
56 FROM_HERE,
57 base::Bind(callback, REGISTRATION_OK, match->second));
58 }
59
60 void ServiceWorkerStorage::FindRegistrationForDocument(
61 const GURL& document_url,
62 const RegistrationCallback& callback) {
63 // TODO(alecflett): This needs to be synchronous in the fast path,
64 // but asynchronous in the slow path (when the patterns have to be
65 // loaded from disk). For now it is always pessimistically async.
66 for (PatternToRegistrationMap::const_iterator it =
67 registration_by_pattern_.begin();
68 it != registration_by_pattern_.end();
69 ++it) {
70 if (PatternMatches(it->first, document_url)) {
71 BrowserThread::PostTask(
72 BrowserThread::IO,
73 FROM_HERE,
74 base::Bind(callback,
75 REGISTRATION_OK,
76 static_cast<scoped_refptr<ServiceWorkerRegistration> >(
77 it->second)));
kinuko 2013/11/27 03:45:23 No need of static_cast
alecflett 2013/12/02 16:11:35 Done.
78 return;
79 }
80 }
81 BrowserThread::PostTask(
82 BrowserThread::IO,
83 FROM_HERE,
84 base::Bind(callback,
85 REGISTRATION_NOT_FOUND,
86 static_cast<scoped_refptr<ServiceWorkerRegistration> >(NULL)));
kinuko 2013/11/27 03:45:23 ditto
alecflett 2013/12/02 16:11:35 Done.
87 }
88
89 namespace {
90 int64 NextRegistrationId() {
91 static int64 worker_id = 0;
92 return worker_id++;
93 }
kinuko 2013/11/27 03:45:23 I suggested having this method as a member method
alecflett 2013/12/02 16:11:35 I think we'll have some variation on it, but it it
94 } // namespace
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());
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 break;
kinuko 2013/11/27 03:45:23 We could return here, and
alecflett 2013/12/02 16:11:35 Done.
171 }
172 }
173 DCHECK(found) << "Deleting non-existent job. ";
kinuko 2013/11/27 03:45:23 put NOTREACHED() << "..." instead of checking foun
alecflett 2013/12/02 16:11:35 Done.
174 }
175
176 void ServiceWorkerStorage::UnregisterComplete(
177 const UnregistrationCallback& callback,
178 ServiceWorkerRegisterJob* job,
179 RegistrationStatus 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 RegistrationStatus 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