diff options
Diffstat (limited to 'webkit/appcache')
-rw-r--r-- | webkit/appcache/appcache_backend_impl.cc | 63 | ||||
-rw-r--r-- | webkit/appcache/appcache_backend_impl.h | 41 | ||||
-rw-r--r-- | webkit/appcache/appcache_frontend_impl.cc | 42 | ||||
-rw-r--r-- | webkit/appcache/appcache_frontend_impl.h | 25 | ||||
-rw-r--r-- | webkit/appcache/appcache_interfaces.cc | 44 | ||||
-rw-r--r-- | webkit/appcache/appcache_interfaces.h | 75 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.cc | 172 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.h | 64 |
8 files changed, 526 insertions, 0 deletions
diff --git a/webkit/appcache/appcache_backend_impl.cc b/webkit/appcache/appcache_backend_impl.cc new file mode 100644 index 0000000..c59fc6d --- /dev/null +++ b/webkit/appcache/appcache_backend_impl.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/appcache/appcache_backend_impl.h" + +#include "base/logging.h" +#include "webkit/appcache/web_application_cache_host_impl.h" + +namespace appcache { + +AppCacheBackendImpl::~AppCacheBackendImpl() { + // TODO(michaeln): if (service_) service_->UnregisterFrontend(frontend_); +} + +void AppCacheBackendImpl::Initialize(AppCacheService* service, + AppCacheFrontend* frontend) { + DCHECK(!service_ && !frontend_ && frontend); // DCHECK(service) + service_ = service; + frontend_ = frontend; + // TODO(michaeln): service_->RegisterFrontend(frontend_); +} + +void AppCacheBackendImpl::RegisterHost(int host_id) { + // TODO(michaeln): plumb to service +} + +void AppCacheBackendImpl::UnregisterHost(int host_id) { + // TODO(michaeln): plumb to service +} + +void AppCacheBackendImpl::SelectCache( + int host_id, + const GURL& document_url, + const int64 cache_document_was_loaded_from, + const GURL& manifest_url) { + // TODO(michaeln): plumb to service + frontend_->OnCacheSelected(host_id, kNoCacheId, UNCACHED); +} + +void AppCacheBackendImpl::MarkAsForeignEntry( + int host_id, + const GURL& document_url, + int64 cache_document_was_loaded_from) { + // TODO(michaeln): plumb to service +} + +Status AppCacheBackendImpl::GetStatus(int host_id) { + // TODO(michaeln): plumb to service + return UNCACHED; +} + +bool AppCacheBackendImpl::StartUpdate(int host_id) { + // TODO(michaeln): plumb to service + return false; +} + +bool AppCacheBackendImpl::SwapCache(int host_id) { + // TODO(michaeln): plumb to service + return false; +} + +} // namespace appcache
\ No newline at end of file diff --git a/webkit/appcache/appcache_backend_impl.h b/webkit/appcache/appcache_backend_impl.h new file mode 100644 index 0000000..93a7083 --- /dev/null +++ b/webkit/appcache/appcache_backend_impl.h @@ -0,0 +1,41 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_APPCACHE_APPCACHE_BACKEND_IMPL_H_ +#define WEBKIT_APPCACHE_APPCACHE_BACKEND_IMPL_H_ + +#include "webkit/appcache/appcache_interfaces.h" + +namespace appcache { + +class AppCacheService; + +class AppCacheBackendImpl : public AppCacheBackend { + public: + AppCacheBackendImpl() : service_(NULL), frontend_(NULL) {} + ~AppCacheBackendImpl(); + + void Initialize(AppCacheService* service, + AppCacheFrontend* frontend); + + virtual void RegisterHost(int host_id); + virtual void UnregisterHost(int host_id); + virtual void SelectCache(int host_id, + const GURL& document_url, + const int64 cache_document_was_loaded_from, + const GURL& manifest_url); + virtual void MarkAsForeignEntry(int host_id, const GURL& document_url, + int64 cache_document_was_loaded_from); + virtual Status GetStatus(int host_id); + virtual bool StartUpdate(int host_id); + virtual bool SwapCache(int host_id); + + private: + AppCacheService* service_; + AppCacheFrontend* frontend_; +}; + +} // namespace + +#endif // WEBKIT_APPCACHE_APPCACHE_BACKEND_IMPL_H_ diff --git a/webkit/appcache/appcache_frontend_impl.cc b/webkit/appcache/appcache_frontend_impl.cc new file mode 100644 index 0000000..a0ef05e --- /dev/null +++ b/webkit/appcache/appcache_frontend_impl.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/appcache/appcache_frontend_impl.h" +#include "webkit/appcache/web_application_cache_host_impl.h" + +namespace appcache { + +// Inline helper to keep the lines shorter and unwrapped. +inline WebApplicationCacheHostImpl* GetHost(int id) { + return WebApplicationCacheHostImpl::FromId(id); +} + +void AppCacheFrontendImpl::OnCacheSelected(int host_id, int64 cache_id , + Status status) { + WebApplicationCacheHostImpl* host = GetHost(host_id); + if (host) + host->OnCacheSelected(cache_id, status); +} + +void AppCacheFrontendImpl::OnStatusChanged(const std::vector<int>& host_ids, + Status status) { + for (std::vector<int>::const_iterator i = host_ids.begin(); + i != host_ids.end(); ++i) { + WebApplicationCacheHostImpl* host = GetHost(*i); + if (host) + host->OnStatusChanged(status); + } +} + +void AppCacheFrontendImpl::OnEventRaised(const std::vector<int>& host_ids, + EventID event_id) { + for (std::vector<int>::const_iterator i = host_ids.begin(); + i != host_ids.end(); ++i) { + WebApplicationCacheHostImpl* host = GetHost(*i); + if (host) + host->OnEventRaised(event_id); + } +} + +} // namespace appcache diff --git a/webkit/appcache/appcache_frontend_impl.h b/webkit/appcache/appcache_frontend_impl.h new file mode 100644 index 0000000..e4ed922 --- /dev/null +++ b/webkit/appcache/appcache_frontend_impl.h @@ -0,0 +1,25 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_APPCACHE_APPCACHE_FRONTEND_IMPL_H_ +#define WEBKIT_APPCACHE_APPCACHE_FRONTEND_IMPL_H_ + +#include <vector> +#include "webkit/appcache/appcache_interfaces.h" + +namespace appcache { + +class AppCacheFrontendImpl : public AppCacheFrontend { + public: + virtual void OnCacheSelected(int host_id, int64 cache_id , + Status status); + virtual void OnStatusChanged(const std::vector<int>& host_ids, + Status status); + virtual void OnEventRaised(const std::vector<int>& host_ids, + EventID event_id); +}; + +} // namespace + +#endif // WEBKIT_APPCACHE_APPCACHE_FRONTEND_IMPL_H_ diff --git a/webkit/appcache/appcache_interfaces.cc b/webkit/appcache/appcache_interfaces.cc new file mode 100644 index 0000000..bd73879 --- /dev/null +++ b/webkit/appcache/appcache_interfaces.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/appcache/appcache_interfaces.h" +#include "webkit/api/public/WebApplicationCacheHost.h" + +using WebKit::WebApplicationCacheHost; + +namespace appcache { + +// Ensure that enum values never get out of sync with the +// ones declared for use within the WebKit api + +COMPILE_ASSERT((int)WebApplicationCacheHost::Uncached == + (int)UNCACHED, Uncached); +COMPILE_ASSERT((int)WebApplicationCacheHost::Idle == + (int)IDLE, Idle); +COMPILE_ASSERT((int)WebApplicationCacheHost::Checking == + (int)CHECKING, Checking); +COMPILE_ASSERT((int)WebApplicationCacheHost::Downloading == + (int)DOWNLOADING, Downloading); +COMPILE_ASSERT((int)WebApplicationCacheHost::UpdateReady == + (int)UPDATE_READY, UpdateReady); +COMPILE_ASSERT((int)WebApplicationCacheHost::Obsolete == + (int)OBSOLETE, Obsolete); +COMPILE_ASSERT((int)WebApplicationCacheHost::CheckingEvent == + (int)CHECKING_EVENT, CheckingEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::ErrorEvent == + (int)ERROR_EVENT, ErrorEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::NoUpdateEvent == + (int)NO_UPDATE_EVENT, NoUpdateEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::DownloadingEvent == + (int)DOWNLOADING_EVENT, DownloadingEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::ProgressEvent == + (int)PROGRESS_EVENT, ProgressEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::UpdateReadyEvent == + (int)UPDATE_READY_EVENT, UpdateReadyEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::CachedEvent == + (int)CACHED_EVENT, CachedEvent); +COMPILE_ASSERT((int)WebApplicationCacheHost::ObsoleteEvent == + (int)OBSOLETE_EVENT, ObsoleteEvent); + +} // namespace diff --git a/webkit/appcache/appcache_interfaces.h b/webkit/appcache/appcache_interfaces.h new file mode 100644 index 0000000..ee63633 --- /dev/null +++ b/webkit/appcache/appcache_interfaces.h @@ -0,0 +1,75 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ +#define WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ + +#include <vector> +#include "base/basictypes.h" + +class GURL; + +namespace appcache { + +// Defines constants, types, and abstract classes used in the main +// process and in child processes. + +static const int kNoHostId = 0; +static const int64 kNoCacheId = 0; +static const int64 kUnknownCacheId = -1; + +enum Status { + UNCACHED, + IDLE, + CHECKING, + DOWNLOADING, + UPDATE_READY, + OBSOLETE +}; + +enum EventID { + CHECKING_EVENT, + ERROR_EVENT, + NO_UPDATE_EVENT, + DOWNLOADING_EVENT, + PROGRESS_EVENT, + UPDATE_READY_EVENT, + CACHED_EVENT, + OBSOLETE_EVENT +}; + +// Interface used by backend to talk to frontend. +class AppCacheFrontend { + public: + virtual void OnCacheSelected(int host_id, int64 cache_id , + Status status) = 0; + virtual void OnStatusChanged(const std::vector<int>& host_ids, + Status status) = 0; + virtual void OnEventRaised(const std::vector<int>& host_ids, + EventID event_id) = 0; + + virtual ~AppCacheFrontend() {} +}; + +// Interface used by frontend to talk to backend. +class AppCacheBackend { + public: + virtual void RegisterHost(int host_id) = 0; + virtual void UnregisterHost(int host_id) = 0; + virtual void SelectCache(int host_id, + const GURL& document_url, + const int64 cache_document_was_loaded_from, + const GURL& manifest_url) = 0; + virtual void MarkAsForeignEntry(int host_id, const GURL& document_url, + int64 cache_document_was_loaded_from) = 0; + virtual Status GetStatus(int host_id) = 0; + virtual bool StartUpdate(int host_id) = 0; + virtual bool SwapCache(int host_id) = 0; + + virtual ~AppCacheBackend() {} +}; + +} // namespace + +#endif // WEBKIT_APPCACHE_APPCACHE_INTERFACES_H_ diff --git a/webkit/appcache/web_application_cache_host_impl.cc b/webkit/appcache/web_application_cache_host_impl.cc new file mode 100644 index 0000000..02a698f --- /dev/null +++ b/webkit/appcache/web_application_cache_host_impl.cc @@ -0,0 +1,172 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/appcache/web_application_cache_host_impl.h" + +#include "base/compiler_specific.h" +#include "base/id_map.h" +#include "webkit/api/public/WebURL.h" +#include "webkit/api/public/WebURLRequest.h" +#include "webkit/api/public/WebURLResponse.h" + +using WebKit::WebApplicationCacheHost; +using WebKit::WebApplicationCacheHostClient; +using WebKit::WebURLRequest; +using WebKit::WebURL; +using WebKit::WebURLResponse; + +namespace appcache { + +static IDMap<WebApplicationCacheHostImpl> all_hosts; + +WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { + return all_hosts.Lookup(id); +} + +WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( + WebApplicationCacheHostClient* client, + AppCacheBackend* backend) + : client_(client), + backend_(backend), + ALLOW_THIS_IN_INITIALIZER_LIST(host_id_(all_hosts.Add(this))), + has_status_(false), + status_(UNCACHED), + has_cached_status_(false), + cached_status_(UNCACHED), + is_in_http_family_(false), + should_capture_main_response_(MAYBE) { + DCHECK(client && backend && (host_id_ != kNoHostId)); + + backend_->RegisterHost(host_id_); +} + +WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { + backend_->UnregisterHost(host_id_); +} + +void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id, + appcache::Status status) { + status_ = status; + has_status_ = true; +} + +void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { + if (has_status_) + status_ = status; +} + +void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { + client_->notifyEventListener(static_cast<EventID>(event_id)); +} + +void WebApplicationCacheHostImpl::willStartMainResourceRequest( + WebURLRequest& request) { + request.setAppCacheContextID(host_id_); +} + +void WebApplicationCacheHostImpl::willStartSubResourceRequest( + WebURLRequest& request) { + request.setAppCacheContextID(host_id_); +} + +void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { + // Reset any previous status values we've received from the backend + // since we're now selecting a new cache. + has_status_ = false; + has_cached_status_ = false; + should_capture_main_response_ = NO; + backend_->SelectCache(host_id_, main_response_url_, + main_response_.appCacheID(), + GURL()); +} + +bool WebApplicationCacheHostImpl::selectCacheWithManifest( + const WebURL& manifest_url) { + // Reset any previous status values we've received from the backend + // since we're now selecting a new cache. + has_status_ = false; + has_cached_status_ = false; + + // Check for new 'master' entries. + if (main_response_.appCacheID() == kNoCacheId) { + should_capture_main_response_ = is_in_http_family_ ? YES : NO; + backend_->SelectCache(host_id_, main_response_url_, + kNoCacheId, manifest_url); + return true; + } + + // Check for 'foreign' entries. + // TODO(michaeln): add manifestUrl() accessor to WebURLResponse, + // for now we don't really detect 'foreign' entries. + // TODO(michaeln): put an == operator on WebURL? + GURL manifest_gurl(manifest_url); + GURL main_response_manifest_gurl(manifest_url); // = mainResp.manifestUrl() + if (main_response_manifest_gurl != manifest_gurl) { + backend_->MarkAsForeignEntry(host_id_, main_response_url_, + main_response_.appCacheID()); + selectCacheWithoutManifest(); + return false; // the navigation will be restarted + } + + // Its a 'master' entry thats already in the cache. + backend_->SelectCache(host_id_, main_response_url_, + main_response_.appCacheID(), + manifest_gurl); + return true; +} + +void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( + const WebURLResponse& response) { + main_response_ = response; + main_response_url_ = main_response_.url(); + is_in_http_family_ = main_response_url_.SchemeIs("http") || + main_response_url_.SchemeIs("https"); + if ((main_response_.appCacheID() != kNoCacheId) || !is_in_http_family_) + should_capture_main_response_ = NO; +} + +void WebApplicationCacheHostImpl::didReceiveDataForMainResource( + const char* data, int len) { + // TODO(michaeln): write me +} + +void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { + // TODO(michaeln): write me +} + +WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { + // We're careful about the status value to avoid race conditions. + // + // Generally the webappcachehost sends an async stream of messages to the + // backend, and receives an asyncronous stream of events from the backend. + // In the backend, all operations are serialized and as state changes + // 'events' are streamed out to relevant parties. In particular the + // 'SelectCache' message is async. Regular page loading and navigation + // involves two non-blocking ipc calls: RegisterHost + SelectCache. + // + // However, the page can call the scriptable API in advance of a cache + // selection being complete (and/or in advance of the webappcachehost having + // received the event about completion). In that case, we force an end-to-end + // fetch of the 'status' value, and cache that value seperately from the + // value we receive via the async event stream. We'll use that cached value + // until cache selection is complete. + if (has_status_) + return static_cast<WebApplicationCacheHost::Status>(status_); + + if (!has_cached_status_) { + cached_status_ = backend_->GetStatus(host_id_); + has_cached_status_ = true; + } + return static_cast<WebApplicationCacheHost::Status>(cached_status_); +} + +bool WebApplicationCacheHostImpl::startUpdate() { + return backend_->StartUpdate(host_id_); +} + +bool WebApplicationCacheHostImpl::swapCache() { + return backend_->SwapCache(host_id_); +} + +} // appcache namespace diff --git a/webkit/appcache/web_application_cache_host_impl.h b/webkit/appcache/web_application_cache_host_impl.h new file mode 100644 index 0000000..dbc00f1 --- /dev/null +++ b/webkit/appcache/web_application_cache_host_impl.h @@ -0,0 +1,64 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_ +#define WEBKIT_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_ + +#include "googleurl/src/gurl.h" +#include "webkit/api/public/WebApplicationCacheHostClient.h" +#include "webkit/api/public/WebURLResponse.h" +#include "webkit/appcache/appcache_interfaces.h" + +namespace appcache { + +class WebApplicationCacheHostImpl : public WebKit::WebApplicationCacheHost { + public: + // Returns the host having given id or NULL if there is no such host. + static WebApplicationCacheHostImpl* FromId(int id); + + WebApplicationCacheHostImpl(WebKit::WebApplicationCacheHostClient* client, + AppCacheBackend* backend); + virtual ~WebApplicationCacheHostImpl(); + + int host_id() const { return host_id_; } + + void OnCacheSelected(int64 selected_cache_id, appcache::Status status); + void OnStatusChanged(appcache::Status); + void OnEventRaised(appcache::EventID); + + // WebApplicationCacheHost methods + virtual void willStartMainResourceRequest(WebKit::WebURLRequest&); + virtual void willStartSubResourceRequest(WebKit::WebURLRequest&); + virtual void selectCacheWithoutManifest(); + virtual bool selectCacheWithManifest(const WebKit::WebURL& manifestURL); + virtual void didReceiveResponseForMainResource(const WebKit::WebURLResponse&); + virtual void didReceiveDataForMainResource(const char* data, int len); + virtual void didFinishLoadingMainResource(bool success); + virtual WebKit::WebApplicationCacheHost::Status status(); + virtual bool startUpdate(); + virtual bool swapCache(); + + private: + enum ShouldCaptureMainResponse { + MAYBE, + YES, + NO + }; + + WebKit::WebApplicationCacheHostClient* client_; + AppCacheBackend* backend_; + int host_id_; + bool has_status_; + appcache::Status status_; + bool has_cached_status_; + appcache::Status cached_status_; + WebKit::WebURLResponse main_response_; + GURL main_response_url_; + bool is_in_http_family_; + ShouldCaptureMainResponse should_capture_main_response_; +}; + +} // namespace + +#endif // WEBKIT_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_ |