1// Copyright 2014 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_cache_listener.h" 6 7#include "base/bind.h" 8#include "base/debug/trace_event.h" 9#include "base/strings/utf_string_conversions.h" 10#include "content/browser/service_worker/service_worker_cache_storage_manager.h" 11#include "content/browser/service_worker/service_worker_context_core.h" 12#include "content/browser/service_worker/service_worker_version.h" 13#include "content/common/service_worker/service_worker_messages.h" 14#include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h" 15 16namespace content { 17 18using blink::WebServiceWorkerCacheError; 19 20namespace { 21 22WebServiceWorkerCacheError ToWebServiceWorkerCacheError( 23 ServiceWorkerCacheStorage::CacheStorageError err) { 24 switch (err) { 25 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR: 26 NOTREACHED(); 27 return blink::WebServiceWorkerCacheErrorNotImplemented; 28 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_IMPLEMENTED: 29 return blink::WebServiceWorkerCacheErrorNotImplemented; 30 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND: 31 return blink::WebServiceWorkerCacheErrorNotFound; 32 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EXISTS: 33 return blink::WebServiceWorkerCacheErrorExists; 34 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_STORAGE: 35 // TODO(jkarlin): Changethis to CACHE_STORAGE_ERROR_STORAGE once that's 36 // added. 37 return blink::WebServiceWorkerCacheErrorNotFound; 38 case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_CLOSING: 39 // TODO(jkarlin): Update this to CACHE_STORAGE_ERROR_CLOSING once that's 40 // added. 41 return blink::WebServiceWorkerCacheErrorNotFound; 42 } 43 NOTREACHED(); 44 return blink::WebServiceWorkerCacheErrorNotImplemented; 45} 46 47} // namespace 48 49ServiceWorkerCacheListener::ServiceWorkerCacheListener( 50 ServiceWorkerVersion* version, 51 base::WeakPtr<ServiceWorkerContextCore> context) 52 : version_(version), 53 context_(context), 54 next_cache_id_(0), 55 weak_factory_(this) { 56} 57 58ServiceWorkerCacheListener::~ServiceWorkerCacheListener() { 59} 60 61bool ServiceWorkerCacheListener::OnMessageReceived( 62 const IPC::Message& message) { 63 bool handled = true; 64 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerCacheListener, message) 65 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageGet, 66 OnCacheStorageGet) 67 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageHas, 68 OnCacheStorageHas) 69 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageCreate, 70 OnCacheStorageCreate) 71 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageDelete, 72 OnCacheStorageDelete) 73 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageKeys, 74 OnCacheStorageKeys) 75 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheMatch, 76 OnCacheMatch) 77 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheMatchAll, 78 OnCacheMatchAll) 79 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheKeys, 80 OnCacheKeys) 81 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheBatch, 82 OnCacheBatch) 83 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheClosed, 84 OnCacheClosed) 85 IPC_MESSAGE_UNHANDLED(handled = false) 86 IPC_END_MESSAGE_MAP() 87 88 return handled; 89} 90 91void ServiceWorkerCacheListener::OnCacheStorageGet( 92 int request_id, 93 const base::string16& cache_name) { 94 TRACE_EVENT0("ServiceWorker", 95 "ServiceWorkerCacheListener::OnCacheStorageGet"); 96 context_->cache_manager()->GetCache( 97 version_->scope().GetOrigin(), 98 base::UTF16ToUTF8(cache_name), 99 base::Bind(&ServiceWorkerCacheListener::OnCacheStorageGetCallback, 100 weak_factory_.GetWeakPtr(), 101 request_id)); 102} 103 104void ServiceWorkerCacheListener::OnCacheStorageHas( 105 int request_id, 106 const base::string16& cache_name) { 107 TRACE_EVENT0("ServiceWorker", 108 "ServiceWorkerCacheListener::OnCacheStorageHas"); 109 context_->cache_manager()->HasCache( 110 version_->scope().GetOrigin(), 111 base::UTF16ToUTF8(cache_name), 112 base::Bind(&ServiceWorkerCacheListener::OnCacheStorageHasCallback, 113 weak_factory_.GetWeakPtr(), 114 request_id)); 115} 116 117void ServiceWorkerCacheListener::OnCacheStorageCreate( 118 int request_id, 119 const base::string16& cache_name) { 120 TRACE_EVENT0("ServiceWorker", 121 "ServiceWorkerCacheListener::OnCacheStorageCreate"); 122 context_->cache_manager()->CreateCache( 123 version_->scope().GetOrigin(), 124 base::UTF16ToUTF8(cache_name), 125 base::Bind(&ServiceWorkerCacheListener::OnCacheStorageCreateCallback, 126 weak_factory_.GetWeakPtr(), 127 request_id)); 128} 129 130void ServiceWorkerCacheListener::OnCacheStorageDelete( 131 int request_id, 132 const base::string16& cache_name) { 133 TRACE_EVENT0("ServiceWorker", 134 "ServiceWorkerCacheListener::OnCacheStorageDelete"); 135 context_->cache_manager()->DeleteCache( 136 version_->scope().GetOrigin(), 137 base::UTF16ToUTF8(cache_name), 138 base::Bind(&ServiceWorkerCacheListener::OnCacheStorageDeleteCallback, 139 weak_factory_.GetWeakPtr(), 140 request_id)); 141} 142 143void ServiceWorkerCacheListener::OnCacheStorageKeys(int request_id) { 144 TRACE_EVENT0("ServiceWorker", 145 "ServiceWorkerCacheListener::OnCacheStorageKeys"); 146 context_->cache_manager()->EnumerateCaches( 147 version_->scope().GetOrigin(), 148 base::Bind(&ServiceWorkerCacheListener::OnCacheStorageKeysCallback, 149 weak_factory_.GetWeakPtr(), 150 request_id)); 151} 152 153void ServiceWorkerCacheListener::OnCacheMatch( 154 int request_id, 155 int cache_id, 156 const ServiceWorkerFetchRequest& request, 157 const ServiceWorkerCacheQueryParams& match_params) { 158 // TODO(gavinp,jkarlin): Implement this method. 159 Send(ServiceWorkerMsg_CacheMatchError( 160 request_id, blink::WebServiceWorkerCacheErrorNotImplemented)); 161} 162 163void ServiceWorkerCacheListener::OnCacheMatchAll( 164 int request_id, 165 int cache_id, 166 const ServiceWorkerFetchRequest& request, 167 const ServiceWorkerCacheQueryParams& match_params) { 168 // TODO(gavinp,jkarlin): Implement this method. 169 Send(ServiceWorkerMsg_CacheMatchAllError( 170 request_id, blink::WebServiceWorkerCacheErrorNotImplemented)); 171} 172 173void ServiceWorkerCacheListener::OnCacheKeys( 174 int request_id, 175 int cache_id, 176 const ServiceWorkerFetchRequest& request, 177 const ServiceWorkerCacheQueryParams& match_params) { 178 // TODO(gavinp,jkarlin): Implement this method. 179 Send(ServiceWorkerMsg_CacheKeysError( 180 request_id, blink::WebServiceWorkerCacheErrorNotImplemented)); 181} 182 183void ServiceWorkerCacheListener::OnCacheBatch( 184 int request_id, 185 int cache_id, 186 const std::vector<ServiceWorkerBatchOperation>& operations) { 187 // TODO(gavinp,jkarlin): Implement this method. 188 Send(ServiceWorkerMsg_CacheBatchError( 189 request_id, blink::WebServiceWorkerCacheErrorNotImplemented)); 190} 191 192void ServiceWorkerCacheListener::OnCacheClosed(int cache_id) { 193 // TODO(gavinp,jkarlin): Implement this method. 194} 195 196void ServiceWorkerCacheListener::Send(const IPC::Message& message) { 197 version_->embedded_worker()->SendMessage(message); 198} 199 200void ServiceWorkerCacheListener::OnCacheStorageGetCallback( 201 int request_id, 202 const scoped_refptr<ServiceWorkerCache>& cache, 203 ServiceWorkerCacheStorage::CacheStorageError error) { 204 if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { 205 Send(ServiceWorkerMsg_CacheStorageGetError( 206 request_id, ToWebServiceWorkerCacheError(error))); 207 return; 208 } 209 210 CacheID cache_id = StoreCacheReference(cache); 211 Send(ServiceWorkerMsg_CacheStorageGetSuccess(request_id, cache_id)); 212} 213 214void ServiceWorkerCacheListener::OnCacheStorageHasCallback( 215 int request_id, 216 bool has_cache, 217 ServiceWorkerCacheStorage::CacheStorageError error) { 218 if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { 219 Send(ServiceWorkerMsg_CacheStorageHasError( 220 request_id, ToWebServiceWorkerCacheError(error))); 221 return; 222 } 223 if (!has_cache) { 224 Send(ServiceWorkerMsg_CacheStorageHasError( 225 request_id, 226 blink::WebServiceWorkerCacheErrorNotFound)); 227 return; 228 } 229 Send(ServiceWorkerMsg_CacheStorageHasSuccess(request_id)); 230} 231 232void ServiceWorkerCacheListener::OnCacheStorageCreateCallback( 233 int request_id, 234 const scoped_refptr<ServiceWorkerCache>& cache, 235 ServiceWorkerCacheStorage::CacheStorageError error) { 236 if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { 237 Send(ServiceWorkerMsg_CacheStorageCreateError( 238 request_id, ToWebServiceWorkerCacheError(error))); 239 return; 240 } 241 CacheID cache_id = StoreCacheReference(cache); 242 Send(ServiceWorkerMsg_CacheStorageCreateSuccess(request_id, cache_id)); 243} 244 245void ServiceWorkerCacheListener::OnCacheStorageDeleteCallback( 246 int request_id, 247 bool deleted, 248 ServiceWorkerCacheStorage::CacheStorageError error) { 249 if (!deleted || 250 error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { 251 Send(ServiceWorkerMsg_CacheStorageDeleteError( 252 request_id, ToWebServiceWorkerCacheError(error))); 253 return; 254 } 255 Send(ServiceWorkerMsg_CacheStorageDeleteSuccess(request_id)); 256} 257 258void ServiceWorkerCacheListener::OnCacheStorageKeysCallback( 259 int request_id, 260 const std::vector<std::string>& strings, 261 ServiceWorkerCacheStorage::CacheStorageError error) { 262 if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { 263 Send(ServiceWorkerMsg_CacheStorageKeysError( 264 request_id, ToWebServiceWorkerCacheError(error))); 265 return; 266 } 267 268 std::vector<base::string16> string16s; 269 for (size_t i = 0, max = strings.size(); i < max; ++i) { 270 string16s.push_back(base::UTF8ToUTF16(strings[i])); 271 } 272 Send(ServiceWorkerMsg_CacheStorageKeysSuccess(request_id, string16s)); 273} 274 275ServiceWorkerCacheListener::CacheID 276ServiceWorkerCacheListener::StoreCacheReference( 277 const scoped_refptr<ServiceWorkerCache>& cache) { 278 int cache_id = next_cache_id_++; 279 id_to_cache_map_[cache_id] = cache; 280 return cache_id; 281} 282 283void ServiceWorkerCacheListener::DropCacheReference(CacheID cache_id) { 284 id_to_cache_map_.erase(cache_id); 285} 286 287} // namespace content 288