 Chromium Code Reviews
 Chromium Code Reviews Issue 62203007:
  Implement memory-persistent registration  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 62203007:
  Implement memory-persistent registration  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| (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 | |
| OLD | NEW |