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