summaryrefslogtreecommitdiffstats
path: root/webkit/appcache
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/appcache')
-rw-r--r--webkit/appcache/appcache_backend_impl.cc63
-rw-r--r--webkit/appcache/appcache_backend_impl.h41
-rw-r--r--webkit/appcache/appcache_frontend_impl.cc42
-rw-r--r--webkit/appcache/appcache_frontend_impl.h25
-rw-r--r--webkit/appcache/appcache_interfaces.cc44
-rw-r--r--webkit/appcache/appcache_interfaces.h75
-rw-r--r--webkit/appcache/web_application_cache_host_impl.cc172
-rw-r--r--webkit/appcache/web_application_cache_host_impl.h64
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_