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

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: Working version 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 ResponseCallback& callback) {
43 // TODO(alecflett): This needs to be synchronous in the fast path,
44 // but asynchronous in the slow path (when the patterns have to be
45 // loaded from disk). For now it is always pessimistically async.
kinuko 2013/11/25 08:17:10 I think it's ok to always call back asynchronously
alecflett 2013/11/26 23:20:00 I completely agree. Its mainly that this is in the
46 PatternToRegistrationMap::const_iterator match =
47 registration_by_pattern_.find(pattern);
48 if (match == registration_by_pattern_.end()) {
49 BrowserThread::PostTask(
50 BrowserThread::IO,
51 FROM_HERE,
52 base::Bind(
53 callback,
54 static_cast<scoped_refptr<ServiceWorkerRegistration> >(NULL)));
55 return;
56 }
57 BrowserThread::PostTask(
58 BrowserThread::IO, FROM_HERE, base::Bind(callback, match->second));
59 }
60
61 void ServiceWorkerStorage::FindRegistrationForDocument(
62 const GURL& document_url,
63 const ResponseCallback& callback) {
64 // TODO(alecflett): This needs to be synchronous in the fast path,
65 // but asynchronous in the slow path (when the patterns have to be
66 // loaded from disk). For now it is always pessimistically async.
67 for (PatternToRegistrationMap::const_iterator it =
68 registration_by_pattern_.begin();
69 it != registration_by_pattern_.end();
70 ++it) {
71 if (PatternMatches(it->first, document_url)) {
72 BrowserThread::PostTask(
73 BrowserThread::IO,
74 FROM_HERE,
75 base::Bind(callback,
76 static_cast<scoped_refptr<ServiceWorkerRegistration> >(
77 it->second)));
78 return;
79 }
80 }
81 BrowserThread::PostTask(
82 BrowserThread::IO,
83 FROM_HERE,
84 base::Bind(callback,
85 static_cast<scoped_refptr<ServiceWorkerRegistration> >(NULL)));
86 }
87
88 namespace {
89 int64 NextRegistrationId() {
90 static int64 worker_id = 0;
91 return worker_id++;
kinuko 2013/11/25 08:17:10 While we're working on in-memory version this coul
alecflett 2013/11/26 23:20:00 I'm not sure of the value of that? This local func
92 }
93 } // namespace
94
95 void ServiceWorkerStorage::Register(const GURL& pattern,
96 const GURL& script_url,
97 const ResponseCallback& callback) {
98 scoped_ptr<ServiceWorkerRegisterJob> job =
99 make_scoped_ptr(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 scoped_refptr<ServiceWorkerRegistration> ServiceWorkerStorage::RegisterInternal(
109 const GURL& pattern,
110 const GURL& script_url) {
111
112 PatternToRegistrationMap::const_iterator current(
113 registration_by_pattern_.find(pattern));
114 DCHECK(current == registration_by_pattern_.end() ||
115 current->second->script_url() == script_url);
116
117 if (current == registration_by_pattern_.end()) {
118 scoped_refptr<ServiceWorkerRegistration> registration(
119 new ServiceWorkerRegistration(
120 pattern, script_url, NextRegistrationId()));
121 // TODO(alecflett): version upgrade path.
122 registration_by_pattern_[pattern] = registration;
123 return registration;
124 }
125
126 return current->second;
127 }
128
129 void ServiceWorkerStorage::EraseJob(ServiceWorkerRegisterJob* job) {
130 ScopedVector<ServiceWorkerRegisterJob>::iterator job_position =
131 registration_jobs_.begin();
132 for (; job_position != registration_jobs_.end(); ++job_position) {
133 if (*job_position == job) {
134 registration_jobs_.erase(job_position);
135 break;
136 }
137 }
138 DCHECK(job_position != registration_jobs_.end())
139 << "Deleting non-existent job.";
140 }
141
142 void ServiceWorkerStorage::UnregisterComplete(
143 const base::Closure& callback,
144 ServiceWorkerRegisterJob* job,
145 ServiceWorkerRegistration* previous_registration) {
146 EraseJob(job);
147 callback.Run();
148 }
149
150 void ServiceWorkerStorage::RegisterComplete(
151 const ResponseCallback& callback,
152 ServiceWorkerRegisterJob* job,
153 ServiceWorkerRegistration* registration) {
154 EraseJob(job);
155 callback.Run(registration);
156 }
157
158 void ServiceWorkerStorage::Unregister(const GURL& pattern,
159 const base::Closure& callback) {
160 scoped_ptr<ServiceWorkerRegisterJob> job =
161 make_scoped_ptr(new ServiceWorkerRegisterJob(
162 weak_factory_.GetWeakPtr(),
163 base::Bind(&ServiceWorkerStorage::UnregisterComplete,
164 weak_factory_.GetWeakPtr(),
165 callback)));
166 job->StartUnregister(pattern);
167 registration_jobs_.push_back(job.release());
168 }
169
170 void ServiceWorkerStorage::UnregisterInternal(const GURL& pattern) {
171 PatternToRegistrationMap::const_iterator match =
172 registration_by_pattern_.find(pattern);
173 if (match != registration_by_pattern_.end()) {
174 match->second->Shutdown();
175 registration_by_pattern_.erase(match);
176 }
177 }
178
179 bool ServiceWorkerStorage::PatternMatches(const GURL& pattern,
180 const GURL& url) {
181 // This is a really basic, naive
182 // TODO(alecflett): Formalize what pattern matches mean.
183 // Temporarily borrowed directly from appcache::Namespace::IsMatch().
184 // We have to escape '?' characters since MatchPattern also treats those
185 // as wildcards which we don't want here, we only do '*'s.
186 std::string pattern_spec(pattern.spec());
187 if (pattern.has_query())
188 ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?");
189 return MatchPattern(url.spec(), pattern_spec);
190 }
191
192 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698