Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_cache_listener.cc
index 4082730..e52c940 100644 (file)
@@ -7,10 +7,12 @@
 #include "base/bind.h"
 #include "base/debug/trace_event.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/browser/service_worker/service_worker_cache.h"
 #include "content/browser/service_worker/service_worker_cache_storage_manager.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_version.h"
 #include "content/common/service_worker/service_worker_messages.h"
+#include "storage/browser/blob/blob_data_handle.h"
 #include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h"
 
 namespace content {
@@ -32,7 +34,7 @@ WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
     case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EXISTS:
       return blink::WebServiceWorkerCacheErrorExists;
     case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_STORAGE:
-      // TODO(jkarlin): Changethis to CACHE_STORAGE_ERROR_STORAGE once that's
+      // TODO(jkarlin): Change this to CACHE_STORAGE_ERROR_STORAGE once that's
       // added.
       return blink::WebServiceWorkerCacheErrorNotFound;
     case ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_CLOSING:
@@ -44,6 +46,27 @@ WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
   return blink::WebServiceWorkerCacheErrorNotImplemented;
 }
 
+// TODO(jkarlin): ServiceWorkerCache and ServiceWorkerCacheStorage should share
+// an error enum type.
+WebServiceWorkerCacheError CacheErrorToWebServiceWorkerCacheError(
+    ServiceWorkerCache::ErrorType err) {
+  switch (err) {
+    case ServiceWorkerCache::ErrorTypeOK:
+      NOTREACHED();
+      return blink::WebServiceWorkerCacheErrorNotImplemented;
+    case ServiceWorkerCache::ErrorTypeExists:
+      return blink::WebServiceWorkerCacheErrorExists;
+    case ServiceWorkerCache::ErrorTypeStorage:
+      // TODO(jkarlin): Change this to CACHE_STORAGE_ERROR_STORAGE once that's
+      // added.
+      return blink::WebServiceWorkerCacheErrorNotFound;
+    case ServiceWorkerCache::ErrorTypeNotFound:
+      return blink::WebServiceWorkerCacheErrorNotFound;
+  }
+  NOTREACHED();
+  return blink::WebServiceWorkerCacheErrorNotImplemented;
+}
+
 }  // namespace
 
 ServiceWorkerCacheListener::ServiceWorkerCacheListener(
@@ -53,21 +76,21 @@ ServiceWorkerCacheListener::ServiceWorkerCacheListener(
       context_(context),
       next_cache_id_(0),
       weak_factory_(this) {
+  version_->embedded_worker()->AddListener(this);
 }
 
 ServiceWorkerCacheListener::~ServiceWorkerCacheListener() {
+  version_->embedded_worker()->RemoveListener(this);
 }
 
 bool ServiceWorkerCacheListener::OnMessageReceived(
     const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerCacheListener, message)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageGet,
-                        OnCacheStorageGet)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageHas,
                         OnCacheStorageHas)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageCreate,
-                        OnCacheStorageCreate)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageOpen,
+                        OnCacheStorageOpen)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageDelete,
                         OnCacheStorageDelete)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageKeys,
@@ -82,25 +105,13 @@ bool ServiceWorkerCacheListener::OnMessageReceived(
                         OnCacheBatch)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheClosed,
                         OnCacheClosed)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_BlobDataHandled, OnBlobDataHandled)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
   return handled;
 }
 
-void ServiceWorkerCacheListener::OnCacheStorageGet(
-    int request_id,
-    const base::string16& cache_name) {
-  TRACE_EVENT0("ServiceWorker",
-               "ServiceWorkerCacheListener::OnCacheStorageGet");
-  context_->cache_manager()->GetCache(
-      version_->scope().GetOrigin(),
-      base::UTF16ToUTF8(cache_name),
-      base::Bind(&ServiceWorkerCacheListener::OnCacheStorageGetCallback,
-                 weak_factory_.GetWeakPtr(),
-                 request_id));
-}
-
 void ServiceWorkerCacheListener::OnCacheStorageHas(
     int request_id,
     const base::string16& cache_name) {
@@ -114,15 +125,15 @@ void ServiceWorkerCacheListener::OnCacheStorageHas(
                  request_id));
 }
 
