 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 { | |
| 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 | |
| OLD | NEW |