Add ICU message format support
[chromium-blink-merge.git] / content / browser / cache_storage / cache_storage_dispatcher_host.cc
blob79d3f5a884033aab3533b9edcdef23d565608aa0
1 // Copyright 2015 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.
5 #include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/trace_event/trace_event.h"
12 #include "content/browser/bad_message.h"
13 #include "content/browser/cache_storage/cache_storage_cache.h"
14 #include "content/browser/cache_storage/cache_storage_context_impl.h"
15 #include "content/browser/cache_storage/cache_storage_manager.h"
16 #include "content/common/cache_storage/cache_storage_messages.h"
17 #include "content/public/browser/content_browser_client.h"
18 #include "storage/browser/blob/blob_data_handle.h"
19 #include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h"
21 namespace content {
23 namespace {
25 const uint32 kFilteredMessageClasses[] = {CacheStorageMsgStart};
27 blink::WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
28 CacheStorageError err) {
29 switch (err) {
30 case CACHE_STORAGE_OK:
31 NOTREACHED();
32 return blink::WebServiceWorkerCacheErrorNotImplemented;
33 case CACHE_STORAGE_ERROR_EXISTS:
34 return blink::WebServiceWorkerCacheErrorExists;
35 case CACHE_STORAGE_ERROR_STORAGE:
36 // TODO(nhiroki): Add WebServiceWorkerCacheError equivalent to
37 // CACHE_STORAGE_ERROR_STORAGE.
38 return blink::WebServiceWorkerCacheErrorNotFound;
39 case CACHE_STORAGE_ERROR_NOT_FOUND:
40 return blink::WebServiceWorkerCacheErrorNotFound;
42 NOTREACHED();
43 return blink::WebServiceWorkerCacheErrorNotImplemented;
46 } // namespace
48 CacheStorageDispatcherHost::CacheStorageDispatcherHost()
49 : BrowserMessageFilter(kFilteredMessageClasses,
50 arraysize(kFilteredMessageClasses)) {
53 CacheStorageDispatcherHost::~CacheStorageDispatcherHost() {
56 void CacheStorageDispatcherHost::Init(CacheStorageContextImpl* context) {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI);
58 BrowserThread::PostTask(
59 BrowserThread::IO, FROM_HERE,
60 base::Bind(&CacheStorageDispatcherHost::CreateCacheListener, this,
61 make_scoped_refptr(context)));
64 void CacheStorageDispatcherHost::OnDestruct() const {
65 BrowserThread::DeleteOnIOThread::Destruct(this);
68 bool CacheStorageDispatcherHost::OnMessageReceived(
69 const IPC::Message& message) {
70 DCHECK_CURRENTLY_ON(BrowserThread::IO);
72 bool handled = true;
73 IPC_BEGIN_MESSAGE_MAP(CacheStorageDispatcherHost, message)
74 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageHas, OnCacheStorageHas)
75 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageOpen, OnCacheStorageOpen)
76 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageDelete,
77 OnCacheStorageDelete)
78 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageKeys, OnCacheStorageKeys)
79 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageMatch,
80 OnCacheStorageMatch)
81 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatch, OnCacheMatch)
82 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatchAll, OnCacheMatchAll)
83 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheKeys, OnCacheKeys)
84 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheBatch, OnCacheBatch)
85 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheClosed, OnCacheClosed)
86 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_BlobDataHandled, OnBlobDataHandled)
87 IPC_MESSAGE_UNHANDLED(handled = false)
88 IPC_END_MESSAGE_MAP()
90 if (!handled)
91 bad_message::ReceivedBadMessage(this, bad_message::CSDH_NOT_RECOGNIZED);
92 return handled;
95 void CacheStorageDispatcherHost::CreateCacheListener(
96 CacheStorageContextImpl* context) {
97 DCHECK_CURRENTLY_ON(BrowserThread::IO);
98 context_ = context;
101 void CacheStorageDispatcherHost::OnCacheStorageHas(
102 int thread_id,
103 int request_id,
104 const GURL& origin,
105 const base::string16& cache_name) {
106 TRACE_EVENT0("CacheStorage", "CacheStorageDispatcherHost::OnCacheStorageHas");
107 context_->cache_manager()->HasCache(
108 origin, base::UTF16ToUTF8(cache_name),
109 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageHasCallback, this,
110 thread_id, request_id));
113 void CacheStorageDispatcherHost::OnCacheStorageOpen(
114 int thread_id,
115 int request_id,
116 const GURL& origin,
117 const base::string16& cache_name) {
118 TRACE_EVENT0("CacheStorage",
119 "CacheStorageDispatcherHost::OnCacheStorageOpen");
120 context_->cache_manager()->OpenCache(
121 origin, base::UTF16ToUTF8(cache_name),
122 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageOpenCallback, this,
123 thread_id, request_id));
126 void CacheStorageDispatcherHost::OnCacheStorageDelete(
127 int thread_id,
128 int request_id,
129 const GURL& origin,
130 const base::string16& cache_name) {
131 TRACE_EVENT0("CacheStorage",
132 "CacheStorageDispatcherHost::OnCacheStorageDelete");
133 context_->cache_manager()->DeleteCache(
134 origin, base::UTF16ToUTF8(cache_name),
135 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageDeleteCallback,
136 this, thread_id, request_id));
139 void CacheStorageDispatcherHost::OnCacheStorageKeys(int thread_id,
140 int request_id,
141 const GURL& origin) {
142 TRACE_EVENT0("CacheStorage",
143 "CacheStorageDispatcherHost::OnCacheStorageKeys");
144 context_->cache_manager()->EnumerateCaches(
145 origin,
146 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageKeysCallback, this,
147 thread_id, request_id));
150 void CacheStorageDispatcherHost::OnCacheStorageMatch(
151 int thread_id,
152 int request_id,
153 const GURL& origin,
154 const ServiceWorkerFetchRequest& request,
155 const CacheStorageCacheQueryParams& match_params) {
156 TRACE_EVENT0("CacheStorage",
157 "CacheStorageDispatcherHost::OnCacheStorageMatch");
159 scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
160 new ServiceWorkerFetchRequest(request.url, request.method,
161 request.headers, request.referrer,
162 request.is_reload));
164 if (match_params.cache_name.empty()) {
165 context_->cache_manager()->MatchAllCaches(
166 origin, scoped_request.Pass(),
167 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback,
168 this, thread_id, request_id));
169 return;
171 context_->cache_manager()->MatchCache(
172 origin, base::UTF16ToUTF8(match_params.cache_name), scoped_request.Pass(),
173 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback, this,
174 thread_id, request_id));
177 void CacheStorageDispatcherHost::OnCacheMatch(
178 int thread_id,
179 int request_id,
180 int cache_id,
181 const ServiceWorkerFetchRequest& request,
182 const CacheStorageCacheQueryParams& match_params) {
183 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
184 if (it == id_to_cache_map_.end()) {
185 Send(new CacheStorageMsg_CacheMatchError(
186 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
187 return;
190 scoped_refptr<CacheStorageCache> cache = it->second;
191 scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
192 new ServiceWorkerFetchRequest(request.url, request.method,
193 request.headers, request.referrer,
194 request.is_reload));
195 cache->Match(scoped_request.Pass(),
196 base::Bind(&CacheStorageDispatcherHost::OnCacheMatchCallback,
197 this, thread_id, request_id, cache));
200 void CacheStorageDispatcherHost::OnCacheMatchAll(
201 int thread_id,
202 int request_id,
203 int cache_id,
204 const ServiceWorkerFetchRequest& request,
205 const CacheStorageCacheQueryParams& match_params) {
206 // TODO(gavinp,jkarlin): Implement this method.
207 Send(new CacheStorageMsg_CacheMatchAllError(
208 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
211 void CacheStorageDispatcherHost::OnCacheKeys(
212 int thread_id,
213 int request_id,
214 int cache_id,
215 const ServiceWorkerFetchRequest& request,
216 const CacheStorageCacheQueryParams& match_params) {
217 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
218 if (it == id_to_cache_map_.end()) {
219 Send(new CacheStorageMsg_CacheKeysError(
220 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
221 return;
224 scoped_refptr<CacheStorageCache> cache = it->second;
226 cache->Keys(base::Bind(&CacheStorageDispatcherHost::OnCacheKeysCallback, this,
227 thread_id, request_id, cache));
230 void CacheStorageDispatcherHost::OnCacheBatch(
231 int thread_id,
232 int request_id,
233 int cache_id,
234 const std::vector<CacheStorageBatchOperation>& operations) {
235 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
236 if (it == id_to_cache_map_.end()) {
237 Send(new CacheStorageMsg_CacheBatchError(
238 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
239 return;
241 scoped_refptr<CacheStorageCache> cache = it->second;
242 cache->BatchOperation(
243 operations, base::Bind(&CacheStorageDispatcherHost::OnCacheBatchCallback,
244 this, thread_id, request_id, cache));
247 void CacheStorageDispatcherHost::OnCacheClosed(int cache_id) {
248 DropCacheReference(cache_id);
251 void CacheStorageDispatcherHost::OnBlobDataHandled(const std::string& uuid) {
252 DropBlobDataHandle(uuid);
255 void CacheStorageDispatcherHost::OnCacheStorageHasCallback(
256 int thread_id,
257 int request_id,
258 bool has_cache,
259 CacheStorageError error) {
260 if (error != CACHE_STORAGE_OK) {
261 Send(new CacheStorageMsg_CacheStorageHasError(
262 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
263 return;
265 if (!has_cache) {
266 Send(new CacheStorageMsg_CacheStorageHasError(
267 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
268 return;
270 Send(new CacheStorageMsg_CacheStorageHasSuccess(thread_id, request_id));
273 void CacheStorageDispatcherHost::OnCacheStorageOpenCallback(
274 int thread_id,
275 int request_id,
276 const scoped_refptr<CacheStorageCache>& cache,
277 CacheStorageError error) {
278 if (error != CACHE_STORAGE_OK) {
279 Send(new CacheStorageMsg_CacheStorageOpenError(
280 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
281 return;
283 CacheID cache_id = StoreCacheReference(cache);
284 Send(new CacheStorageMsg_CacheStorageOpenSuccess(thread_id, request_id,
285 cache_id));
288 void CacheStorageDispatcherHost::OnCacheStorageDeleteCallback(
289 int thread_id,
290 int request_id,
291 bool deleted,
292 CacheStorageError error) {
293 if (!deleted || error != CACHE_STORAGE_OK) {
294 Send(new CacheStorageMsg_CacheStorageDeleteError(
295 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
296 return;
298 Send(new CacheStorageMsg_CacheStorageDeleteSuccess(thread_id, request_id));
301 void CacheStorageDispatcherHost::OnCacheStorageKeysCallback(
302 int thread_id,
303 int request_id,
304 const std::vector<std::string>& strings,
305 CacheStorageError error) {
306 if (error != CACHE_STORAGE_OK) {
307 Send(new CacheStorageMsg_CacheStorageKeysError(
308 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
309 return;
312 std::vector<base::string16> string16s;
313 for (size_t i = 0, max = strings.size(); i < max; ++i) {
314 string16s.push_back(base::UTF8ToUTF16(strings[i]));
316 Send(new CacheStorageMsg_CacheStorageKeysSuccess(thread_id, request_id,
317 string16s));
320 void CacheStorageDispatcherHost::OnCacheStorageMatchCallback(
321 int thread_id,
322 int request_id,
323 CacheStorageError error,
324 scoped_ptr<ServiceWorkerResponse> response,
325 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
326 if (error != CACHE_STORAGE_OK) {
327 Send(new CacheStorageMsg_CacheStorageMatchError(
328 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
329 return;
332 if (blob_data_handle)
333 StoreBlobDataHandle(blob_data_handle.Pass());
335 Send(new CacheStorageMsg_CacheStorageMatchSuccess(thread_id, request_id,
336 *response));
339 void CacheStorageDispatcherHost::OnCacheMatchCallback(
340 int thread_id,
341 int request_id,
342 const scoped_refptr<CacheStorageCache>& cache,
343 CacheStorageError error,
344 scoped_ptr<ServiceWorkerResponse> response,
345 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
346 if (error != CACHE_STORAGE_OK) {
347 Send(new CacheStorageMsg_CacheMatchError(
348 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
349 return;
352 if (blob_data_handle)
353 StoreBlobDataHandle(blob_data_handle.Pass());
355 Send(new CacheStorageMsg_CacheMatchSuccess(thread_id, request_id, *response));
358 void CacheStorageDispatcherHost::OnCacheKeysCallback(
359 int thread_id,
360 int request_id,
361 const scoped_refptr<CacheStorageCache>& cache,
362 CacheStorageError error,
363 scoped_ptr<CacheStorageCache::Requests> requests) {
364 if (error != CACHE_STORAGE_OK) {
365 Send(new CacheStorageMsg_CacheKeysError(
366 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
367 return;
370 CacheStorageCache::Requests out;
372 for (CacheStorageCache::Requests::const_iterator it = requests->begin();
373 it != requests->end(); ++it) {
374 ServiceWorkerFetchRequest request(it->url, it->method, it->headers,
375 it->referrer, it->is_reload);
376 out.push_back(request);
379 Send(new CacheStorageMsg_CacheKeysSuccess(thread_id, request_id, out));
382 void CacheStorageDispatcherHost::OnCacheBatchCallback(
383 int thread_id,
384 int request_id,
385 const scoped_refptr<CacheStorageCache>& cache,
386 CacheStorageError error) {
387 if (error != CACHE_STORAGE_OK) {
388 Send(new CacheStorageMsg_CacheBatchError(
389 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
390 return;
393 Send(new CacheStorageMsg_CacheBatchSuccess(thread_id, request_id));
396 CacheStorageDispatcherHost::CacheID
397 CacheStorageDispatcherHost::StoreCacheReference(
398 const scoped_refptr<CacheStorageCache>& cache) {
399 int cache_id = next_cache_id_++;
400 id_to_cache_map_[cache_id] = cache;
401 return cache_id;
404 void CacheStorageDispatcherHost::DropCacheReference(CacheID cache_id) {
405 id_to_cache_map_.erase(cache_id);
408 void CacheStorageDispatcherHost::StoreBlobDataHandle(
409 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
410 DCHECK(blob_data_handle);
411 std::pair<UUIDToBlobDataHandleList::iterator, bool> rv =
412 blob_handle_store_.insert(std::make_pair(
413 blob_data_handle->uuid(), std::list<storage::BlobDataHandle>()));
414 rv.first->second.push_front(storage::BlobDataHandle(*blob_data_handle));
417 void CacheStorageDispatcherHost::DropBlobDataHandle(std::string uuid) {
418 UUIDToBlobDataHandleList::iterator it = blob_handle_store_.find(uuid);
419 if (it == blob_handle_store_.end())
420 return;
421 DCHECK(!it->second.empty());
422 it->second.pop_front();
423 if (it->second.empty())
424 blob_handle_store_.erase(it);
427 } // namespace content