-void ServiceWorkerCacheListener::OnCacheStorageCreate(
+void ServiceWorkerCacheListener::OnCacheStorageOpen(
     int request_id,
     const base::string16& cache_name) {
   TRACE_EVENT0("ServiceWorker",
-               "ServiceWorkerCacheListener::OnCacheStorageCreate");
-  context_->cache_manager()->CreateCache(
+               "ServiceWorkerCacheListener::OnCacheStorageOpen");
+  context_->cache_manager()->OpenCache(
       version_->scope().GetOrigin(),
       base::UTF16ToUTF8(cache_name),
-      base::Bind(&ServiceWorkerCacheListener::OnCacheStorageCreateCallback,
+      base::Bind(&ServiceWorkerCacheListener::OnCacheStorageOpenCallback,
                  weak_factory_.GetWeakPtr(),
                  request_id));
 }
@@ -155,9 +166,25 @@ void ServiceWorkerCacheListener::OnCacheMatch(
     int cache_id,
     const ServiceWorkerFetchRequest& request,
     const ServiceWorkerCacheQueryParams& match_params) {
-  // TODO(gavinp,jkarlin): Implement this method.
-  Send(ServiceWorkerMsg_CacheMatchError(
-      request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
+  IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
+  if (it == id_to_cache_map_.end()) {
+    Send(ServiceWorkerMsg_CacheMatchError(
+        request_id, blink::WebServiceWorkerCacheErrorNotFound));
+    return;
+  }
+
+  scoped_refptr<ServiceWorkerCache> cache = it->second;
+  scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
+      new ServiceWorkerFetchRequest(request.url,
+                                    request.method,
+                                    request.headers,
+                                    request.referrer,
+                                    request.is_reload));
+  cache->Match(scoped_request.Pass(),
+               base::Bind(&ServiceWorkerCacheListener::OnCacheMatchCallback,
+                          weak_factory_.GetWeakPtr(),
+                          request_id,
+                          cache));
 }
 
 void ServiceWorkerCacheListener::OnCacheMatchAll(
@@ -175,40 +202,90 @@ void ServiceWorkerCacheListener::OnCacheKeys(
     int cache_id,
     const ServiceWorkerFetchRequest& request,
     const ServiceWorkerCacheQueryParams& match_params) {
-  // TODO(gavinp,jkarlin): Implement this method.
-  Send(ServiceWorkerMsg_CacheKeysError(
-      request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
+  IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
+  if (it == id_to_cache_map_.end()) {
+    Send(ServiceWorkerMsg_CacheKeysError(
+        request_id, blink::WebServiceWorkerCacheErrorNotFound));
+    return;
+  }
+
+  scoped_refptr<ServiceWorkerCache> cache = it->second;
+
+  cache->Keys(base::Bind(&ServiceWorkerCacheListener::OnCacheKeysCallback,
+                         weak_factory_.GetWeakPtr(),
+                         request_id,
+                         cache));
 }
 
 void ServiceWorkerCacheListener::OnCacheBatch(
     int request_id,
     int cache_id,
     const std::vector<ServiceWorkerBatchOperation>& operations) {
-  // TODO(gavinp,jkarlin): Implement this method.
+  if (operations.size() != 1u) {
+    Send(ServiceWorkerMsg_CacheBatchError(
+        request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
+    return;
+  }
+
+  IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
+  if (it == id_to_cache_map_.end()) {
+    Send(ServiceWorkerMsg_CacheBatchError(
+        request_id, blink::WebServiceWorkerCacheErrorNotFound));
+    return;
+  }
+
+  const ServiceWorkerBatchOperation& operation = operations[0];
+
+  scoped_refptr<ServiceWorkerCache> cache = it->second;
+  scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
+      new ServiceWorkerFetchRequest(operation.request.url,
+                                    operation.request.method,
+                                    operation.request.headers,
+                                    operation.request.referrer,
+                                    operation.request.is_reload));
+
+  if (operation.operation_type == SERVICE_WORKER_CACHE_OPERATION_TYPE_DELETE) {
+    cache->Delete(scoped_request.Pass(),
+                  base::Bind(&ServiceWorkerCacheListener::OnCacheDeleteCallback,
+                             weak_factory_.GetWeakPtr(),
+                             request_id,
+                             cache));
+    return;
+  }
+
+  if (operation.operation_type == SERVICE_WORKER_CACHE_OPERATION_TYPE_PUT) {
+    scoped_ptr<ServiceWorkerResponse> scoped_response(
+        new ServiceWorkerResponse(operation.response.url,
+                                  operation.response.status_code,
+                                  operation.response.status_text,
+                                  operation.response.response_type,
+                                  operation.response.headers,
+                                  operation.response.blob_uuid,
+                                  operation.response.blob_size));
+    cache->Put(scoped_request.Pass(),
+               scoped_response.Pass(),
+               base::Bind(&ServiceWorkerCacheListener::OnCachePutCallback,
+                          weak_factory_.GetWeakPtr(),
+                          request_id,
+                          cache));
+
+    return;
+  }
+
   Send(ServiceWorkerMsg_CacheBatchError(
       request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
 }
 
 void ServiceWorkerCacheListener::OnCacheClosed(int cache_id) {
-  // TODO(gavinp,jkarlin): Implement this method.
+  DropCacheReference(cache_id);
 }
 
-void ServiceWorkerCacheListener::Send(const IPC::Message& message) {
-  version_->embedded_worker()->SendMessage(message);
+void ServiceWorkerCacheListener::OnBlobDataHandled(const std::string& uuid) {
+  DropBlobDataHandle(uuid);
 }
 
-void ServiceWorkerCacheListener::OnCacheStorageGetCallback(
-    int request_id,
-    const scoped_refptr<ServiceWorkerCache>& cache,
-    ServiceWorkerCacheStorage::CacheStorageError error) {
-  if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) {
-    Send(ServiceWorkerMsg_CacheStorageGetError(
-        request_id, ToWebServiceWorkerCacheError(error)));
-    return;
-  }
-
-  CacheID cache_id = StoreCacheReference(cache);
-  Send(ServiceWorkerMsg_CacheStorageGetSuccess(request_id, cache_id));
+void ServiceWorkerCacheListener::Send(const IPC::Message& message) {
+  version_->embedded_worker()->SendMessage(message);
 }
 
 void ServiceWorkerCacheListener::OnCacheStorageHasCallback(
@@ -229,17 +306,17 @@ void ServiceWorkerCacheListener::OnCacheStorageHasCallback(
   Send(ServiceWorkerMsg_CacheStorageHasSuccess(request_id));
 }
 
-void ServiceWorkerCacheListener::OnCacheStorageCreateCallback(
+void ServiceWorkerCacheListener::OnCacheStorageOpenCallback(
     int request_id,
     const scoped_refptr<ServiceWorkerCache>& cache,
     ServiceWorkerCacheStorage::CacheStorageError error) {
   if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) {
-    Send(ServiceWorkerMsg_CacheStorageCreateError(
+    Send(ServiceWorkerMsg_CacheStorageOpenError(
         request_id, ToWebServiceWorkerCacheError(error)));
     return;
   }
   CacheID cache_id = StoreCacheReference(cache);
-  Send(ServiceWorkerMsg_CacheStorageCreateSuccess(request_id, cache_id));
+  Send(ServiceWorkerMsg_CacheStorageOpenSuccess(request_id, cache_id));
 }
 
 void ServiceWorkerCacheListener::OnCacheStorageDeleteCallback(
@@ -272,6 +349,82 @@ void ServiceWorkerCacheListener::OnCacheStorageKeysCallback(
   Send(ServiceWorkerMsg_CacheStorageKeysSuccess(request_id, string16s));
 }
 
+void ServiceWorkerCacheListener::OnCacheMatchCallback(
+    int request_id,
+    const scoped_refptr<ServiceWorkerCache>& cache,
+    ServiceWorkerCache::ErrorType error,
+    scoped_ptr<ServiceWorkerResponse> response,
+    scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
+  if (error != ServiceWorkerCache::ErrorTypeOK) {
+    Send(ServiceWorkerMsg_CacheMatchError(
+        request_id, CacheErrorToWebServiceWorkerCacheError(error)));
+    return;
+  }
+
+  if (blob_data_handle)
+    StoreBlobDataHandle(blob_data_handle.Pass());
+
+  Send(ServiceWorkerMsg_CacheMatchSuccess(request_id, *response));
+}
+
+void ServiceWorkerCacheListener::OnCacheKeysCallback(
+    int request_id,
+    const scoped_refptr<ServiceWorkerCache>& cache,
+    ServiceWorkerCache::ErrorType error,
+    scoped_ptr<ServiceWorkerCache::Requests> requests) {
+  if (error != ServiceWorkerCache::ErrorTypeOK) {
+    Send(ServiceWorkerMsg_CacheKeysError(
+        request_id, CacheErrorToWebServiceWorkerCacheError(error)));
+    return;
+  }
+
+  ServiceWorkerCache::Requests out;
+
+  for (ServiceWorkerCache::Requests::const_iterator it = requests->begin();
+       it != requests->end();
+       ++it) {
+    ServiceWorkerFetchRequest request(
+        it->url, it->method, it->headers, it->referrer, it->is_reload);
+    out.push_back(request);
+  }
+
+  Send(ServiceWorkerMsg_CacheKeysSuccess(request_id, out));
+}
+
+void ServiceWorkerCacheListener::OnCacheDeleteCallback(
+    int request_id,
+    const scoped_refptr<ServiceWorkerCache>& cache,
+    ServiceWorkerCache::ErrorType error) {
+  if (error != ServiceWorkerCache::ErrorTypeOK) {
+    Send(ServiceWorkerMsg_CacheBatchError(
+        request_id, CacheErrorToWebServiceWorkerCacheError(error)));
+    return;
+  }
+
+  Send(ServiceWorkerMsg_CacheBatchSuccess(
+      request_id, std::vector<ServiceWorkerResponse>()));
+}
+
+void ServiceWorkerCacheListener::OnCachePutCallback(
+    int request_id,
+    const scoped_refptr<ServiceWorkerCache>& cache,
+    ServiceWorkerCache::ErrorType error,
+    scoped_ptr<ServiceWorkerResponse> response,
+    scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
+  if (error != ServiceWorkerCache::ErrorTypeOK) {
+    Send(ServiceWorkerMsg_CacheBatchError(
+        request_id, CacheErrorToWebServiceWorkerCacheError(error)));
+    return;
+  }
+
+  if (blob_data_handle)
+    StoreBlobDataHandle(blob_data_handle.Pass());
+
+  std::vector<ServiceWorkerResponse> responses;
+  responses.push_back(*response);
+  Send(ServiceWorkerMsg_CacheBatchSuccess(request_id, responses));
+}
+
 ServiceWorkerCacheListener::CacheID
 ServiceWorkerCacheListener::StoreCacheReference(
     const scoped_refptr<ServiceWorkerCache>& cache) {
@@ -284,4 +437,23 @@ void ServiceWorkerCacheListener::DropCacheReference(CacheID cache_id) {
   id_to_cache_map_.erase(cache_id);
 }
 
+void ServiceWorkerCacheListener::StoreBlobDataHandle(
+    scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
+  DCHECK(blob_data_handle);
+  std::pair<UUIDToBlobDataHandleList::iterator, bool> rv =
+      blob_handle_store_.insert(std::make_pair(
+          blob_data_handle->uuid(), std::list<storage::BlobDataHandle>()));
+  rv.first->second.push_front(storage::BlobDataHandle(*blob_data_handle));
+}
+
+void ServiceWorkerCacheListener::DropBlobDataHandle(std::string uuid) {
+  UUIDToBlobDataHandleList::iterator it = blob_handle_store_.find(uuid);
+  if (it == blob_handle_store_.end())
+    return;
+  DCHECK(!it->second.empty());
+  it->second.pop_front();
+  if (it->second.empty())
+    blob_handle_store_.erase(it);
+}
+
 }  // namespace content