summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 22:30:30 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 22:30:30 +0000
commit23f1ef1a445a53bcefc8ddab9f4184b1db7321c5 (patch)
treec9f17a33025ed5b5c5dee76a7b4fef9104e9a995
parente143c823ce66af5a83a9a17b6f5938eb16e49392 (diff)
downloadchromium_src-23f1ef1a445a53bcefc8ddab9f4184b1db7321c5.zip
chromium_src-23f1ef1a445a53bcefc8ddab9f4184b1db7321c5.tar.gz
chromium_src-23f1ef1a445a53bcefc8ddab9f4184b1db7321c5.tar.bz2
Plumb request interception into the appcache library for both chrome and test_shell.
AppCache library: * Added AppCacheInterceptor, which is derived from URLRequest::Interceptor. Chrome: * Each UserProfile instantiates a ChromeAppCacheService, which is derived from an appcache library class. * Each ChromeURLRequestContext associated with that profile has a reference to that instance. * ResourceDispatcherHost pokes AppCacheInterceptor when initiating URLRequests and when returning the response head. TestShell: * Added SimpleAppCacheSystem which bundles together appcache lib components for use in a single process with an UI and IO thread. * TestShellWebKit instantiates and initializes an instance of the above, aimed at at temp directory that will get cleaned up when the test run is over. * SimpleResourceLoaderBridge pokes the system when initiating URLRequests and when returning the response head. TEST=none, although many existing tests exercise this stuff BUG=none Review URL: http://codereview.chromium.org/173406 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25099 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_profile_impl.h3
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc3
-rw-r--r--chrome/browser/net/chrome_url_request_context.h9
-rw-r--r--chrome/browser/profile.cc32
-rw-r--r--chrome/browser/profile.h8
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc15
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc5
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/common/appcache/appcache_backend_proxy.cc7
-rw-r--r--chrome/common/appcache/appcache_dispatcher_host.cc85
-rw-r--r--chrome/common/appcache/appcache_dispatcher_host.h20
-rw-r--r--chrome/common/appcache/appcache_frontend_proxy.cc1
-rw-r--r--chrome/common/appcache/chrome_appcache_service.h67
-rw-r--r--chrome/common/chrome_constants.cc1
-rw-r--r--chrome/common/chrome_constants.h1
-rw-r--r--chrome/test/testing_profile.h5
-rw-r--r--webkit/appcache/appcache_backend_impl.cc48
-rw-r--r--webkit/appcache/appcache_backend_impl.h44
-rw-r--r--webkit/appcache/appcache_host.h4
-rw-r--r--webkit/appcache/appcache_interceptor.cc125
-rw-r--r--webkit/appcache/appcache_interceptor.h60
-rw-r--r--webkit/appcache/appcache_service.cc15
-rw-r--r--webkit/appcache/appcache_service.h27
-rw-r--r--webkit/appcache/web_application_cache_host_impl.cc1
-rw-r--r--webkit/tools/test_shell/simple_appcache_system.cc323
-rw-r--r--webkit/tools/test_shell/simple_appcache_system.h108
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc49
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.h1
-rw-r--r--webkit/tools/test_shell/test_shell.gyp1
-rw-r--r--webkit/tools/test_shell/test_shell_webkit_init.h12
-rw-r--r--webkit/webkit.gyp2
31 files changed, 991 insertions, 92 deletions
diff --git a/chrome/browser/automation/automation_profile_impl.h b/chrome/browser/automation/automation_profile_impl.h
index c0f2592..7a22fc3 100644
--- a/chrome/browser/automation/automation_profile_impl.h
+++ b/chrome/browser/automation/automation_profile_impl.h
@@ -45,6 +45,9 @@ class AutomationProfileImpl : public Profile {
virtual Profile* GetOriginalProfile() {
return original_profile_->GetOriginalProfile();
}
+ virtual ChromeAppCacheService* GetAppCacheService() {
+ return original_profile_->GetAppCacheService();
+ }
virtual VisitedLinkMaster* GetVisitedLinkMaster() {
return original_profile_->GetVisitedLinkMaster();
}
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index 65671d4..0bc5572 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -354,6 +354,8 @@ ChromeURLRequestContext::ChromeURLRequestContext(Profile* profile)
}
ssl_config_service_ = profile->GetSSLConfigService();
+
+ appcache_service_ = profile->GetAppCacheService();
}
ChromeURLRequestContext::ChromeURLRequestContext(
@@ -378,6 +380,7 @@ ChromeURLRequestContext::ChromeURLRequestContext(
blacklist_ = other->blacklist_;
is_media_ = other->is_media_;
is_off_the_record_ = other->is_off_the_record_;
+ appcache_service_ = other->appcache_service_;
}
// NotificationObserver implementation.
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index f4baea6..d0303d7 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/file_path.h"
+#include "chrome/common/appcache/chrome_appcache_service.h"
#include "chrome/common/net/cookie_monster_sqlite.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/pref_service.h"
@@ -65,6 +66,12 @@ class ChromeURLRequestContext : public URLRequestContext,
return user_script_dir_path_;
}
+ // Gets the appcache service to be used for requests in this context.
+ // May be NULL if requests for this context aren't subject to appcaching.
+ ChromeAppCacheService* appcache_service() const {
+ return appcache_service_.get();
+ }
+
virtual const std::string& GetUserAgent(const GURL& url) const;
virtual bool InterceptCookie(const URLRequest* request, std::string* cookie);
@@ -118,6 +125,8 @@ class ChromeURLRequestContext : public URLRequestContext,
// Path to the directory user scripts are stored in.
FilePath user_script_dir_path_;
+ scoped_refptr<ChromeAppCacheService> appcache_service_;
+
scoped_ptr<SQLitePersistentCookieStore> cookie_db_;
PrefService* prefs_;
const Blacklist* blacklist_;
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index fb92549..1aa04e8 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/visitedlink_master.h"
#include "chrome/browser/visitedlink_event_listener.h"
#include "chrome/browser/webdata/web_data_service.h"
+#include "chrome/common/appcache/chrome_appcache_service.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -115,6 +116,16 @@ static void CleanupRequestContext(ChromeURLRequestContext* context) {
}
}
+static void CleanupAppCacheService(ChromeAppCacheService* service) {
+ if (service) {
+ MessageLoop* io_thread = ChromeThread::GetMessageLoop(ChromeThread::IO);
+ if (io_thread)
+ io_thread->ReleaseSoon(FROM_HERE, service);
+ else
+ service->Release();
+ }
+}
+
// static
void Profile::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(prefs::kSearchSuggestEnabled, true);
@@ -187,6 +198,7 @@ class OffTheRecordProfileImpl : public Profile,
virtual ~OffTheRecordProfileImpl() {
CleanupRequestContext(request_context_);
CleanupRequestContext(extensions_request_context_);
+ CleanupAppCacheService(appcache_service_.release());
}
virtual FilePath GetPath() { return profile_->GetPath(); }
@@ -208,6 +220,14 @@ class OffTheRecordProfileImpl : public Profile,
return profile_;
}
+ virtual ChromeAppCacheService* GetAppCacheService() {
+ if (!appcache_service_.get()) {
+ appcache_service_ = new ChromeAppCacheService();
+ appcache_service_->InitializeOnUIThread(GetPath(), true);
+ }
+ return appcache_service_.get();
+ }
+
virtual VisitedLinkMaster* GetVisitedLinkMaster() {
// We don't provide access to the VisitedLinkMaster when we're OffTheRecord
// because we don't want to leak the sites that the user has visited before.
@@ -484,6 +504,9 @@ class OffTheRecordProfileImpl : public Profile,
ChromeURLRequestContext* extensions_request_context_;
+ // Use a seperate appcache service for OTR.
+ scoped_refptr<ChromeAppCacheService> appcache_service_;
+
// The download manager that only stores downloaded items in memory.
scoped_refptr<DownloadManager> download_manager_;
@@ -700,6 +723,7 @@ ProfileImpl::~ProfileImpl() {
CleanupRequestContext(request_context_);
CleanupRequestContext(media_request_context_);
CleanupRequestContext(extensions_request_context_);
+ CleanupAppCacheService(appcache_service_.release());
// When the request contexts are gone, the blacklist wont be needed anymore.
delete blacklist_;
@@ -749,6 +773,14 @@ Profile* ProfileImpl::GetOriginalProfile() {
return this;
}
+ChromeAppCacheService* ProfileImpl::GetAppCacheService() {
+ if (!appcache_service_.get()) {
+ appcache_service_ = new ChromeAppCacheService();
+ appcache_service_->InitializeOnUIThread(GetPath(), false);
+ }
+ return appcache_service_.get();
+}
+
VisitedLinkMaster* ProfileImpl::GetVisitedLinkMaster() {
if (!visited_link_master_.get()) {
scoped_ptr<VisitedLinkMaster> visited_links(
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index 36679a7..83ae64c 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -25,6 +25,7 @@ class SSLConfigService;
class Blacklist;
class BookmarkModel;
class BrowserThemeProvider;
+class ChromeAppCacheService;
class ChromeURLRequestContext;
class DownloadManager;
class Extension;
@@ -117,6 +118,11 @@ class Profile {
// profile is not off the record.
virtual Profile* GetOriginalProfile() = 0;
+ // Retrieves a pointer to the AppCacheService for this profile.
+ // Chrome request contexts associated with this profile also have
+ // a reference to this instance.
+ virtual ChromeAppCacheService* GetAppCacheService() = 0;
+
// Retrieves a pointer to the VisitedLinkMaster associated with this
// profile. The VisitedLinkMaster is lazily created the first time
// that this method is called.
@@ -359,6 +365,7 @@ class ProfileImpl : public Profile,
virtual Profile* GetOffTheRecordProfile();
virtual void DestroyOffTheRecordProfile();
virtual Profile* GetOriginalProfile();
+ virtual ChromeAppCacheService* GetAppCacheService();
virtual VisitedLinkMaster* GetVisitedLinkMaster();
virtual UserScriptMaster* GetUserScriptMaster();
virtual SSLHostState* GetSSLHostState();
@@ -444,6 +451,7 @@ class ProfileImpl : public Profile,
FilePath path_;
FilePath base_cache_path_;
+ scoped_refptr<ChromeAppCacheService> appcache_service_;
scoped_ptr<VisitedLinkEventListener> visited_link_event_listener_;
scoped_ptr<VisitedLinkMaster> visited_link_master_;
scoped_refptr<ExtensionsService> extensions_service_;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 7d42929..669118b 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -54,6 +54,7 @@
#include "net/base/ssl_cert_request_info.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
+#include "webkit/appcache/appcache_interceptor.h"
#include "webkit/appcache/appcache_interfaces.h"
// TODO(port): Move these includes to the above section when porting is done.
@@ -239,9 +240,11 @@ void PopulateResourceResponse(URLRequest* request,
request->GetCharset(&response->response_head.charset);
response->response_head.filter_policy = filter_policy;
response->response_head.content_length = request->GetExpectedContentSize();
- response->response_head.appcache_id = appcache::kNoCacheId;
- response->response_head.appcache_manifest_url = GURL();
request->GetMimeType(&response->response_head.mime_type);
+ appcache::AppCacheInterceptor::GetExtraResponseInfo(
+ request,
+ &response->response_head.appcache_id,
+ &response->response_head.appcache_manifest_url);
}
} // namespace
@@ -294,6 +297,9 @@ void ResourceDispatcherHost::Initialize() {
DCHECK(MessageLoop::current() == ui_loop_);
download_file_manager_->Initialize();
safe_browsing_->Initialize(io_loop_);
+ io_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(&appcache::AppCacheInterceptor::EnsureRegistered));
}
void ResourceDispatcherHost::Shutdown() {
@@ -582,6 +588,11 @@ void ResourceDispatcherHost::BeginRequest(
chrome_browser_net::SetOriginProcessUniqueIDForRequest(
request_data.origin_child_id, request);
+ // Have the appcache associate its extra info with the request.
+ appcache::AppCacheInterceptor::SetExtraRequestInfo(
+ request, context ? context->appcache_service() : NULL, child_id,
+ request_data.appcache_host_id, request_data.resource_type);
+
BeginRequestInternal(request);
}
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 61debd5..b211f67 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -156,7 +156,8 @@ ResourceMessageFilter::ResourceMessageFilter(
profile_(profile),
render_widget_helper_(render_widget_helper),
audio_renderer_host_(audio_renderer_host),
- appcache_dispatcher_host_(new AppCacheDispatcherHost),
+ appcache_dispatcher_host_(
+ new AppCacheDispatcherHost(profile->GetAppCacheService())),
ALLOW_THIS_IN_INITIALIZER_LIST(dom_storage_dispatcher_host_(
new DOMStorageDispatcherHost(this, profile->GetWebKitContext(),
resource_dispatcher_host->webkit_thread()))),
@@ -193,7 +194,7 @@ ResourceMessageFilter::~ResourceMessageFilter() {
void ResourceMessageFilter::Init() {
render_widget_helper_->Init(id(), resource_dispatcher_host_);
- appcache_dispatcher_host_->Initialize(this);
+ appcache_dispatcher_host_->Initialize(this, id());
}
// Called on the IPC thread:
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index e4bbe6f..47a521b 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -423,6 +423,7 @@
'common/appcache/appcache_dispatcher_host.h',
'common/appcache/appcache_frontend_proxy.cc',
'common/appcache/appcache_frontend_proxy.h',
+ 'common/appcache/chrome_appcache_service.h',
'common/automation_constants.cc',
'common/automation_constants.h',
'common/bindings_policy.h',
diff --git a/chrome/common/appcache/appcache_backend_proxy.cc b/chrome/common/appcache/appcache_backend_proxy.cc
index 14b81f1..25c77f7 100644
--- a/chrome/common/appcache/appcache_backend_proxy.cc
+++ b/chrome/common/appcache/appcache_backend_proxy.cc
@@ -34,20 +34,19 @@ void AppCacheBackendProxy::MarkAsForeignEntry(
}
appcache::Status AppCacheBackendProxy::GetStatus(int host_id) {
- appcache::Status status;
+ appcache::Status status = appcache::UNCACHED;
sender_->Send(new AppCacheMsg_GetStatus(host_id, &status));
return status;
}
bool AppCacheBackendProxy::StartUpdate(int host_id) {
- bool result;
+ bool result = false;
sender_->Send(new AppCacheMsg_StartUpdate(host_id, &result));
return result;
}
bool AppCacheBackendProxy::SwapCache(int host_id) {
- bool result;
+ bool result = false;
sender_->Send(new AppCacheMsg_SwapCache(host_id, &result));
return result;
}
-
diff --git a/chrome/common/appcache/appcache_dispatcher_host.cc b/chrome/common/appcache/appcache_dispatcher_host.cc
index b71f2d9..ee0265f 100644
--- a/chrome/common/appcache/appcache_dispatcher_host.cc
+++ b/chrome/common/appcache/appcache_dispatcher_host.cc
@@ -4,12 +4,28 @@
#include "chrome/common/appcache/appcache_dispatcher_host.h"
+#include "chrome/common/appcache/chrome_appcache_service.h"
#include "chrome/common/render_messages.h"
-void AppCacheDispatcherHost::Initialize(IPC::Message::Sender* sender) {
+AppCacheDispatcherHost::AppCacheDispatcherHost(
+ ChromeAppCacheService* appcache_service)
+ : appcache_service_(appcache_service) {
+}
+
+void AppCacheDispatcherHost::Initialize(IPC::Message::Sender* sender,
+ int process_id) {
DCHECK(sender);
frontend_proxy_.set_sender(sender);
- backend_impl_.Initialize(NULL, &frontend_proxy_);
+ if (appcache_service_.get()) {
+ backend_impl_.Initialize(
+ appcache_service_.get(), &frontend_proxy_, process_id);
+ get_status_callback_.reset(
+ NewCallback(this, &AppCacheDispatcherHost::GetStatusCallback));
+ start_update_callback_.reset(
+ NewCallback(this, &AppCacheDispatcherHost::StartUpdateCallback));
+ swap_cache_callback_.reset(
+ NewCallback(this, &AppCacheDispatcherHost::SwapCacheCallback));
+ }
}
bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& msg,
@@ -31,49 +47,78 @@ bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& msg,
}
void AppCacheDispatcherHost::OnRegisterHost(int host_id) {
- backend_impl_.RegisterHost(host_id);
+ if (appcache_service_.get())
+ backend_impl_.RegisterHost(host_id);
}
void AppCacheDispatcherHost::OnUnregisterHost(int host_id) {
- backend_impl_.UnregisterHost(host_id);
+ if (appcache_service_.get())
+ backend_impl_.UnregisterHost(host_id);
}
void AppCacheDispatcherHost::OnSelectCache(
int host_id, const GURL& document_url,
int64 cache_document_was_loaded_from,
const GURL& opt_manifest_url) {
- backend_impl_.SelectCache(host_id, document_url,
- cache_document_was_loaded_from,
- opt_manifest_url);
+ if (appcache_service_.get())
+ backend_impl_.SelectCache(host_id, document_url,
+ cache_document_was_loaded_from,
+ opt_manifest_url);
+ else
+ frontend_proxy_.OnCacheSelected(
+ host_id, appcache::kNoCacheId, appcache::UNCACHED);
}
void AppCacheDispatcherHost::OnMarkAsForeignEntry(
int host_id, const GURL& document_url,
int64 cache_document_was_loaded_from) {
- backend_impl_.MarkAsForeignEntry(host_id, document_url,
- cache_document_was_loaded_from);
+ if (appcache_service_.get())
+ backend_impl_.MarkAsForeignEntry(host_id, document_url,
+ cache_document_was_loaded_from);
}
void AppCacheDispatcherHost::OnGetStatus(int host_id,
IPC::Message* reply_msg) {
- // TODO(michaeln): Handle the case where cache selection is not yet complete.
- appcache::Status status = backend_impl_.GetStatus(host_id);
- AppCacheMsg_GetStatus::WriteReplyParams(reply_msg, status);
- frontend_proxy_.sender()->Send(reply_msg);
+ if (appcache_service_.get())
+ backend_impl_.GetStatusWithCallback(
+ host_id, get_status_callback_.get(), reply_msg);
+ else
+ GetStatusCallback(appcache::UNCACHED, reply_msg);
}
void AppCacheDispatcherHost::OnStartUpdate(int host_id,
IPC::Message* reply_msg) {
- // TODO(michaeln): Handle the case where cache selection is not yet complete.
- bool success = backend_impl_.StartUpdate(host_id);
- AppCacheMsg_StartUpdate::WriteReplyParams(reply_msg, success);
- frontend_proxy_.sender()->Send(reply_msg);
+ if (appcache_service_.get())
+ backend_impl_.StartUpdateWithCallback(
+ host_id, start_update_callback_.get(), reply_msg);
+ else
+ StartUpdateCallback(false, reply_msg);
}
void AppCacheDispatcherHost::OnSwapCache(int host_id,
IPC::Message* reply_msg) {
- // TODO(michaeln): Handle the case where cache selection is not yet complete.
- bool success = backend_impl_.SwapCache(host_id);
- AppCacheMsg_SwapCache::WriteReplyParams(reply_msg, success);
+ if (appcache_service_.get())
+ backend_impl_.SwapCacheWithCallback(
+ host_id, swap_cache_callback_.get(), reply_msg);
+ else
+ SwapCacheCallback(false, reply_msg);
+}
+
+void AppCacheDispatcherHost::GetStatusCallback(
+ appcache::Status status, void* param) {
+ IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
+ AppCacheMsg_GetStatus::WriteReplyParams(reply_msg, status);
+ frontend_proxy_.sender()->Send(reply_msg);
+}
+
+void AppCacheDispatcherHost::StartUpdateCallback(bool result, void* param) {
+ IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
+ AppCacheMsg_StartUpdate::WriteReplyParams(reply_msg, result);
+ frontend_proxy_.sender()->Send(reply_msg);
+}
+
+void AppCacheDispatcherHost::SwapCacheCallback(bool result, void* param) {
+ IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
+ AppCacheMsg_SwapCache::WriteReplyParams(reply_msg, result);
frontend_proxy_.sender()->Send(reply_msg);
}
diff --git a/chrome/common/appcache/appcache_dispatcher_host.h b/chrome/common/appcache/appcache_dispatcher_host.h
index f141fdb..47f245a 100644
--- a/chrome/common/appcache/appcache_dispatcher_host.h
+++ b/chrome/common/appcache/appcache_dispatcher_host.h
@@ -6,19 +6,27 @@
#define CHROME_COMMON_APPCACHE_APPCACHE_DISPATCHER_HOST_H_
#include <vector>
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
#include "chrome/common/appcache/appcache_frontend_proxy.h"
#include "ipc/ipc_message.h"
#include "webkit/appcache/appcache_backend_impl.h"
+class ChromeAppCacheService;
+
// Handles appcache related messages sent to the main browser process from
// its child processes. There is a distinct host for each child process.
// Messages are handled on the IO thread. The ResourceMessageFilter creates
// an instance and delegates calls to it.
class AppCacheDispatcherHost {
public:
- void Initialize(IPC::Message::Sender* sender);
+ explicit AppCacheDispatcherHost(ChromeAppCacheService* appcache_service);
+
+ void Initialize(IPC::Message::Sender* sender, int process_id);
bool OnMessageReceived(const IPC::Message& msg, bool* msg_is_ok);
+ int process_id() const { return backend_impl_.process_id(); }
+
// Note: needed to satisfy ipc message dispatching macros.
bool Send(IPC::Message* msg) {
return frontend_proxy_.sender()->Send(msg);
@@ -37,8 +45,18 @@ class AppCacheDispatcherHost {
void OnStartUpdate(int host_id, IPC::Message* reply_msg);
void OnSwapCache(int host_id, IPC::Message* reply_msg);
+ void GetStatusCallback(appcache::Status status, void* param);
+ void StartUpdateCallback(bool result, void* param);
+ void SwapCacheCallback(bool result, void* param);
+
AppCacheFrontendProxy frontend_proxy_;
appcache::AppCacheBackendImpl backend_impl_;
+ scoped_refptr<ChromeAppCacheService> appcache_service_;
+ scoped_ptr<appcache::GetStatusCallback> get_status_callback_;
+ scoped_ptr<appcache::StartUpdateCallback> start_update_callback_;
+ scoped_ptr<appcache::SwapCacheCallback> swap_cache_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppCacheDispatcherHost);
};
#endif // CHROME_COMMON_APPCACHE_APPCACHE_DISPATCHER_HOST_H_
diff --git a/chrome/common/appcache/appcache_frontend_proxy.cc b/chrome/common/appcache/appcache_frontend_proxy.cc
index bf20baa8..08c8510 100644
--- a/chrome/common/appcache/appcache_frontend_proxy.cc
+++ b/chrome/common/appcache/appcache_frontend_proxy.cc
@@ -20,4 +20,3 @@ void AppCacheFrontendProxy::OnEventRaised(const std::vector<int>& host_ids,
appcache::EventID event_id) {
sender_->Send(new AppCacheMsg_EventRaised(host_ids, event_id));
}
-
diff --git a/chrome/common/appcache/chrome_appcache_service.h b/chrome/common/appcache/chrome_appcache_service.h
new file mode 100644
index 0000000..63736da
--- /dev/null
+++ b/chrome/common/appcache/chrome_appcache_service.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2009 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 CHROME_COMMON_APPCACHE_CHROME_APPCACHE_SERVICE_H_
+#define CHROME_COMMON_APPCACHE_CHROME_APPCACHE_SERVICE_H_
+
+#include "base/file_path.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/task.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/chrome_constants.h"
+#include "webkit/appcache/appcache_service.h"
+
+// An AppCacheService subclass used by the chrome. There is an instance
+// associated with each Profile. This derivation adds refcounting semantics
+// since a profile has multiple URLRequestContexts which refer to the same
+// object, and those URLRequestContexts are refcounted independently of the
+// owning profile.
+//
+// All methods, including the dtor, are expected to be called on the IO thread
+// except for the ctor and the init method which are expected to be called on
+// the UI thread.
+class ChromeAppCacheService
+ : public base::RefCountedThreadSafe<ChromeAppCacheService>,
+ public appcache::AppCacheService {
+ public:
+
+ explicit ChromeAppCacheService()
+ : was_initialized_with_io_thread_(false) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ }
+
+ void InitializeOnUIThread(const FilePath& data_directory,
+ bool is_incognito) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ // Some test cases run without an IO thread.
+ MessageLoop* io_thread = ChromeThread::GetMessageLoop(ChromeThread::IO);
+ if (io_thread) {
+ was_initialized_with_io_thread_ = true;
+ io_thread->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &ChromeAppCacheService::InitializeOnIOThread,
+ data_directory, is_incognito));
+ }
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<ChromeAppCacheService>;
+
+ virtual ~ChromeAppCacheService() {
+ DCHECK(!was_initialized_with_io_thread_ ||
+ ChromeThread::CurrentlyOn(ChromeThread::IO));
+ }
+
+ void InitializeOnIOThread(const FilePath& data_directory,
+ bool is_incognito) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ Initialize(is_incognito ? FilePath()
+ : data_directory.Append(chrome::kAppCacheDirname));
+ }
+
+ bool was_initialized_with_io_thread_;
+};
+
+#endif // CHROME_COMMON_APPCACHE_CHROME_APPCACHE_SERVICE_H_
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index 6e578c5..d892a8f 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -64,6 +64,7 @@ const FilePath::CharType kCacheDirname[] = FPL("Cache");
const FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache");
const FilePath::CharType kOffTheRecordMediaCacheDirname[] =
FPL("Incognito Media Cache");
+const FilePath::CharType kAppCacheDirname[] = FPL("Application Cache");
const wchar_t kChromePluginDataDirname[] = L"Plugin Data";
const wchar_t kThemeImagesDirname[] = L"Cached Theme Images";
const FilePath::CharType kCookieFilename[] = FPL("Cookies");
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index 9e76426..0f5ec52 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -30,6 +30,7 @@ extern const FilePath::CharType kArchivedHistoryFilename[];
extern const FilePath::CharType kCacheDirname[];
extern const FilePath::CharType kMediaCacheDirname[];
extern const FilePath::CharType kOffTheRecordMediaCacheDirname[];
+extern const FilePath::CharType kAppCacheDirname[];
extern const wchar_t kChromePluginDataDirname[];
extern const wchar_t kThemeImagesDirname[];
extern const FilePath::CharType kCookieFilename[];
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index ff89b61..d786017 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -75,6 +75,9 @@ class TestingProfile : public Profile {
virtual Profile* GetOriginalProfile() {
return this;
}
+ virtual ChromeAppCacheService* GetAppCacheService() {
+ return NULL;
+ }
virtual VisitedLinkMaster* GetVisitedLinkMaster() {
return NULL;
}
@@ -130,11 +133,9 @@ class TestingProfile : public Profile {
virtual TemplateURLFetcher* GetTemplateURLFetcher() {
return NULL;
}
-
virtual ThumbnailStore* GetThumbnailStore() {
return NULL;
}
-
virtual DownloadManager* GetDownloadManager() {
return NULL;
}
diff --git a/webkit/appcache/appcache_backend_impl.cc b/webkit/appcache/appcache_backend_impl.cc
index 1c0cfc7..82b40ee 100644
--- a/webkit/appcache/appcache_backend_impl.cc
+++ b/webkit/appcache/appcache_backend_impl.cc
@@ -4,29 +4,34 @@
#include "webkit/appcache/appcache_backend_impl.h"
-#include "base/logging.h"
+#include "webkit/appcache/appcache_host.h"
+#include "webkit/appcache/appcache_service.h"
#include "webkit/appcache/web_application_cache_host_impl.h"
namespace appcache {
AppCacheBackendImpl::~AppCacheBackendImpl() {
- // TODO(michaeln): if (service_) service_->UnregisterFrontend(frontend_);
+ if (service_)
+ service_->UnregisterBackend(this);
}
void AppCacheBackendImpl::Initialize(AppCacheService* service,
- AppCacheFrontend* frontend) {
- DCHECK(!service_ && !frontend_ && frontend); // DCHECK(service)
+ AppCacheFrontend* frontend,
+ int process_id) {
+ DCHECK(!service_ && !frontend_ && frontend && service);
service_ = service;
frontend_ = frontend;
- // TODO(michaeln): service_->RegisterFrontend(frontend_);
+ process_id_ = process_id;
+ service_->RegisterBackend(this);
}
-void AppCacheBackendImpl::RegisterHost(int host_id) {
- // TODO(michaeln): plumb to service
+void AppCacheBackendImpl::RegisterHost(int id) {
+ DCHECK(hosts_.find(id) == hosts_.end());
+ hosts_.insert(HostMap::value_type(id, AppCacheHost(id, frontend_)));
}
-void AppCacheBackendImpl::UnregisterHost(int host_id) {
- // TODO(michaeln): plumb to service
+void AppCacheBackendImpl::UnregisterHost(int id) {
+ hosts_.erase(id);
}
void AppCacheBackendImpl::SelectCache(
@@ -34,7 +39,7 @@ void AppCacheBackendImpl::SelectCache(
const GURL& document_url,
const int64 cache_document_was_loaded_from,
const GURL& manifest_url) {
- // TODO(michaeln): plumb to service
+ // TODO(michaeln): write me
frontend_->OnCacheSelected(host_id, kNoCacheId, UNCACHED);
}
@@ -42,22 +47,25 @@ void AppCacheBackendImpl::MarkAsForeignEntry(
int host_id,
const GURL& document_url,
int64 cache_document_was_loaded_from) {
- // TODO(michaeln): plumb to service
+ // TODO(michaeln): write me
}
-Status AppCacheBackendImpl::GetStatus(int host_id) {
- // TODO(michaeln): plumb to service
- return UNCACHED;
+void AppCacheBackendImpl::GetStatusWithCallback(
+ int host_id, GetStatusCallback* callback, void* callback_param) {
+ // TODO(michaeln): write me
+ callback->Run(UNCACHED, callback_param);
}
-bool AppCacheBackendImpl::StartUpdate(int host_id) {
- // TODO(michaeln): plumb to service
- return false;
+void AppCacheBackendImpl::StartUpdateWithCallback(
+ int host_id, StartUpdateCallback* callback, void* callback_param) {
+ // TODO(michaeln): write me
+ callback->Run(false, callback_param);
}
-bool AppCacheBackendImpl::SwapCache(int host_id) {
- // TODO(michaeln): plumb to service
- return false;
+void AppCacheBackendImpl::SwapCacheWithCallback(
+ int host_id, SwapCacheCallback* callback, void* callback_param) {
+ // TODO(michaeln): write me
+ callback->Run(false, callback_param);
}
} // namespace appcache
diff --git a/webkit/appcache/appcache_backend_impl.h b/webkit/appcache/appcache_backend_impl.h
index 93a7083..abf4247 100644
--- a/webkit/appcache/appcache_backend_impl.h
+++ b/webkit/appcache/appcache_backend_impl.h
@@ -5,20 +5,42 @@
#ifndef WEBKIT_APPCACHE_APPCACHE_BACKEND_IMPL_H_
#define WEBKIT_APPCACHE_APPCACHE_BACKEND_IMPL_H_
+#include <map>
+
+#include "base/logging.h"
+#include "base/task.h"
+#include "webkit/appcache/appcache_host.h"
#include "webkit/appcache/appcache_interfaces.h"
namespace appcache {
class AppCacheService;
+typedef Callback2<Status, void*>::Type GetStatusCallback;
+typedef Callback2<bool, void*>::Type StartUpdateCallback;
+typedef Callback2<bool, void*>::Type SwapCacheCallback;
+
class AppCacheBackendImpl : public AppCacheBackend {
public:
- AppCacheBackendImpl() : service_(NULL), frontend_(NULL) {}
+ AppCacheBackendImpl() : service_(NULL), frontend_(NULL), process_id_(0) {}
~AppCacheBackendImpl();
void Initialize(AppCacheService* service,
- AppCacheFrontend* frontend);
+ AppCacheFrontend* frontend,
+ int process_id);
+
+ int process_id() const { return process_id_; }
+
+ // Returns a pointer to a registered host. The backend retains ownership.
+ AppCacheHost* GetHost(int host_id) {
+ HostMap::iterator it = hosts_.find(host_id);
+ return (it != hosts_.end()) ? &(it->second) : NULL;
+ }
+ typedef std::map<int, AppCacheHost> HostMap;
+ const HostMap& hosts() { return hosts_; }
+
+ // AppCacheBackend methods
virtual void RegisterHost(int host_id);
virtual void UnregisterHost(int host_id);
virtual void SelectCache(int host_id,
@@ -27,13 +49,25 @@ class AppCacheBackendImpl : public AppCacheBackend {
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);
+
+ // We don't use the sync variants in the backend, would block the IO thread.
+ virtual Status GetStatus(int host_id) { NOTREACHED(); return UNCACHED; }
+ virtual bool StartUpdate(int host_id) { NOTREACHED(); return false; }
+ virtual bool SwapCache(int host_id) { NOTREACHED(); return false; }
+
+ // Async variants of the sync methods defined in the backend interface.
+ void GetStatusWithCallback(int host_id, GetStatusCallback* callback,
+ void* callback_param);
+ void StartUpdateWithCallback(int host_id, StartUpdateCallback* callback,
+ void* callback_param);
+ void SwapCacheWithCallback(int host_id, SwapCacheCallback* callback,
+ void* callback_param);
private:
AppCacheService* service_;
AppCacheFrontend* frontend_;
+ int process_id_;
+ HostMap hosts_;
};
} // namespace
diff --git a/webkit/appcache/appcache_host.h b/webkit/appcache/appcache_host.h
index 439e042..bebc22d 100644
--- a/webkit/appcache/appcache_host.h
+++ b/webkit/appcache/appcache_host.h
@@ -24,6 +24,10 @@ class AppCacheHost {
selected_cache_ = cache;
}
+ bool is_selection_pending() {
+ return false; // TODO(michaeln)
+ }
+
private:
// identifies the corresponding appcache host in the child process
int host_id_;
diff --git a/webkit/appcache/appcache_interceptor.cc b/webkit/appcache/appcache_interceptor.cc
new file mode 100644
index 0000000..a66fea8
--- /dev/null
+++ b/webkit/appcache/appcache_interceptor.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2009 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_interceptor.h"
+
+#include "webkit/appcache/appcache_backend_impl.h"
+#include "webkit/appcache/appcache_host.h"
+#include "webkit/appcache/appcache_interfaces.h"
+#include "webkit/appcache/appcache_service.h"
+
+namespace appcache {
+
+// Extra info we associate with requests for use at MaybeIntercept time. This
+// info is deleted when the URLRequest is deleted which occurs after the
+// request is complete and all data has been read.
+struct AppCacheInterceptor::ExtraInfo : public URLRequest::UserData {
+ // Inputs, extra request info
+ AppCacheService* service;
+ int process_id;
+ int host_id;
+ ResourceType::Type resource_type;
+
+ // Outputs, extra response info
+ int64 cache_id;
+ GURL manifest_url;
+
+ // The host associated with the request
+ // TODO(michaeln): Be careful with this data member, its not clear
+ // if a URLRequest can outlive the associated host. As we get further
+ // along, we'll need to notify reqeust waiting on cache selection to
+ // allow them to continue upon completion of selection. But we also need
+ // to handle navigating away from the page away prior to selection being
+ // complete.
+ AppCacheHost* host_;
+
+ ExtraInfo(AppCacheService* service, int process_id, int host_id,
+ ResourceType::Type resource_type, AppCacheHost* host)
+ : service(service), process_id(process_id), host_id(host_id),
+ resource_type(resource_type), cache_id(kNoCacheId), host_(host) {
+ }
+
+ static void SetInfo(URLRequest* request, ExtraInfo* info) {
+ request->SetUserData(instance(), info); // request takes ownership
+ }
+
+ static ExtraInfo* GetInfo(URLRequest* request) {
+ return static_cast<ExtraInfo*>(request->GetUserData(instance()));
+ }
+};
+
+static bool IsMainRequest(ResourceType::Type type) {
+ // TODO(michaeln): SHARED_WORKER type?
+ return ResourceType::IsFrame(type);
+}
+
+void AppCacheInterceptor::SetExtraRequestInfo(
+ URLRequest* request, AppCacheService* service, int process_id,
+ int host_id, ResourceType::Type resource_type) {
+ if (service && (host_id != kNoHostId)) {
+ AppCacheHost* host = service->GetBackend(process_id)->GetHost(host_id);
+ DCHECK(host);
+ if (IsMainRequest(resource_type) || host->selected_cache() ||
+ host->is_selection_pending()) {
+ ExtraInfo* info = new ExtraInfo(service, process_id,
+ host_id, resource_type, host);
+ ExtraInfo::SetInfo(request, info);
+ }
+ }
+}
+
+void AppCacheInterceptor::GetExtraResponseInfo(URLRequest* request,
+ int64* cache_id,
+ GURL* manifest_url) {
+ ExtraInfo* info = ExtraInfo::GetInfo(request);
+ if (info) {
+ // TODO(michaeln): If this is a main request and it was retrieved from
+ // an appcache, ensure that appcache survives the frame navigation. The
+ // AppCacheHost should hold reference to that cache to prevent it from
+ // being dropped from the in-memory collection of AppCaches. When cache
+ // selection occurs, that extra reference should be dropped.
+ *cache_id = info->cache_id;
+ *manifest_url = info->manifest_url;
+ } else {
+ DCHECK(*cache_id == kNoCacheId);
+ DCHECK(manifest_url->is_empty());
+ }
+}
+
+AppCacheInterceptor::AppCacheInterceptor() {
+ URLRequest::RegisterRequestInterceptor(this);
+}
+
+AppCacheInterceptor::~AppCacheInterceptor() {
+ URLRequest::UnregisterRequestInterceptor(this);
+}
+
+URLRequestJob* AppCacheInterceptor::MaybeIntercept(URLRequest* request) {
+ ExtraInfo* info = ExtraInfo::GetInfo(request);
+ if (!info)
+ return NULL;
+ // TODO(michaeln): write me
+ return NULL;
+}
+
+URLRequestJob* AppCacheInterceptor::MaybeInterceptRedirect(
+ URLRequest* request,
+ const GURL& location) {
+ ExtraInfo* info = ExtraInfo::GetInfo(request);
+ if (!info)
+ return NULL;
+ // TODO(michaeln): write me
+ return NULL;
+}
+
+URLRequestJob* AppCacheInterceptor::MaybeInterceptResponse(
+ URLRequest* request) {
+ ExtraInfo* info = ExtraInfo::GetInfo(request);
+ if (!info)
+ return NULL;
+ // TODO(michaeln): write me
+ return NULL;
+}
+
+} // namespace appcache
diff --git a/webkit/appcache/appcache_interceptor.h b/webkit/appcache/appcache_interceptor.h
new file mode 100644
index 0000000..51b9a89
--- /dev/null
+++ b/webkit/appcache/appcache_interceptor.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2009 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_INTERCEPTOR_H_
+#define WEBKIT_APPCACHE_APPCACHE_INTERCEPTOR_H_
+
+#include "base/singleton.h"
+#include "googleurl/src/gurl.h"
+#include "net/url_request/url_request.h"
+#include "webkit/glue/resource_type.h"
+
+namespace appcache {
+
+class AppCacheService;
+
+// An interceptor to hijack requests and potentially service them out of
+// the appcache.
+class AppCacheInterceptor : public URLRequest::Interceptor {
+ public:
+ // Registers a singleton instance with the net library.
+ // Should be called early in the IO thread prior to initiating requests.
+ static void EnsureRegistered() {
+ CHECK(instance());
+ }
+
+ // Must be called to make a request eligible for retrieval from an appcache.
+ static void SetExtraRequestInfo(URLRequest* request,
+ AppCacheService* service,
+ int process_id,
+ int host_id,
+ ResourceType::Type resource_type);
+
+ // May be called after response headers are complete to retrieve extra
+ // info about the response.
+ static void GetExtraResponseInfo(URLRequest* request,
+ int64* cache_id,
+ GURL* manifest_url);
+
+ protected:
+ // URLRequest::Interceptor overrides
+ virtual URLRequestJob* MaybeIntercept(URLRequest* request);
+ virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request);
+ virtual URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
+ const GURL& location);
+
+ private:
+ friend struct DefaultSingletonTraits<AppCacheInterceptor>;
+ static AppCacheInterceptor* instance() {
+ return Singleton<AppCacheInterceptor>::get();
+ }
+ struct ExtraInfo;
+ AppCacheInterceptor();
+ virtual ~AppCacheInterceptor();
+ DISALLOW_COPY_AND_ASSIGN(AppCacheInterceptor);
+};
+
+} // namespace appcache
+
+#endif // WEBKIT_APPCACHE_APPCACHE_INTERCEPTOR_H_
diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc
index 0d3579b..0fd5356 100644
--- a/webkit/appcache/appcache_service.cc
+++ b/webkit/appcache/appcache_service.cc
@@ -17,14 +17,21 @@ AppCacheService::~AppCacheService() {
DCHECK(groups_.empty());
}
-void AppCacheService::RegisterBackendImpl(
+void AppCacheService::Initialize(const FilePath& cache_directory) {
+ // An empty cache directory indicates chrome incognito.
+ cache_directory_ = cache_directory;
+}
+
+void AppCacheService::RegisterBackend(
AppCacheBackendImpl* backend_impl) {
- backends_.insert(backend_impl);
+ DCHECK(backends_.find(backend_impl->process_id()) == backends_.end());
+ backends_.insert(
+ BackendMap::value_type(backend_impl->process_id(), backend_impl));
}
-void AppCacheService::UnregisterBackendImpl(
+void AppCacheService::UnregisterBackend(
AppCacheBackendImpl* backend_impl) {
- backends_.erase(backend_impl);
+ backends_.erase(backend_impl->process_id());
}
void AppCacheService::AddCache(AppCache* cache) {
diff --git a/webkit/appcache/appcache_service.h b/webkit/appcache/appcache_service.h
index 3eaa43d..bc8bee8 100644
--- a/webkit/appcache/appcache_service.h
+++ b/webkit/appcache/appcache_service.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/hash_tables.h"
+#include "base/file_path.h"
#include "googleurl/src/gurl.h"
namespace appcache {
@@ -24,17 +25,34 @@ class AppCacheService {
public:
virtual ~AppCacheService();
+ void Initialize(const FilePath& cache_directory);
+
// TODO(jennb): API to set service settings, like file paths for storage
// track which processes are using this appcache service
- void RegisterBackendImpl(AppCacheBackendImpl* backend_impl);
- void UnregisterBackendImpl(AppCacheBackendImpl* backend_impl);
+ void RegisterBackend(AppCacheBackendImpl* backend_impl);
+ void UnregisterBackend(AppCacheBackendImpl* backend_impl);
void AddCache(AppCache* cache);
void RemoveCache(AppCache* cache);
void AddGroup(AppCacheGroup* group);
void RemoveGroup(AppCacheGroup* group);
+ AppCacheBackendImpl* GetBackend(int id) {
+ BackendMap::iterator it = backends_.find(id);
+ return (it != backends_.end()) ? it->second : NULL;
+ }
+
+ AppCache* GetCache(int64 id) {
+ CacheMap::iterator it = caches_.find(id);
+ return (it != caches_.end()) ? it->second : NULL;
+ }
+
+ AppCacheGroup* GetGroup(const GURL& manifest_url) {
+ GroupMap::iterator it = groups_.find(manifest_url);
+ return (it != groups_.end()) ? it->second : NULL;
+ }
+
private:
// In-memory representation of stored appcache data. Represents a subset
// of the appcache database currently in use.
@@ -44,9 +62,10 @@ class AppCacheService {
GroupMap groups_;
// Track current processes. One 'backend' per child process.
- typedef std::set<AppCacheBackendImpl*> BackendSet;
- BackendSet backends_;
+ typedef std::map<int, AppCacheBackendImpl*> BackendMap;
+ BackendMap backends_;
+ FilePath cache_directory_;
// TODO(jennb): info about appcache storage
// AppCacheDatabase db_;
// DiskCache response_storage_;
diff --git a/webkit/appcache/web_application_cache_host_impl.cc b/webkit/appcache/web_application_cache_host_impl.cc
index 02a698f..d5d50fb 100644
--- a/webkit/appcache/web_application_cache_host_impl.cc
+++ b/webkit/appcache/web_application_cache_host_impl.cc
@@ -43,6 +43,7 @@ WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() {
backend_->UnregisterHost(host_id_);
+ all_hosts.Remove(host_id_);
}
void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id,
diff --git a/webkit/tools/test_shell/simple_appcache_system.cc b/webkit/tools/test_shell/simple_appcache_system.cc
new file mode 100644
index 0000000..5ab7fe2
--- /dev/null
+++ b/webkit/tools/test_shell/simple_appcache_system.cc
@@ -0,0 +1,323 @@
+// Copyright (c) 2009 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/tools/test_shell/simple_appcache_system.h"
+
+#include "base/lock.h"
+#include "base/task.h"
+#include "base/waitable_event.h"
+#include "webkit/appcache/appcache_interceptor.h"
+#include "webkit/appcache/web_application_cache_host_impl.h"
+#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
+
+using WebKit::WebApplicationCacheHost;
+using WebKit::WebApplicationCacheHostClient;
+using appcache::WebApplicationCacheHostImpl;
+using appcache::AppCacheBackendImpl;
+using appcache::AppCacheInterceptor;
+
+
+// SimpleFrontendProxy --------------------------------------------------------
+// Proxies method calls from the backend IO thread to the frontend UI thread.
+
+class SimpleFrontendProxy
+ : public base::RefCountedThreadSafe<SimpleFrontendProxy>,
+ public appcache::AppCacheFrontend {
+ public:
+ explicit SimpleFrontendProxy(SimpleAppCacheSystem* appcache_system)
+ : system_(appcache_system) {
+ }
+
+ void clear_appcache_system() { system_ = NULL; }
+
+ virtual void OnCacheSelected(int host_id, int64 cache_id ,
+ appcache::Status status) {
+ if (!system_)
+ return;
+ if (system_->is_io_thread())
+ system_->ui_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleFrontendProxy::OnCacheSelected,
+ host_id, cache_id, status));
+ else if (system_->is_ui_thread())
+ system_->frontend_impl_.OnCacheSelected(host_id, cache_id, status);
+ else
+ NOTREACHED();
+ }
+
+ virtual void OnStatusChanged(const std::vector<int>& host_ids,
+ appcache::Status status) {
+ if (!system_)
+ return;
+ if (system_->is_io_thread())
+ system_->ui_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleFrontendProxy::OnStatusChanged, host_ids, status));
+ else if (system_->is_ui_thread())
+ system_->frontend_impl_.OnStatusChanged(host_ids, status);
+ else
+ NOTREACHED();
+ }
+
+ virtual void OnEventRaised(const std::vector<int>& host_ids,
+ appcache::EventID event_id) {
+ if (!system_)
+ return;
+ if (system_->is_io_thread())
+ system_->ui_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleFrontendProxy::OnEventRaised, host_ids, event_id));
+ else if (system_->is_ui_thread())
+ system_->frontend_impl_.OnEventRaised(host_ids, event_id);
+ else
+ NOTREACHED();
+ }
+
+ private:
+ SimpleAppCacheSystem* system_;
+};
+
+
+// SimpleBackendProxy --------------------------------------------------------
+// Proxies method calls from the frontend UI thread to the backend IO thread.
+
+class SimpleBackendProxy
+ : public base::RefCountedThreadSafe<SimpleBackendProxy>,
+ public appcache::AppCacheBackend {
+ public:
+ explicit SimpleBackendProxy(SimpleAppCacheSystem* appcache_system)
+ : system_(appcache_system), event_(true, false) {
+ get_status_callback_.reset(
+ NewCallback(this, &SimpleBackendProxy::GetStatusCallback));
+ start_update_callback_.reset(
+ NewCallback(this, &SimpleBackendProxy::StartUpdateCallback));
+ swap_cache_callback_.reset(
+ NewCallback(this, &SimpleBackendProxy::SwapCacheCallback));
+ }
+
+ virtual void RegisterHost(int host_id) {
+ if (system_->is_ui_thread()) {
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::RegisterHost, host_id));
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->RegisterHost(host_id);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ virtual void UnregisterHost(int host_id) {
+ if (system_->is_ui_thread()) {
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::UnregisterHost, host_id));
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->UnregisterHost(host_id);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ virtual void SelectCache(int host_id,
+ const GURL& document_url,
+ const int64 cache_document_was_loaded_from,
+ const GURL& manifest_url) {
+ if (system_->is_ui_thread()) {
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::SelectCache, host_id, document_url,
+ cache_document_was_loaded_from, manifest_url));
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->SelectCache(host_id, document_url,
+ cache_document_was_loaded_from,
+ manifest_url);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ virtual void MarkAsForeignEntry(int host_id, const GURL& document_url,
+ int64 cache_document_was_loaded_from) {
+ if (system_->is_ui_thread()) {
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::MarkAsForeignEntry, host_id, document_url,
+ cache_document_was_loaded_from));
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->MarkAsForeignEntry(
+ host_id, document_url,
+ cache_document_was_loaded_from);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ virtual appcache::Status GetStatus(int host_id) {
+ if (system_->is_ui_thread()) {
+ status_result_ = appcache::UNCACHED;
+ event_.Reset();
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::GetStatus, host_id));
+ event_.Wait();
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->GetStatusWithCallback(
+ host_id, get_status_callback_.get(), NULL);
+ } else {
+ NOTREACHED();
+ }
+ return status_result_;
+ }
+
+ virtual bool StartUpdate(int host_id) {
+ if (system_->is_ui_thread()) {
+ bool_result_ = false;
+ event_.Reset();
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::StartUpdate, host_id));
+ event_.Wait();
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->StartUpdateWithCallback(
+ host_id, start_update_callback_.get(), NULL);
+ } else {
+ NOTREACHED();
+ }
+ return bool_result_;
+ }
+
+ virtual bool SwapCache(int host_id) {
+ if (system_->is_ui_thread()) {
+ bool_result_ = false;
+ event_.Reset();
+ system_->io_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SimpleBackendProxy::SwapCache, host_id));
+ event_.Wait();
+ } else if (system_->is_io_thread()) {
+ system_->backend_impl_->SwapCacheWithCallback(
+ host_id, swap_cache_callback_.get(), NULL);
+ } else {
+ NOTREACHED();
+ }
+ return bool_result_;
+ }
+
+ void GetStatusCallback(appcache::Status status, void* param) {
+ status_result_ = status;
+ event_.Signal();
+ }
+
+ void StartUpdateCallback(bool result, void* param) {
+ bool_result_ = result;
+ event_.Signal();
+ }
+
+ void SwapCacheCallback(bool result, void* param) {
+ bool_result_ = result;
+ event_.Signal();
+ }
+
+ void SignalEvent() {
+ event_.Signal();
+ }
+
+ private:
+ SimpleAppCacheSystem* system_;
+ base::WaitableEvent event_;
+ bool bool_result_;
+ appcache::Status status_result_;
+ scoped_ptr<appcache::GetStatusCallback> get_status_callback_;
+ scoped_ptr<appcache::StartUpdateCallback> start_update_callback_;
+ scoped_ptr<appcache::SwapCacheCallback> swap_cache_callback_;
+};
+
+
+// SimpleAppCacheSystem --------------------------------------------------------
+
+// This class only works for a single process browser.
+static const int kSingleProcessId = 1;
+
+// A not so thread safe singleton, but should work for test_shell.
+SimpleAppCacheSystem* SimpleAppCacheSystem::instance_ = NULL;
+
+SimpleAppCacheSystem::SimpleAppCacheSystem()
+ : io_message_loop_(NULL), ui_message_loop_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ backend_proxy_(new SimpleBackendProxy(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ frontend_proxy_(new SimpleFrontendProxy(this))),
+ backend_impl_(NULL), service_(NULL) {
+ DCHECK(!instance_);
+ instance_ = this;
+}
+
+SimpleAppCacheSystem::~SimpleAppCacheSystem() {
+ DCHECK(!io_message_loop_ && !backend_impl_ && !service_);
+ frontend_proxy_->clear_appcache_system(); // in case a task is in transit
+ instance_ = NULL;
+}
+
+void SimpleAppCacheSystem::InitOnUIThread(
+ const FilePath& cache_directory) {
+ DCHECK(!ui_message_loop_);
+ DCHECK(!cache_directory.empty());
+ ui_message_loop_ = MessageLoop::current();
+ cache_directory_ = cache_directory;
+}
+
+void SimpleAppCacheSystem::InitOnIOThread() {
+ if (!is_initailized_on_ui_thread())
+ return;
+
+ DCHECK(!io_message_loop_);
+ io_message_loop_ = MessageLoop::current();
+ io_message_loop_->AddDestructionObserver(this);
+
+ // Recreate and initialize per each IO thread.
+ service_ = new appcache::AppCacheService();
+ backend_impl_ = new appcache::AppCacheBackendImpl();
+ service_->Initialize(cache_directory_);
+ backend_impl_->Initialize(service_, frontend_proxy_.get(), kSingleProcessId);
+
+ AppCacheInterceptor::EnsureRegistered();
+}
+
+WebApplicationCacheHost* SimpleAppCacheSystem::CreateCacheHostForWebKit(
+ WebApplicationCacheHostClient* client) {
+ if (!is_initailized_on_ui_thread())
+ return NULL;
+
+ DCHECK(is_ui_thread());
+
+ // The IO thread needs to be running for this system to work.
+ SimpleResourceLoaderBridge::EnsureIOThread();
+
+ if (!is_initialized())
+ return NULL;
+ return new WebApplicationCacheHostImpl(client, backend_proxy_.get());
+}
+
+void SimpleAppCacheSystem::SetExtraRequestBits(
+ URLRequest* request, int host_id, ResourceType::Type resource_type) {
+ if (is_initialized()) {
+ DCHECK(is_io_thread());
+ AppCacheInterceptor::SetExtraRequestInfo(
+ request, service_, kSingleProcessId, host_id, resource_type);
+ }
+}
+
+void SimpleAppCacheSystem::GetExtraResponseBits(
+ URLRequest* request, int64* cache_id, GURL* manifest_url) {
+ if (is_initialized()) {
+ DCHECK(is_io_thread());
+ AppCacheInterceptor::GetExtraResponseInfo(
+ request, cache_id, manifest_url);
+ }
+}
+
+void SimpleAppCacheSystem::WillDestroyCurrentMessageLoop() {
+ DCHECK(is_io_thread());
+ DCHECK(backend_impl_->hosts().empty());
+
+ io_message_loop_ = NULL;
+ delete backend_impl_;
+ delete service_;
+ backend_impl_ = NULL;
+ service_ = NULL;
+
+ // Just in case the main thread is waiting on it.
+ backend_proxy_->SignalEvent();
+}
diff --git a/webkit/tools/test_shell/simple_appcache_system.h b/webkit/tools/test_shell/simple_appcache_system.h
index 6f53524..184842f 100644
--- a/webkit/tools/test_shell/simple_appcache_system.h
+++ b/webkit/tools/test_shell/simple_appcache_system.h
@@ -5,21 +5,117 @@
#ifndef WEBKIT_TOOLS_TEST_SHELL_SIMPLE_APPCACHE_SYSTEM_H_
#define WEBKIT_TOOLS_TEST_SHELL_SIMPLE_APPCACHE_SYSTEM_H_
+#include "base/file_path.h"
+#include "base/message_loop.h"
#include "webkit/appcache/appcache_backend_impl.h"
#include "webkit/appcache/appcache_frontend_impl.h"
+#include "webkit/appcache/appcache_service.h"
+#include "webkit/glue/resource_type.h"
-class SimpleAppCacheSystem {
+namespace WebKit {
+class WebApplicationCacheHost;
+class WebApplicationCacheHostClient;
+}
+class SimpleBackendProxy;
+class SimpleFrontendProxy;
+class URLRequest;
+
+// A class that composes the constituent parts of an appcache system
+// together for use in a single process with two relavant threads,
+// a UI thread on which webkit runs and an IO thread on which URLRequests
+// are handled. This class conspires with SimpleResourceLoaderBridge to
+// retrieve resources from the appcache.
+class SimpleAppCacheSystem : public MessageLoop::DestructionObserver {
public:
- void Initialize() {
- backend_impl_.Initialize(NULL, &frontend_impl_);
+ // Should be instanced somewhere in main(). If not instanced, the public
+ // static methods are all safe no-ops.
+ SimpleAppCacheSystem();
+ virtual ~SimpleAppCacheSystem();
+
+ // One-time main UI thread initialization.
+ static void InitializeOnUIThread(const FilePath& cache_directory) {
+ if (instance_)
+ instance_->InitOnUIThread(cache_directory);
}
- appcache::AppCacheBackend* backend() { return &backend_impl_; }
- appcache::AppCacheFrontend* frontend() { return &frontend_impl_; }
+ // Called by SimpleResourceLoaderBridge's IOThread class.
+ // Per IO thread initialization. Only one IO thread can exist
+ // at a time, but after IO thread termination a new one can be
+ // started on which this method should be called. The instance
+ // is assumed to outlive the IO thread.
+ static void InitializeOnIOThread() {
+ if (instance_)
+ instance_->InitOnIOThread();
+ }
+
+ // Called by TestShellWebKitInit to manufacture a 'host' for webcore.
+ static WebKit::WebApplicationCacheHost* CreateApplicationCacheHost(
+ WebKit::WebApplicationCacheHostClient* client) {
+ return instance_ ? instance_->CreateCacheHostForWebKit(client) : NULL;
+ }
+
+ // Called by SimpleResourceLoaderBridge to hook into resource loads.
+ static void SetExtraRequestInfo(URLRequest* request,
+ int host_id,
+ ResourceType::Type resource_type) {
+ if (instance_)
+ instance_->SetExtraRequestBits(request, host_id, resource_type);
+ }
+
+ // Called by SimpleResourceLoaderBridge extract extra response bits.
+ static void GetExtraResponseInfo(URLRequest* request,
+ int64* cache_id,
+ GURL* manifest_url) {
+ if (instance_)
+ instance_->GetExtraResponseBits(request, cache_id, manifest_url);
+ }
private:
- appcache::AppCacheBackendImpl backend_impl_;
+ friend class SimpleBackendProxy;
+ friend class SimpleFrontendProxy;
+
+ // A low-tech singleton.
+ static SimpleAppCacheSystem* instance_;
+
+ // Instance methods called by our static public methods
+ void InitOnUIThread(const FilePath& cache_directory);
+ void InitOnIOThread();
+ WebKit::WebApplicationCacheHost* CreateCacheHostForWebKit(
+ WebKit::WebApplicationCacheHostClient* client);
+ void SetExtraRequestBits(URLRequest* request,
+ int host_id,
+ ResourceType::Type resource_type);
+ void GetExtraResponseBits(URLRequest* request,
+ int64* cache_id,
+ GURL* manifest_url);
+
+ // Helpers
+ MessageLoop* io_message_loop() { return io_message_loop_; }
+ MessageLoop* ui_message_loop() { return ui_message_loop_; }
+ bool is_io_thread() { return MessageLoop::current() == io_message_loop_; }
+ bool is_ui_thread() { return MessageLoop::current() == ui_message_loop_; }
+ bool is_initialized() {
+ return io_message_loop_ && is_initailized_on_ui_thread();
+ }
+ bool is_initailized_on_ui_thread() {
+ return ui_message_loop_ && !cache_directory_.empty();
+ }
+
+ // IOThread DestructionObserver
+ virtual void WillDestroyCurrentMessageLoop();
+
+ FilePath cache_directory_;
+ MessageLoop* io_message_loop_;
+ MessageLoop* ui_message_loop_;
+ scoped_refptr<SimpleBackendProxy> backend_proxy_;
+ scoped_refptr<SimpleFrontendProxy> frontend_proxy_;
appcache::AppCacheFrontendImpl frontend_impl_;
+
+ // Created and used only on the IO thread, these do
+ // not survive IO thread termination. If a new IO thread
+ // is started new instances will be created.
+ appcache::AppCacheBackendImpl* backend_impl_;
+ appcache::AppCacheService* service_;
};
#endif // WEBKIT_TOOLS_TEST_SHELL_SIMPLE_APPCACHE_SYSTEM_H_
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index c27f061..46126a0 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -48,6 +48,7 @@
#include "net/url_request/url_request.h"
#include "webkit/appcache/appcache_interfaces.h"
#include "webkit/glue/resource_loader_bridge.h"
+#include "webkit/tools/test_shell/simple_appcache_system.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
using webkit_glue::ResourceLoaderBridge;
@@ -71,6 +72,10 @@ class IOThread : public base::Thread {
Stop();
}
+ virtual void Init() {
+ SimpleAppCacheSystem::InitializeOnIOThread();
+ }
+
virtual void CleanUp() {
if (request_context) {
request_context->Release();
@@ -79,19 +84,6 @@ class IOThread : public base::Thread {
}
};
-bool EnsureIOThread() {
- if (io_thread)
- return true;
-
- if (!request_context)
- SimpleResourceLoaderBridge::Init(NULL);
-
- io_thread = new IOThread();
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
- return io_thread->StartWithOptions(options);
-}
-
//-----------------------------------------------------------------------------
struct RequestParams {
@@ -101,6 +93,7 @@ struct RequestParams {
GURL referrer;
std::string headers;
int load_flags;
+ ResourceType::Type request_type;
int appcache_host_id;
scoped_refptr<net::UploadData> upload;
};
@@ -214,6 +207,9 @@ class RequestProxy : public URLRequest::Delegate,
request_->set_load_flags(params->load_flags);
request_->set_upload(params->upload.get());
request_->set_context(request_context);
+ SimpleAppCacheSystem::SetExtraRequestInfo(
+ request_.get(), params->appcache_host_id, params->request_type);
+
request_->Start();
if (request_->has_upload() &&
@@ -376,11 +372,13 @@ class RequestProxy : public URLRequest::Delegate,
info->request_time = request->request_time();
info->response_time = request->response_time();
info->headers = request->response_headers();
- info->appcache_id = appcache::kNoCacheId;
- // TODO(michaeln): info->appcache_manifest_url = GURL();
request->GetMimeType(&info->mime_type);
request->GetCharset(&info->charset);
info->content_length = request->GetExpectedContentSize();
+ SimpleAppCacheSystem::GetExtraResponseInfo(
+ request,
+ &info->appcache_id,
+ &info->appcache_manifest_url);
}
scoped_ptr<URLRequest> request_;
@@ -469,6 +467,7 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
const GURL& referrer,
const std::string& headers,
int load_flags,
+ ResourceType::Type request_type,
int appcache_host_id)
: params_(new RequestParams),
proxy_(NULL) {
@@ -478,6 +477,7 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
params_->referrer = referrer;
params_->headers = headers;
params_->load_flags = load_flags;
+ params_->request_type = request_type;
params_->appcache_host_id = appcache_host_id;
}
@@ -517,7 +517,7 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
virtual bool Start(Peer* peer) {
DCHECK(!proxy_);
- if (!EnsureIOThread())
+ if (!SimpleResourceLoaderBridge::EnsureIOThread())
return false;
proxy_ = new RequestProxy();
@@ -540,7 +540,7 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
virtual void SyncLoad(SyncLoadResponse* response) {
DCHECK(!proxy_);
- if (!EnsureIOThread())
+ if (!SimpleResourceLoaderBridge::EnsureIOThread())
return;
// this may change as the result of a redirect
@@ -616,7 +616,7 @@ ResourceLoaderBridge* ResourceLoaderBridge::Create(
int routing_id) {
return new ResourceLoaderBridgeImpl(method, url, first_party_for_cookies,
referrer, headers, load_flags,
- appcache_host_id);
+ request_type, appcache_host_id);
}
// Issue the proxy resolve request on the io thread, and wait
@@ -696,3 +696,16 @@ std::string SimpleResourceLoaderBridge::GetCookies(
return getter->GetResult();
}
+
+bool SimpleResourceLoaderBridge::EnsureIOThread() {
+ if (io_thread)
+ return true;
+
+ if (!request_context)
+ SimpleResourceLoaderBridge::Init(NULL);
+
+ io_thread = new IOThread();
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ return io_thread->StartWithOptions(options);
+}
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.h b/webkit/tools/test_shell/simple_resource_loader_bridge.h
index 24df90c..460071b 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.h
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.h
@@ -33,6 +33,7 @@ class SimpleResourceLoaderBridge {
const std::string& cookie);
static std::string GetCookies(const GURL& url,
const GURL& first_party_for_cookies);
+ static bool EnsureIOThread();
};
#endif // WEBKIT_TOOLS_TEST_SHELL_SIMPLE_RESOURCE_LOADER_BRIDGE_H__
diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp
index 73249ed..94d3863 100644
--- a/webkit/tools/test_shell/test_shell.gyp
+++ b/webkit/tools/test_shell/test_shell.gyp
@@ -63,6 +63,7 @@
'mock_webclipboard_impl.cc',
'mock_webclipboard_impl.h',
'resource.h',
+ 'simple_appcache_system.cc',
'simple_appcache_system.h',
'simple_clipboard_impl.cc',
'simple_resource_loader_bridge.cc',
diff --git a/webkit/tools/test_shell/test_shell_webkit_init.h b/webkit/tools/test_shell/test_shell_webkit_init.h
index 2727d6b..354d949 100644
--- a/webkit/tools/test_shell/test_shell_webkit_init.h
+++ b/webkit/tools/test_shell/test_shell_webkit_init.h
@@ -7,6 +7,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
+#include "base/scoped_temp_dir.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
#include "media/base/media.h"
@@ -42,7 +43,6 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl {
WebKit::enableV8SingleThreadMode();
WebKit::registerExtension(extensions_v8::GearsExtension::Get());
WebKit::registerExtension(extensions_v8::IntervalExtension::Get());
- appcache_system_.Initialize();
// Load libraries for media and enable the media player.
FilePath module_path;
@@ -50,6 +50,12 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl {
media::InitializeMediaLibrary(module_path)) {
WebKit::enableMediaPlayer();
}
+
+ // Construct and initialize an appcache system for this scope.
+ // A new empty temp directory is created to house any cached
+ // content during the run. Upon exit that directory is deleted.
+ if (appcache_dir_.CreateUniqueTempDir())
+ SimpleAppCacheSystem::InitializeOnUIThread(appcache_dir_.path());
}
~TestShellWebKitInit() {
@@ -149,14 +155,14 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl {
virtual WebKit::WebApplicationCacheHost* createApplicationCacheHost(
WebKit::WebApplicationCacheHostClient* client) {
- return new appcache::WebApplicationCacheHostImpl(
- client, appcache_system_.backend());
+ return SimpleAppCacheSystem::CreateApplicationCacheHost(client);
}
private:
webkit_glue::SimpleWebMimeRegistryImpl mime_registry_;
MockWebClipboardImpl mock_clipboard_;
webkit_glue::WebClipboardImpl real_clipboard_;
+ ScopedTempDir appcache_dir_;
SimpleAppCacheSystem appcache_system_;
};
diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp
index 0a6fe18..397d56c 100644
--- a/webkit/webkit.gyp
+++ b/webkit/webkit.gyp
@@ -1258,6 +1258,8 @@
'appcache/appcache_group.h',
'appcache/appcache_host.cc',
'appcache/appcache_host.h',
+ 'appcache/appcache_interceptor.cc',
+ 'appcache/appcache_interceptor.h',
'appcache/appcache_interfaces.cc',
'appcache/appcache_interfaces.h',
'appcache/appcache_service.cc',