Commit 203f6295 authored by gavinp's avatar gavinp Committed by Commit bot

content::WebServiceWorkerCache implementation.

The WebCache object itself is created by the
ServiceWorkerCacheStorageDispatcher, which also handles much of its
messaging for lifetime reasons, since a cache operation can outlive
its WebServiceWorkerCache object.

R=falken@chromium.org,jkarlin@chromium.org
BUG=None

Review URL: https://codereview.chromium.org/474593002

Cr-Commit-Position: refs/heads/master@{#296726}
parent 2eee6cb9
...@@ -72,6 +72,16 @@ bool ServiceWorkerCacheListener::OnMessageReceived( ...@@ -72,6 +72,16 @@ bool ServiceWorkerCacheListener::OnMessageReceived(
OnCacheStorageDelete) OnCacheStorageDelete)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageKeys, IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheStorageKeys,
OnCacheStorageKeys) OnCacheStorageKeys)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheMatch,
OnCacheMatch)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheMatchAll,
OnCacheMatchAll)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheKeys,
OnCacheKeys)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheBatch,
OnCacheBatch)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CacheClosed,
OnCacheClosed)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -140,6 +150,49 @@ void ServiceWorkerCacheListener::OnCacheStorageKeys(int request_id) { ...@@ -140,6 +150,49 @@ void ServiceWorkerCacheListener::OnCacheStorageKeys(int request_id) {
request_id)); request_id));
} }
void ServiceWorkerCacheListener::OnCacheMatch(
int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params) {
// TODO(gavinp,jkarlin): Implement this method.
Send(ServiceWorkerMsg_CacheMatchError(
request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
}
void ServiceWorkerCacheListener::OnCacheMatchAll(
int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params) {
// TODO(gavinp,jkarlin): Implement this method.
Send(ServiceWorkerMsg_CacheMatchAllError(
request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
}
void ServiceWorkerCacheListener::OnCacheKeys(
int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params) {
// TODO(gavinp,jkarlin): Implement this method.
Send(ServiceWorkerMsg_CacheKeysError(
request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
}
void ServiceWorkerCacheListener::OnCacheBatch(
int request_id,
int cache_id,
const std::vector<ServiceWorkerBatchOperation>& operations) {
// TODO(gavinp,jkarlin): Implement this method.
Send(ServiceWorkerMsg_CacheBatchError(
request_id, blink::WebServiceWorkerCacheErrorNotImplemented));
}
void ServiceWorkerCacheListener::OnCacheClosed(int cache_id) {
// TODO(gavinp,jkarlin): Implement this method.
}
void ServiceWorkerCacheListener::Send(const IPC::Message& message) { void ServiceWorkerCacheListener::Send(const IPC::Message& message) {
version_->embedded_worker()->SendMessage(message); version_->embedded_worker()->SendMessage(message);
} }
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
namespace content { namespace content {
struct ServiceWorkerBatchOperation;
struct ServiceWorkerCacheQueryParams;
struct ServiceWorkerFetchRequest;
class ServiceWorkerVersion; class ServiceWorkerVersion;
// This class listens for requests on the Cache APIs, and sends response // This class listens for requests on the Cache APIs, and sends response
...@@ -26,7 +29,8 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener { ...@@ -26,7 +29,8 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener {
// From EmbeddedWorkerInstance::Listener: // From EmbeddedWorkerInstance::Listener:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Message receiver functions for CacheStorage API. private:
// The message receiver functions for the CacheStorage API:
void OnCacheStorageGet(int request_id, const base::string16& cache_name); void OnCacheStorageGet(int request_id, const base::string16& cache_name);
void OnCacheStorageHas(int request_id, const base::string16& cache_name); void OnCacheStorageHas(int request_id, const base::string16& cache_name);
void OnCacheStorageCreate(int request_id, void OnCacheStorageCreate(int request_id,
...@@ -35,8 +39,23 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener { ...@@ -35,8 +39,23 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener {
const base::string16& cache_name); const base::string16& cache_name);
void OnCacheStorageKeys(int request_id); void OnCacheStorageKeys(int request_id);
// TODO(gavinp,jkarlin): Plumb a message up from the renderer saying that the // The message receiver functions for the Cache API:
// renderer is done with a cache id. void OnCacheMatch(int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params);
void OnCacheMatchAll(int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params);
void OnCacheKeys(int request_id,
int cache_id,
const ServiceWorkerFetchRequest& request,
const ServiceWorkerCacheQueryParams& match_params);
void OnCacheBatch(int request_id,
int cache_id,
const std::vector<ServiceWorkerBatchOperation>& operations);
void OnCacheClosed(int cache_id);
private: private:
typedef int32_t CacheID; // TODO(jkarlin): Bump to 64 bit. typedef int32_t CacheID; // TODO(jkarlin): Bump to 64 bit.
......
...@@ -52,6 +52,23 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse) ...@@ -52,6 +52,23 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse)
IPC_STRUCT_TRAITS_MEMBER(blob_uuid) IPC_STRUCT_TRAITS_MEMBER(blob_uuid)
IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerCacheQueryParams)
IPC_STRUCT_TRAITS_MEMBER(ignore_search)
IPC_STRUCT_TRAITS_MEMBER(ignore_method)
IPC_STRUCT_TRAITS_MEMBER(ignore_vary)
IPC_STRUCT_TRAITS_MEMBER(prefix_match)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerCacheOperationType,
content::SERVICE_WORKER_CACHE_OPERATION_TYPE_LAST)
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerBatchOperation)
IPC_STRUCT_TRAITS_MEMBER(operation_type)
IPC_STRUCT_TRAITS_MEMBER(request)
IPC_STRUCT_TRAITS_MEMBER(response)
IPC_STRUCT_TRAITS_MEMBER(match_params)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerObjectInfo) IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerObjectInfo)
IPC_STRUCT_TRAITS_MEMBER(handle_id) IPC_STRUCT_TRAITS_MEMBER(handle_id)
IPC_STRUCT_TRAITS_MEMBER(scope) IPC_STRUCT_TRAITS_MEMBER(scope)
...@@ -182,6 +199,33 @@ IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_CacheStorageDelete, ...@@ -182,6 +199,33 @@ IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_CacheStorageDelete,
IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys, IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys,
int /* request_id */) int /* request_id */)
// Cache operations in the browser.
IPC_MESSAGE_ROUTED4(ServiceWorkerHostMsg_CacheMatch,
int /* request_id */,
int /* cache_id */,
content::ServiceWorkerFetchRequest,
content::ServiceWorkerCacheQueryParams)
IPC_MESSAGE_ROUTED4(ServiceWorkerHostMsg_CacheMatchAll,
int /* request_id */,
int /* cache_id */,
content::ServiceWorkerFetchRequest,
content::ServiceWorkerCacheQueryParams)
IPC_MESSAGE_ROUTED4(ServiceWorkerHostMsg_CacheKeys,
int /* request_id */,
int /* cache_id */,
content::ServiceWorkerFetchRequest,
content::ServiceWorkerCacheQueryParams);
IPC_MESSAGE_ROUTED3(ServiceWorkerHostMsg_CacheBatch,
int /* request_id */,
int /* cache_id */,
std::vector<content::ServiceWorkerBatchOperation>);
IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheClosed,
int /* cache_id */);
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Messages sent from the browser to the child process. // Messages sent from the browser to the child process.
// //
...@@ -335,3 +379,31 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheStorageDeleteError, ...@@ -335,3 +379,31 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheStorageDeleteError,
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheStorageKeysError, IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheStorageKeysError,
int /* request_id */, int /* request_id */,
blink::WebServiceWorkerCacheError /* reason */) blink::WebServiceWorkerCacheError /* reason */)
// Sent via EmbeddedWorker at successful completion of Cache operations.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheMatchSuccess,
int /* request_id */,
content::ServiceWorkerResponse)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheMatchAllSuccess,
int /* request_id */,
std::vector<content::ServiceWorkerResponse>)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheKeysSuccess,
int /* request_id */,
std::vector<content::ServiceWorkerFetchRequest>)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheBatchSuccess,
int /* request_id */,
std::vector<content::ServiceWorkerResponse>)
// Sent via EmbeddedWorker at erroneous completion of CacheStorage operations.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheMatchError,
int /* request_id */,
blink::WebServiceWorkerCacheError)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheMatchAllError,
int /* request_id */,
blink::WebServiceWorkerCacheError)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheKeysError,
int /* request_id */,
blink::WebServiceWorkerCacheError)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_CacheBatchError,
int /* request_id */,
blink::WebServiceWorkerCacheError)
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
namespace content { namespace content {
ServiceWorkerFetchRequest::ServiceWorkerFetchRequest() ServiceWorkerFetchRequest::ServiceWorkerFetchRequest() : blob_size(0),
: blob_size(0), is_reload(false) { is_reload(false) {}
}
ServiceWorkerFetchRequest::ServiceWorkerFetchRequest( ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
const GURL& url, const GURL& url,
...@@ -21,8 +20,7 @@ ServiceWorkerFetchRequest::ServiceWorkerFetchRequest( ...@@ -21,8 +20,7 @@ ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
headers(headers), headers(headers),
blob_size(0), blob_size(0),
referrer(referrer), referrer(referrer),
is_reload(is_reload) { is_reload(is_reload) {}
}
ServiceWorkerFetchRequest::~ServiceWorkerFetchRequest() {} ServiceWorkerFetchRequest::~ServiceWorkerFetchRequest() {}
...@@ -38,11 +36,18 @@ ServiceWorkerResponse::ServiceWorkerResponse( ...@@ -38,11 +36,18 @@ ServiceWorkerResponse::ServiceWorkerResponse(
status_code(status_code), status_code(status_code),
status_text(status_text), status_text(status_text),
headers(headers), headers(headers),
blob_uuid(blob_uuid) { blob_uuid(blob_uuid) {}
}
ServiceWorkerResponse::~ServiceWorkerResponse() {} ServiceWorkerResponse::~ServiceWorkerResponse() {}
ServiceWorkerCacheQueryParams::ServiceWorkerCacheQueryParams()
: ignore_search(false),
ignore_method(false),
ignore_vary(false),
prefix_match(false) {}
ServiceWorkerBatchOperation::ServiceWorkerBatchOperation() {}
ServiceWorkerObjectInfo::ServiceWorkerObjectInfo() ServiceWorkerObjectInfo::ServiceWorkerObjectInfo()
: handle_id(kInvalidServiceWorkerHandleId), : handle_id(kInvalidServiceWorkerHandleId),
state(blink::WebServiceWorkerStateUnknown) {} state(blink::WebServiceWorkerStateUnknown) {}
......
...@@ -88,6 +88,35 @@ struct CONTENT_EXPORT ServiceWorkerResponse { ...@@ -88,6 +88,35 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
std::string blob_uuid; std::string blob_uuid;
}; };
// Controls how requests are matched in the Cache API.
struct CONTENT_EXPORT ServiceWorkerCacheQueryParams {
ServiceWorkerCacheQueryParams();
bool ignore_search;
bool ignore_method;
bool ignore_vary;
bool prefix_match;
};
// The type of a single batch operation in the Cache API.
enum ServiceWorkerCacheOperationType {
SERVICE_WORKER_CACHE_OPERATION_TYPE_UNDEFINED,
SERVICE_WORKER_CACHE_OPERATION_TYPE_PUT,
SERVICE_WORKER_CACHE_OPERATION_TYPE_DELETE,
SERVICE_WORKER_CACHE_OPERATION_TYPE_LAST =
SERVICE_WORKER_CACHE_OPERATION_TYPE_DELETE
};
// A single batch operation for the Cache API.
struct CONTENT_EXPORT ServiceWorkerBatchOperation {
ServiceWorkerBatchOperation();
ServiceWorkerCacheOperationType operation_type;
ServiceWorkerFetchRequest request;
ServiceWorkerResponse response;
ServiceWorkerCacheQueryParams match_params;
};
// Represents initialization info for a WebServiceWorker object. // Represents initialization info for a WebServiceWorker object.
struct CONTENT_EXPORT ServiceWorkerObjectInfo { struct CONTENT_EXPORT ServiceWorkerObjectInfo {
ServiceWorkerObjectInfo(); ServiceWorkerObjectInfo();
......
...@@ -4,15 +4,152 @@ ...@@ -4,15 +4,152 @@
#include "content/renderer/service_worker/service_worker_cache_storage_dispatcher.h" #include "content/renderer/service_worker/service_worker_cache_storage_dispatcher.h"
#include <map>
#include <string>
#include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h"
#include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_thread.h"
#include "content/renderer/service_worker/service_worker_script_context.h" #include "content/renderer/service_worker/service_worker_script_context.h"
#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerCache.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerRequest.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerResponse.h"
namespace content { namespace content {
using blink::WebServiceWorkerCacheError;
using blink::WebServiceWorkerRequest;
namespace { namespace {
class HeaderVisitor : public blink::WebHTTPHeaderVisitor {
public:
HeaderVisitor(ServiceWorkerHeaderMap* headers) : headers_(headers) {}
virtual ~HeaderVisitor() {}
virtual void visitHeader(const blink::WebString& name,
const blink::WebString& value) {
headers_->insert(ServiceWorkerHeaderMap::value_type(
base::UTF16ToASCII(name), base::UTF16ToASCII(value)));
}
private:
ServiceWorkerHeaderMap* headers_;
};
scoped_ptr<HeaderVisitor> MakeHeaderVisitor(ServiceWorkerHeaderMap* headers) {
return scoped_ptr<HeaderVisitor>(new HeaderVisitor(headers)).Pass();
}
ServiceWorkerFetchRequest FetchRequestFromWebRequest(
const blink::WebServiceWorkerRequest& web_request) {
ServiceWorkerHeaderMap headers;
web_request.visitHTTPHeaderFields(MakeHeaderVisitor(&headers).get());
return ServiceWorkerFetchRequest(web_request.url(),
base::UTF16ToASCII(web_request.method()),
headers, web_request.referrerUrl(),
web_request.isReload());
}
void PopulateWebRequestFromFetchRequest(
const ServiceWorkerFetchRequest& request,
blink::WebServiceWorkerRequest* web_request) {
web_request->setURL(request.url);
web_request->setMethod(base::ASCIIToUTF16(request.method));
for (ServiceWorkerHeaderMap::const_iterator i = request.headers.begin(),
end = request.headers.end();
i != end; ++i) {
web_request->setHeader(base::ASCIIToUTF16(i->first),
base::ASCIIToUTF16(i->second));
}
web_request->setReferrer(base::ASCIIToUTF16(request.referrer.spec()),
blink::WebReferrerPolicy::WebReferrerPolicyNever);
web_request->setIsReload(request.is_reload);
}
blink::WebVector<blink::WebServiceWorkerRequest> WebRequestsFromRequests(
const std::vector<ServiceWorkerFetchRequest>& requests) {
blink::WebVector<blink::WebServiceWorkerRequest>
web_requests(requests.size());
for (size_t i = 0; i < requests.size(); ++i)
PopulateWebRequestFromFetchRequest(requests[i], &(web_requests[i]));
return web_requests;
}
ServiceWorkerResponse ResponseFromWebResponse(
const blink::WebServiceWorkerResponse& web_response) {
ServiceWorkerHeaderMap headers;
web_response.visitHTTPHeaderFields(MakeHeaderVisitor(&headers).get());
return ServiceWorkerResponse(
web_response.url(), web_response.status(),
base::UTF16ToASCII(web_response.statusText()), headers,
base::UTF16ToASCII(web_response.blobUUID()));
}
void PopulateWebResponseFromResponse(
const ServiceWorkerResponse& response,
blink::WebServiceWorkerResponse* web_response) {
web_response->setURL(response.url);
web_response->setStatus(response.status_code);
web_response->setStatusText(base::ASCIIToUTF16(response.status_text));
for (ServiceWorkerHeaderMap::const_iterator i = response.headers.begin(),
end = response.headers.end();
i != end; ++i) {
web_response->setHeader(base::ASCIIToUTF16(i->first),
base::ASCIIToUTF16(i->second));
}
// TODO(gavinp): set blob here.
}
blink::WebVector<blink::WebServiceWorkerResponse> WebResponsesFromResponses(
const std::vector<ServiceWorkerResponse>& responses) {
blink::WebVector<blink::WebServiceWorkerResponse>
web_responses(responses.size());
for (size_t i = 0; i < responses.size(); ++i)
PopulateWebResponseFromResponse(responses[i], &(web_responses[i]));
return web_responses;
}
ServiceWorkerCacheQueryParams QueryParamsFromWebQueryParams(
const blink::WebServiceWorkerCache::QueryParams& web_query_params) {
ServiceWorkerCacheQueryParams query_params;
query_params.ignore_search = web_query_params.ignoreSearch;
query_params.ignore_method = web_query_params.ignoreMethod;
query_params.ignore_vary = web_query_params.ignoreVary;
query_params.prefix_match = web_query_params.prefixMatch;
return query_params;
}
ServiceWorkerCacheOperationType CacheOperationTypeFromWebCacheOperationType(
blink::WebServiceWorkerCache::OperationType operation_type) {
switch (operation_type) {
case blink::WebServiceWorkerCache::OperationTypePut:
return SERVICE_WORKER_CACHE_OPERATION_TYPE_PUT;
case blink::WebServiceWorkerCache::OperationTypeDelete:
return SERVICE_WORKER_CACHE_OPERATION_TYPE_DELETE;
default:
return SERVICE_WORKER_CACHE_OPERATION_TYPE_UNDEFINED;
}
}
ServiceWorkerBatchOperation BatchOperationFromWebBatchOperation(
const blink::WebServiceWorkerCache::BatchOperation& web_operation) {
ServiceWorkerBatchOperation operation;
operation.operation_type =
CacheOperationTypeFromWebCacheOperationType(web_operation.operationType);
operation.request = FetchRequestFromWebRequest(web_operation.request);
operation.response = ResponseFromWebResponse(web_operation.response);
operation.match_params =
QueryParamsFromWebQueryParams(web_operation.matchParams);
return operation;
}
template<typename T> template<typename T>
void ClearCallbacksMapWithErrors(T* callbacks_map) { void ClearCallbacksMapWithErrors(T* callbacks_map) {
typename T::iterator iter(callbacks_map); typename T::iterator iter(callbacks_map);
...@@ -27,9 +164,65 @@ void ClearCallbacksMapWithErrors(T* callbacks_map) { ...@@ -27,9 +164,65 @@ void ClearCallbacksMapWithErrors(T* callbacks_map) {
} // namespace } // namespace
// The WebCache object is the Chromium side implementation of the Blink
// WebServiceWorkerCache API. Most of its methods delegate directly to the
// ServiceWorkerStorage object, which is able to assign unique IDs as well
// as have a lifetime longer than the requests.
class ServiceWorkerCacheStorageDispatcher::WebCache
: public blink::WebServiceWorkerCache {
public:
WebCache(base::WeakPtr<ServiceWorkerCacheStorageDispatcher> dispatcher,
int cache_id)
: dispatcher_(dispatcher),
cache_id_(cache_id) {}
virtual ~WebCache() {
if (dispatcher_)
dispatcher_->OnWebCacheDestruction(cache_id_);
}
// From blink::WebServiceWorkerCache:
virtual void dispatchMatch(CacheMatchCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const QueryParams& query_params) {
if (!dispatcher_)
return;
dispatcher_->dispatchMatchForCache(cache_id_, callbacks, request,
query_params);
}
virtual void dispatchMatchAll(CacheWithResponsesCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const QueryParams& query_params) {
if (!dispatcher_)
return;
dispatcher_->dispatchMatchAllForCache(cache_id_, callbacks, request,
query_params);
}
virtual void dispatchKeys(CacheWithRequestsCallbacks* callbacks,
const blink::WebServiceWorkerRequest* request,
const QueryParams& query_params) {
if (!dispatcher_)
return;
dispatcher_->dispatchKeysForCache(cache_id_, callbacks, request,
query_params);
}
virtual void dispatchBatch(
CacheWithResponsesCallbacks* callbacks,
const blink::WebVector<BatchOperation>& batch_operations) {
if (!dispatcher_)
return;
dispatcher_->dispatchBatchForCache(cache_id_, callbacks, batch_operations);
}
private:
const base::WeakPtr<ServiceWorkerCacheStorageDispatcher> dispatcher_;
const int cache_id_;
};
ServiceWorkerCacheStorageDispatcher::ServiceWorkerCacheStorageDispatcher( ServiceWorkerCacheStorageDispatcher::ServiceWorkerCacheStorageDispatcher(
ServiceWorkerScriptContext* script_context) ServiceWorkerScriptContext* script_context)
: script_context_(script_context) {} : script_context_(script_context),
weak_factory_(this) {}
ServiceWorkerCacheStorageDispatcher::~ServiceWorkerCacheStorageDispatcher() { ServiceWorkerCacheStorageDispatcher::~ServiceWorkerCacheStorageDispatcher() {
ClearCallbacksMapWithErrors(&get_callbacks_); ClearCallbacksMapWithErrors(&get_callbacks_);
...@@ -37,6 +230,11 @@ ServiceWorkerCacheStorageDispatcher::~ServiceWorkerCacheStorageDispatcher() { ...@@ -37,6 +230,11 @@ ServiceWorkerCacheStorageDispatcher::~ServiceWorkerCacheStorageDispatcher() {
ClearCallbacksMapWithErrors(&create_callbacks_); ClearCallbacksMapWithErrors(&create_callbacks_);
ClearCallbacksMapWithErrors(&delete_callbacks_); ClearCallbacksMapWithErrors(&delete_callbacks_);
ClearCallbacksMapWithErrors(&keys_callbacks_); ClearCallbacksMapWithErrors(&keys_callbacks_);
ClearCallbacksMapWithErrors(&cache_match_callbacks_);
ClearCallbacksMapWithErrors(&cache_match_all_callbacks_);
ClearCallbacksMapWithErrors(&cache_keys_callbacks_);
ClearCallbacksMapWithErrors(&cache_batch_callbacks_);
} }
bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived( bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived(
...@@ -63,6 +261,22 @@ bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived( ...@@ -63,6 +261,22 @@ bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived(
OnCacheStorageDeleteError) OnCacheStorageDeleteError)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageKeysError, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageKeysError,
OnCacheStorageKeysError) OnCacheStorageKeysError)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchSuccess,
OnCacheMatchSuccess)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchAllSuccess,
OnCacheMatchAllSuccess)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheKeysSuccess,
OnCacheKeysSuccess)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheBatchSuccess,
OnCacheBatchSuccess)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchError,
OnCacheMatchError)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchAllError,
OnCacheMatchAllError)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheKeysError,
OnCacheKeysError)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheBatchError,
OnCacheBatchError)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -72,9 +286,10 @@ bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived( ...@@ -72,9 +286,10 @@ bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived(
void ServiceWorkerCacheStorageDispatcher::OnCacheStorageGetSuccess( void ServiceWorkerCacheStorageDispatcher::OnCacheStorageGetSuccess(
int request_id, int request_id,
int cache_id) { int cache_id) {
CacheStorageWithCacheCallbacks* callbacks = WebCache* web_cache = new WebCache(weak_factory_.GetWeakPtr(), cache_id);
get_callbacks_.Lookup(request_id); web_caches_.AddWithID(web_cache, cache_id);
callbacks->onSuccess(NULL); CacheStorageWithCacheCallbacks* callbacks = get_callbacks_.Lookup(request_id);
callbacks->onSuccess(web_cache);
get_callbacks_.Remove(request_id); get_callbacks_.Remove(request_id);
} }
...@@ -88,9 +303,11 @@ void ServiceWorkerCacheStorageDispatcher::OnCacheStorageHasSuccess( ...@@ -88,9 +303,11 @@ void ServiceWorkerCacheStorageDispatcher::OnCacheStorageHasSuccess(
void ServiceWorkerCacheStorageDispatcher::OnCacheStorageCreateSuccess( void ServiceWorkerCacheStorageDispatcher::OnCacheStorageCreateSuccess(
int request_id, int request_id,
int cache_id) { int cache_id) {
WebCache* web_cache = new WebCache(weak_factory_.GetWeakPtr(), cache_id);
web_caches_.AddWithID(web_cache, cache_id);
CacheStorageWithCacheCallbacks* callbacks = CacheStorageWithCacheCallbacks* callbacks =
create_callbacks_.Lookup(request_id); create_callbacks_.Lookup(request_id);
callbacks->onSuccess(NULL); callbacks->onSuccess(web_cache);
create_callbacks_.Remove(request_id); create_callbacks_.Remove(request_id);
} }
...@@ -155,6 +372,91 @@ void ServiceWorkerCacheStorageDispatcher::OnCacheStorageKeysError( ...@@ -155,6 +372,91 @@ void ServiceWorkerCacheStorageDispatcher::OnCacheStorageKeysError(
keys_callbacks_.Remove(request_id); keys_callbacks_.Remove(request_id);
} }
void ServiceWorkerCacheStorageDispatcher::OnCacheMatchSuccess(
int request_id,
const ServiceWorkerResponse& response) {
blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks =
cache_match_callbacks_.Lookup(request_id);
blink::WebServiceWorkerResponse web_response;
PopulateWebResponseFromResponse(response, &web_response);
callbacks->onSuccess(&web_response);
cache_match_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheMatchAllSuccess(
int request_id,
const std::vector<ServiceWorkerResponse>& responses) {
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
cache_match_all_callbacks_.Lookup(request_id);
blink::WebVector<blink::WebServiceWorkerResponse>
web_responses = WebResponsesFromResponses(responses);
callbacks->onSuccess(&web_responses);
cache_match_all_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheKeysSuccess(
int request_id,
const std::vector<ServiceWorkerFetchRequest>& requests) {
blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks =
cache_keys_callbacks_.Lookup(request_id);
blink::WebVector<blink::WebServiceWorkerRequest>
web_requests = WebRequestsFromRequests(requests);
callbacks->onSuccess(&web_requests);
cache_keys_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheBatchSuccess(
int request_id,
const std::vector<ServiceWorkerResponse>& responses) {
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
cache_batch_callbacks_.Lookup(request_id);
blink::WebVector<blink::WebServiceWorkerResponse>
web_responses = WebResponsesFromResponses(responses);
callbacks->onSuccess(&web_responses);
cache_batch_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheMatchError(
int request_id,
blink::WebServiceWorkerCacheError reason) {
blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks =
cache_match_callbacks_.Lookup(request_id);
callbacks->onError(&reason);
cache_match_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheMatchAllError(
int request_id,
blink::WebServiceWorkerCacheError reason) {
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
cache_match_all_callbacks_.Lookup(request_id);
callbacks->onError(&reason);
cache_match_all_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheKeysError(
int request_id,
blink::WebServiceWorkerCacheError reason) {
blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks =
cache_keys_callbacks_.Lookup(request_id);
callbacks->onError(&reason);
cache_keys_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::OnCacheBatchError(
int request_id,
blink::WebServiceWorkerCacheError reason) {
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
cache_batch_callbacks_.Lookup(request_id);
callbacks->onError(&reason);
cache_batch_callbacks_.Remove(request_id);
}
void ServiceWorkerCacheStorageDispatcher::dispatchGet( void ServiceWorkerCacheStorageDispatcher::dispatchGet(
CacheStorageWithCacheCallbacks* callbacks, CacheStorageWithCacheCallbacks* callbacks,
const blink::WebString& cacheName) { const blink::WebString& cacheName) {
...@@ -194,4 +496,68 @@ void ServiceWorkerCacheStorageDispatcher::dispatchKeys( ...@@ -194,4 +496,68 @@ void ServiceWorkerCacheStorageDispatcher::dispatchKeys(
script_context_->GetRoutingID(), request_id)); script_context_->GetRoutingID(), request_id));
} }
void ServiceWorkerCacheStorageDispatcher::dispatchMatchForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const blink::WebServiceWorkerCache::QueryParams& query_params) {
int request_id = cache_match_callbacks_.Add(callbacks);
script_context_->Send(new ServiceWorkerHostMsg_CacheMatch(
script_context_->GetRoutingID(), request_id, cache_id,
FetchRequestFromWebRequest(request),
QueryParamsFromWebQueryParams(query_params)));
}
void ServiceWorkerCacheStorageDispatcher::dispatchMatchAllForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const blink::WebServiceWorkerCache::QueryParams& query_params) {
int request_id = cache_match_all_callbacks_.Add(callbacks);
script_context_->Send(new ServiceWorkerHostMsg_CacheMatchAll(
script_context_->GetRoutingID(), request_id, cache_id,
FetchRequestFromWebRequest(request),
QueryParamsFromWebQueryParams(query_params)));
}
void ServiceWorkerCacheStorageDispatcher::dispatchKeysForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks,
const blink::WebServiceWorkerRequest* request,
const blink::WebServiceWorkerCache::QueryParams& query_params) {
int request_id = cache_keys_callbacks_.Add(callbacks);
script_context_->Send(new ServiceWorkerHostMsg_CacheKeys(
script_context_->GetRoutingID(), request_id, cache_id,
request ? FetchRequestFromWebRequest(*request)
: ServiceWorkerFetchRequest(),
QueryParamsFromWebQueryParams(query_params)));
}
void ServiceWorkerCacheStorageDispatcher::dispatchBatchForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
const blink::WebVector<
blink::WebServiceWorkerCache::BatchOperation>& web_operations) {
int request_id = cache_batch_callbacks_.Add(callbacks);
std::vector<ServiceWorkerBatchOperation> operations;
operations.reserve(web_operations.size());
for (size_t i = 0; i < web_operations.size(); ++i) {
operations.push_back(
BatchOperationFromWebBatchOperation(web_operations[i]));
}
script_context_->Send(new ServiceWorkerHostMsg_CacheBatch(
script_context_->GetRoutingID(), request_id, cache_id, operations));
}
void ServiceWorkerCacheStorageDispatcher::OnWebCacheDestruction(int cache_id) {
web_caches_.Remove(cache_id);
script_context_->Send(new ServiceWorkerHostMsg_CacheClosed(
script_context_->GetRoutingID(), cache_id));
}
} // namespace content } // namespace content
...@@ -2,25 +2,30 @@ ...@@ -2,25 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_FETCH_STORES_DISPATCHER_H_ #ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CACHE_STORAGE_DISPATCHER_H_
#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_FETCH_STORES_DISPATCHER_H_ #define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CACHE_STORAGE_DISPATCHER_H_
#include <vector> #include <vector>
#include "base/id_map.h" #include "base/id_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "content/public/renderer/render_process_observer.h" #include "content/public/renderer/render_process_observer.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerCache.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h" #include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerCacheStorage.h" #include "third_party/WebKit/public/platform/WebServiceWorkerCacheStorage.h"
namespace content { namespace content {
struct ServiceWorkerFetchRequest;
class ServiceWorkerScriptContext; class ServiceWorkerScriptContext;
struct ServiceWorkerResponse;
// There is one ServiceWorkerCacheStorageDispatcher per // There is one ServiceWorkerCacheStorageDispatcher per
// ServiceWorkerScriptContext. It starts CacheStorage operations with messages // ServiceWorkerScriptContext. It handles CacheStorage operations with messages
// to the browser process and runs callbacks at operation completion. // to/from the browser, creating Cache objects (for which it also handles
// messages) as it goes.
class ServiceWorkerCacheStorageDispatcher class ServiceWorkerCacheStorageDispatcher
: public blink::WebServiceWorkerCacheStorage { : public blink::WebServiceWorkerCacheStorage {
...@@ -29,9 +34,10 @@ class ServiceWorkerCacheStorageDispatcher ...@@ -29,9 +34,10 @@ class ServiceWorkerCacheStorageDispatcher
ServiceWorkerScriptContext* script_context); ServiceWorkerScriptContext* script_context);
virtual ~ServiceWorkerCacheStorageDispatcher(); virtual ~ServiceWorkerCacheStorageDispatcher();
// ServiceWorkerScriptContext calls our OnMessageReceived directly.
bool OnMessageReceived(const IPC::Message& message); bool OnMessageReceived(const IPC::Message& message);
// Message handlers for messages from the browser process. // Message handlers for CacheStorage messages from the browser process.
void OnCacheStorageGetSuccess(int request_id, int cache_id); void OnCacheStorageGetSuccess(int request_id, int cache_id);
void OnCacheStorageHasSuccess(int request_id); void OnCacheStorageHasSuccess(int request_id);
void OnCacheStorageCreateSuccess(int request_id, int cache_id); void OnCacheStorageCreateSuccess(int request_id, int cache_id);
...@@ -50,6 +56,27 @@ class ServiceWorkerCacheStorageDispatcher ...@@ -50,6 +56,27 @@ class ServiceWorkerCacheStorageDispatcher
void OnCacheStorageKeysError(int request_id, void OnCacheStorageKeysError(int request_id,
blink::WebServiceWorkerCacheError reason); blink::WebServiceWorkerCacheError reason);
// Message handlers for Cache messages from the browser process.
void OnCacheMatchSuccess(int request_id,
const ServiceWorkerResponse& response);
void OnCacheMatchAllSuccess(
int request_id,
const std::vector<ServiceWorkerResponse>& response);
void OnCacheKeysSuccess(
int request_id,
const std::vector<ServiceWorkerFetchRequest>& response);
void OnCacheBatchSuccess(int request_id,
const std::vector<ServiceWorkerResponse>& response);
void OnCacheMatchError(int request_id,
blink::WebServiceWorkerCacheError reason);
void OnCacheMatchAllError(int request_id,
blink::WebServiceWorkerCacheError reason);
void OnCacheKeysError(int request_id,
blink::WebServiceWorkerCacheError reason);
void OnCacheBatchError(int request_id,
blink::WebServiceWorkerCacheError reason);
// From WebServiceWorkerCacheStorage: // From WebServiceWorkerCacheStorage:
virtual void dispatchGet(CacheStorageWithCacheCallbacks* callbacks, virtual void dispatchGet(CacheStorageWithCacheCallbacks* callbacks,
const blink::WebString& cacheName); const blink::WebString& cacheName);
...@@ -61,13 +88,47 @@ class ServiceWorkerCacheStorageDispatcher ...@@ -61,13 +88,47 @@ class ServiceWorkerCacheStorageDispatcher
const blink::WebString& cacheName); const blink::WebString& cacheName);
virtual void dispatchKeys(CacheStorageKeysCallbacks* callbacks); virtual void dispatchKeys(CacheStorageKeysCallbacks* callbacks);
// These methods are used by WebCache to forward events to the browser
// process.
void dispatchMatchForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const blink::WebServiceWorkerCache::QueryParams& query_params);
void dispatchMatchAllForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
const blink::WebServiceWorkerRequest& request,
const blink::WebServiceWorkerCache::QueryParams& query_params);
void dispatchKeysForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks,
const blink::WebServiceWorkerRequest* request,
const blink::WebServiceWorkerCache::QueryParams& query_params);
void dispatchBatchForCache(
int cache_id,
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
const blink::WebVector<blink::WebServiceWorkerCache::BatchOperation>&
batch_operations);
void OnWebCacheDestruction(int cache_id);
private: private:
class WebCache;
typedef IDMap<CacheStorageCallbacks, IDMapOwnPointer> CallbacksMap; typedef IDMap<CacheStorageCallbacks, IDMapOwnPointer> CallbacksMap;
typedef IDMap<CacheStorageWithCacheCallbacks, IDMapOwnPointer> typedef IDMap<CacheStorageWithCacheCallbacks, IDMapOwnPointer>
WithCacheCallbacksMap; WithCacheCallbacksMap;
typedef IDMap<CacheStorageKeysCallbacks, IDMapOwnPointer> typedef IDMap<CacheStorageKeysCallbacks, IDMapOwnPointer>
KeysCallbacksMap; KeysCallbacksMap;
typedef IDMap<blink::WebServiceWorkerCache::CacheMatchCallbacks,
IDMapOwnPointer> MatchCallbacksMap;
typedef IDMap<blink::WebServiceWorkerCache::CacheWithResponsesCallbacks,
IDMapOwnPointer> WithResponsesCallbacksMap;
typedef IDMap<blink::WebServiceWorkerCache::CacheWithRequestsCallbacks,
IDMapOwnPointer> WithRequestsCallbacksMap;
// Not owned. The script context containing this object. // Not owned. The script context containing this object.
ServiceWorkerScriptContext* script_context_; ServiceWorkerScriptContext* script_context_;
...@@ -77,6 +138,18 @@ class ServiceWorkerCacheStorageDispatcher ...@@ -77,6 +138,18 @@ class ServiceWorkerCacheStorageDispatcher
CallbacksMap delete_callbacks_; CallbacksMap delete_callbacks_;
KeysCallbacksMap keys_callbacks_; KeysCallbacksMap keys_callbacks_;
// The individual caches created under this CacheStorage object.
IDMap<WebCache, IDMapExternalPointer> web_caches_;
// These ID maps are held in the CacheStorage object rather than the Cache
// object to ensure that the IDs are unique.
MatchCallbacksMap cache_match_callbacks_;
WithResponsesCallbacksMap cache_match_all_callbacks_;
WithRequestsCallbacksMap cache_keys_callbacks_;
WithResponsesCallbacksMap cache_batch_callbacks_;
base::WeakPtrFactory<ServiceWorkerCacheStorageDispatcher> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageDispatcher); DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageDispatcher);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment