summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 23:40:02 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 23:40:02 +0000
commitd68a4fc6f448c6ebf407e2817320e7736c4735ee (patch)
treed76e2c91aa67af5a880ec81eddcbf2d12887e865 /webkit
parent63eb6c0bebc31046bbd954ef21dee86dca9d7fe3 (diff)
downloadchromium_src-d68a4fc6f448c6ebf407e2817320e7736c4735ee.zip
chromium_src-d68a4fc6f448c6ebf407e2817320e7736c4735ee.tar.gz
chromium_src-d68a4fc6f448c6ebf407e2817320e7736c4735ee.tar.bz2
Hook up the content settings UI to the appcache.
* Populate the tree view with appcaches * Delete selected appcaches from the tree view * Delete the date range indicated in the browsing data remover TEST=manual BUG=34634 Review URL: http://codereview.chromium.org/660423 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40796 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/appcache/appcache_group.cc17
-rw-r--r--webkit/appcache/appcache_group.h7
-rw-r--r--webkit/appcache/appcache_host.cc14
-rw-r--r--webkit/appcache/appcache_service.cc138
-rw-r--r--webkit/appcache/appcache_service.h64
-rw-r--r--webkit/appcache/appcache_storage.h9
-rw-r--r--webkit/appcache/appcache_storage_impl.cc61
-rw-r--r--webkit/appcache/appcache_storage_impl.h4
-rw-r--r--webkit/appcache/mock_appcache_storage.h1
9 files changed, 303 insertions, 12 deletions
diff --git a/webkit/appcache/appcache_group.cc b/webkit/appcache/appcache_group.cc
index 8063b911..0f9b4af 100644
--- a/webkit/appcache/appcache_group.cc
+++ b/webkit/appcache/appcache_group.cc
@@ -41,6 +41,7 @@ AppCacheGroup::AppCacheGroup(AppCacheService* service,
manifest_url_(manifest_url),
update_status_(IDLE),
is_obsolete_(false),
+ is_being_deleted_(false),
newest_complete_cache_(NULL),
update_job_(NULL),
service_(service),
@@ -137,9 +138,8 @@ void AppCacheGroup::RemoveCache(AppCache* cache) {
void AppCacheGroup::AddNewlyDeletableResponseIds(
std::vector<int64>* response_ids) {
- if (!is_obsolete() && old_caches_.empty()) {
- service_->storage()->DeleteResponses(
- manifest_url_, *response_ids);
+ if (is_being_deleted() || (!is_obsolete() && old_caches_.empty())) {
+ service_->storage()->DeleteResponses(manifest_url_, *response_ids);
response_ids->clear();
return;
}
@@ -156,6 +156,7 @@ void AppCacheGroup::AddNewlyDeletableResponseIds(
void AppCacheGroup::StartUpdateWithNewMasterEntry(
AppCacheHost* host, const GURL& new_master_resource) {
+ DCHECK(!is_obsolete() && !is_being_deleted());
if (is_in_dtor_)
return;
@@ -172,6 +173,14 @@ void AppCacheGroup::StartUpdateWithNewMasterEntry(
}
}
+void AppCacheGroup::CancelUpdate() {
+ if (update_job_) {
+ delete update_job_;
+ DCHECK(!update_job_);
+ DCHECK_EQ(IDLE, update_status_);
+ }
+}
+
void AppCacheGroup::QueueUpdate(AppCacheHost* host,
const GURL& new_master_resource) {
DCHECK(update_job_ && host && !new_master_resource.is_empty());
@@ -208,7 +217,7 @@ void AppCacheGroup::RunQueuedUpdates() {
observers_.AddObserver(host);
}
- if (!is_obsolete())
+ if (!is_obsolete() && !is_being_deleted())
StartUpdateWithNewMasterEntry(host, it->second);
}
}
diff --git a/webkit/appcache/appcache_group.h b/webkit/appcache/appcache_group.h
index 1558b5a8..c1bb1fc 100644
--- a/webkit/appcache/appcache_group.h
+++ b/webkit/appcache/appcache_group.h
@@ -55,6 +55,9 @@ class AppCacheGroup : public base::RefCounted<AppCacheGroup> {
bool is_obsolete() const { return is_obsolete_; }
void set_obsolete(bool value) { is_obsolete_ = value; }
+ bool is_being_deleted() const { return is_being_deleted_; }
+ void set_being_deleted(bool value) { is_being_deleted_ = value; }
+
AppCache* newest_complete_cache() const { return newest_complete_cache_; }
void AddCache(AppCache* complete_cache);
@@ -81,6 +84,9 @@ class AppCacheGroup : public base::RefCounted<AppCacheGroup> {
void StartUpdateWithNewMasterEntry(AppCacheHost* host,
const GURL& new_master_resource);
+ // Cancels an update if one is running.
+ void CancelUpdate();
+
private:
class HostObserver;
@@ -113,6 +119,7 @@ class AppCacheGroup : public base::RefCounted<AppCacheGroup> {
const GURL manifest_url_;
UpdateStatus update_status_;
bool is_obsolete_;
+ bool is_being_deleted_;
std::vector<int64> newly_deletable_response_ids_;
// Old complete app caches.
diff --git a/webkit/appcache/appcache_host.cc b/webkit/appcache/appcache_host.cc
index 9d1bf9c..4fb098f 100644
--- a/webkit/appcache/appcache_host.cc
+++ b/webkit/appcache/appcache_host.cc
@@ -142,7 +142,7 @@ void AppCacheHost::DoPendingStartUpdate() {
bool success = false;
if (associated_cache_ && associated_cache_->owning_group()) {
AppCacheGroup* group = associated_cache_->owning_group();
- if (!group->is_obsolete()) {
+ if (!group->is_obsolete() && !group->is_being_deleted()) {
success = true;
group->StartUpdate();
}
@@ -235,7 +235,7 @@ void AppCacheHost::LoadOrCreateGroup(const GURL& manifest_url) {
}
void AppCacheHost::OnGroupLoaded(AppCacheGroup* group,
- const GURL& manifest_url) {
+ const GURL& manifest_url) {
DCHECK(manifest_url == pending_selected_manifest_url_);
pending_selected_manifest_url_ = GURL();
FinishCacheSelection(NULL, group);
@@ -270,11 +270,12 @@ void AppCacheHost::FinishCacheSelection(
DCHECK(cache->owning_group());
DCHECK(new_master_entry_url_.is_empty());
AssociateCache(cache);
- if (!cache->owning_group()->is_obsolete()) {
- cache->owning_group()->StartUpdateWithHost(this);
- ObserveGroupBeingUpdated(cache->owning_group());
+ AppCacheGroup* owing_group = cache->owning_group();
+ if (!owing_group->is_obsolete() && !owing_group->is_being_deleted()) {
+ owing_group->StartUpdateWithHost(this);
+ ObserveGroupBeingUpdated(owing_group);
}
- } else if (group) {
+ } else if (group && !group->is_being_deleted()) {
// If document was loaded using HTTP GET or equivalent, and, there is a
// manifest URL, and manifest URL has the same origin as document.
// Invoke the application cache update process for manifest URL, with
@@ -287,6 +288,7 @@ void AppCacheHost::FinishCacheSelection(
ObserveGroupBeingUpdated(group);
} else {
// Otherwise, the Document is not associated with any application cache.
+ new_master_entry_url_ = GURL();
AssociateCache(NULL);
}
diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc
index 65cc457..a6bc24a 100644
--- a/webkit/appcache/appcache_service.cc
+++ b/webkit/appcache/appcache_service.cc
@@ -5,17 +5,142 @@
#include "webkit/appcache/appcache_service.h"
#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/stl_util-inl.h"
#include "webkit/appcache/appcache_backend_impl.h"
#include "webkit/appcache/appcache_storage_impl.h"
namespace appcache {
+// AsyncHelper -------
+
+class AppCacheService::AsyncHelper
+ : public AppCacheStorage::Delegate {
+ public:
+ AsyncHelper(
+ AppCacheService* service, net::CompletionCallback* callback)
+ : service_(service), callback_(callback) {
+ service_->pending_helpers_.insert(this);
+ }
+
+ virtual ~AsyncHelper() {
+ if (service_)
+ service_->pending_helpers_.erase(this);
+ }
+
+ virtual void Start() = 0;
+ virtual void Cancel();
+
+ protected:
+ void CallCallback(int rv) {
+ if (callback_) {
+ // Defer to guarentee async completion.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(&DeferredCallCallback, callback_, rv));
+ }
+ callback_ = NULL;
+ }
+
+ static void DeferredCallCallback(net::CompletionCallback* callback, int rv) {
+ callback->Run(rv);
+ }
+
+ AppCacheService* service_;
+ net::CompletionCallback* callback_;
+};
+
+void AppCacheService::AsyncHelper::Cancel() {
+ CallCallback(net::ERR_ABORTED);
+ service_->storage()->CancelDelegateCallbacks(this);
+ service_ = NULL;
+}
+
+// DeleteHelper -------
+
+class AppCacheService::DeleteHelper : public AsyncHelper {
+ public:
+ DeleteHelper(
+ AppCacheService* service, const GURL& manifest_url,
+ net::CompletionCallback* callback)
+ : AsyncHelper(service, callback), manifest_url_(manifest_url) {
+ }
+
+ virtual void Start() {
+ service_->storage()->LoadOrCreateGroup(manifest_url_, this);
+ }
+
+ private:
+ // AppCacheStorage::Delegate methods
+ virtual void OnGroupLoaded(
+ appcache::AppCacheGroup* group, const GURL& manifest_url);
+ virtual void OnGroupMadeObsolete(
+ appcache::AppCacheGroup* group, bool success);
+
+ GURL manifest_url_;
+};
+
+void AppCacheService::DeleteHelper::OnGroupLoaded(
+ appcache::AppCacheGroup* group, const GURL& manifest_url) {
+ if (group) {
+ group->set_being_deleted(true);
+ group->CancelUpdate();
+ service_->storage()->MakeGroupObsolete(group, this);
+ } else {
+ CallCallback(net::ERR_FAILED);
+ delete this;
+ }
+}
+
+void AppCacheService::DeleteHelper::OnGroupMadeObsolete(
+ appcache::AppCacheGroup* group, bool success) {
+ CallCallback(success ? net::OK : net::ERR_FAILED);
+ delete this;
+}
+
+// GetInfoHelper -------
+
+class AppCacheService::GetInfoHelper : AsyncHelper {
+ public:
+ GetInfoHelper(
+ AppCacheService* service, AppCacheInfoCollection* collection,
+ net::CompletionCallback* callback)
+ : AsyncHelper(service, callback), collection_(collection) {
+ }
+
+ virtual void Start() {
+ service_->storage()->GetAllInfo(this);
+ }
+
+ private:
+ // AppCacheStorage::Delegate override
+ virtual void OnAllInfo(AppCacheInfoCollection* collection);
+
+ scoped_refptr<AppCacheInfoCollection> collection_;
+};
+
+void AppCacheService::GetInfoHelper::OnAllInfo(
+ AppCacheInfoCollection* collection) {
+ if (collection)
+ collection->infos_by_origin.swap(collection_->infos_by_origin);
+ CallCallback(collection ? net::OK : net::ERR_FAILED);
+ delete this;
+}
+
+
+// AppCacheService -------
+
AppCacheService::AppCacheService()
: appcache_policy_(NULL), request_context_(NULL) {
}
AppCacheService::~AppCacheService() {
DCHECK(backends_.empty());
+
+ std::for_each(pending_helpers_.begin(),
+ pending_helpers_.end(),
+ std::mem_fun(&AsyncHelper::Cancel));
+ STLDeleteElements(&pending_helpers_);
}
void AppCacheService::Initialize(const FilePath& cache_directory) {
@@ -25,6 +150,19 @@ void AppCacheService::Initialize(const FilePath& cache_directory) {
storage_.reset(storage);
}
+void AppCacheService::GetAllAppCacheInfo(AppCacheInfoCollection* collection,
+ net::CompletionCallback* callback) {
+ DCHECK(collection);
+ GetInfoHelper* helper = new GetInfoHelper(this, collection, callback);
+ helper->Start();
+}
+
+void AppCacheService::DeleteAppCacheGroup(const GURL& manifest_url,
+ net::CompletionCallback* callback) {
+ DeleteHelper* helper = new DeleteHelper(this, manifest_url, callback);
+ helper->Start();
+}
+
void AppCacheService::RegisterBackend(
AppCacheBackendImpl* backend_impl) {
DCHECK(backends_.find(backend_impl->process_id()) == backends_.end());
diff --git a/webkit/appcache/appcache_service.h b/webkit/appcache/appcache_service.h
index 70a0953..7ccdeea 100644
--- a/webkit/appcache/appcache_service.h
+++ b/webkit/appcache/appcache_service.h
@@ -5,8 +5,15 @@
#ifndef WEBKIT_APPCACHE_APPCACHE_SERVICE_H_
#define WEBKIT_APPCACHE_APPCACHE_SERVICE_H_
+#include <set>
+#include <vector>
+
#include "base/file_path.h"
+#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
+#include "base/time.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/appcache/appcache_storage.h"
@@ -17,6 +24,36 @@ namespace appcache {
class AppCacheBackendImpl;
class AppCachePolicy;
+// Structure that contains basic info about an appcache.
+struct AppCacheInfo {
+ AppCacheInfo() {}
+ AppCacheInfo(const GURL& manifest_url,
+ int64 size,
+ base::Time creation_time,
+ base::Time last_access_time,
+ base::Time last_update_time)
+ : manifest_url(manifest_url),
+ size(size),
+ creation_time(creation_time),
+ last_access_time(last_access_time),
+ last_update_time(last_update_time) {
+ }
+ GURL manifest_url;
+ int64 size;
+ base::Time creation_time;
+ base::Time last_access_time;
+ base::Time last_update_time;
+};
+
+typedef std::vector<AppCacheInfo> AppCacheInfoVector;
+
+// Refcounted container to avoid copying the collection in callbacks.
+struct AppCacheInfoCollection
+ : public base::RefCountedThreadSafe<AppCacheInfoCollection> {
+ virtual ~AppCacheInfoCollection() {}
+ std::map<GURL, AppCacheInfoVector> infos_by_origin;
+};
+
// Class that manages the application cache service. Sends notifications
// to many frontends. One instance per user-profile. Each instance has
// exclusive access to it's cache_directory on disk.
@@ -27,11 +64,27 @@ class AppCacheService {
void Initialize(const FilePath& cache_directory);
+ // Purges any memory not needed.
void PurgeMemory() {
if (storage_.get())
storage_->PurgeMemory();
}
+ // Populates 'collection' with info about all of the appcaches stored
+ // within the service, 'callback' is invoked upon completion. The service
+ // acquires a reference to the 'collection' until until completion.
+ // This method always completes asynchronously.
+ void GetAllAppCacheInfo(AppCacheInfoCollection* collection,
+ net::CompletionCallback* callback);
+
+ // Deletes the group identified by 'manifest_url', 'callback' is
+ // invoked upon completion. Upon completion, the cache group and
+ // any resources within the group are no longer loadable and all
+ // subresource loads for pages associated with a deleted group
+ // will fail. This method always completes asynchronously.
+ void DeleteAppCacheGroup(const GURL& manifest_url,
+ net::CompletionCallback* callback);
+
// Context for use during cache updates, should only be accessed
// on the IO thread. We do NOT add a reference to the request context,
// it is the callers responsibility to ensure that the pointer
@@ -49,7 +102,8 @@ class AppCacheService {
appcache_policy_ = policy;
}
- // Track which processes are using this appcache service.
+ // Each child process in chrome uses a distinct backend instance.
+ // See chrome/browser/AppCacheDispatcherHost.
void RegisterBackend(AppCacheBackendImpl* backend_impl);
void UnregisterBackend(AppCacheBackendImpl* backend_impl);
AppCacheBackendImpl* GetBackend(int id) const {
@@ -60,11 +114,19 @@ class AppCacheService {
AppCacheStorage* storage() const { return storage_.get(); }
protected:
+ class AsyncHelper;
+ class DeleteHelper;
+ class GetInfoHelper;
+
+ typedef std::set<AsyncHelper*> PendingAsyncHelpers;
+
AppCachePolicy* appcache_policy_;
// Deals with persistence.
scoped_ptr<AppCacheStorage> storage_;
+ PendingAsyncHelpers pending_helpers_;
+
// Track current processes. One 'backend' per child process.
typedef std::map<int, AppCacheBackendImpl*> BackendMap;
BackendMap backends_;
diff --git a/webkit/appcache/appcache_storage.h b/webkit/appcache/appcache_storage.h
index 4c51e39..5618be4 100644
--- a/webkit/appcache/appcache_storage.h
+++ b/webkit/appcache/appcache_storage.h
@@ -26,6 +26,7 @@ class AppCacheGroup;
class AppCacheResponseReader;
class AppCacheResponseWriter;
class AppCacheService;
+struct AppCacheInfoCollection;
struct HttpResponseInfoIOBuffer;
class AppCacheStorage {
@@ -35,6 +36,9 @@ class AppCacheStorage {
public:
virtual ~Delegate() {}
+ // If retrieval fails, 'collection' will be NULL.
+ virtual void OnAllInfo(AppCacheInfoCollection* collection) {}
+
// If a load fails the 'cache' will be NULL.
virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) {}
@@ -65,6 +69,11 @@ class AppCacheStorage {
explicit AppCacheStorage(AppCacheService* service);
virtual ~AppCacheStorage();
+ // Schedules a task to retrieve basic info about all groups and caches
+ // stored in the system. Upon completion the delegate will be called
+ // with the results.
+ virtual void GetAllInfo(Delegate* delegate) = 0;
+
// Schedules a cache to be loaded from storage. Upon load completion
// the delegate will be called back. If the cache already resides in
// memory, the delegate will be called back immediately without returning
diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc
index 6fd5486..54afc9a 100644
--- a/webkit/appcache/appcache_storage_impl.cc
+++ b/webkit/appcache/appcache_storage_impl.cc
@@ -183,6 +183,49 @@ class AppCacheStorageImpl::DisableDatabaseTask : public DatabaseTask {
virtual void Run() { database_->Disable(); }
};
+// GetAllInfoTask -------
+
+class AppCacheStorageImpl::GetAllInfoTask : public DatabaseTask {
+ public:
+ explicit GetAllInfoTask(AppCacheStorageImpl* storage)
+ : DatabaseTask(storage),
+ info_collection_(new AppCacheInfoCollection()) {
+ }
+
+ virtual void Run();
+ virtual void RunCompleted();
+
+ scoped_refptr<AppCacheInfoCollection> info_collection_;
+};
+
+void AppCacheStorageImpl::GetAllInfoTask::Run() {
+ std::set<GURL> origins;
+ database_->FindOriginsWithGroups(&origins);
+ for (std::set<GURL>::const_iterator origin = origins.begin();
+ origin != origins.end(); ++origin) {
+ AppCacheInfoVector& infos =
+ info_collection_->infos_by_origin[*origin];
+ std::vector<AppCacheDatabase::GroupRecord> groups;
+ database_->FindGroupsForOrigin(*origin, &groups);
+ for (std::vector<AppCacheDatabase::GroupRecord>::const_iterator
+ group = groups.begin();
+ group != groups.end(); ++group) {
+ AppCacheDatabase::CacheRecord cache_record;
+ database_->FindCacheForGroup(group->group_id, &cache_record);
+ infos.push_back(
+ AppCacheInfo(
+ group->manifest_url, cache_record.cache_size,
+ group->creation_time, group->last_access_time,
+ cache_record.update_time));
+ }
+ }
+}
+
+void AppCacheStorageImpl::GetAllInfoTask::RunCompleted() {
+ DCHECK(delegates_.size() == 1);
+ FOR_EACH_DELEGATE(delegates_, OnAllInfo(info_collection_));
+}
+
// StoreOrLoadTask -------
class AppCacheStorageImpl::StoreOrLoadTask : public DatabaseTask {
@@ -812,6 +855,13 @@ void AppCacheStorageImpl::Disable() {
task->Schedule();
}
+void AppCacheStorageImpl::GetAllInfo(Delegate* delegate) {
+ DCHECK(delegate);
+ scoped_refptr<GetAllInfoTask> task = new GetAllInfoTask(this);
+ task->AddDelegate(GetOrCreateDelegateReference(delegate));
+ task->Schedule();
+}
+
void AppCacheStorageImpl::LoadCache(int64 id, Delegate* delegate) {
DCHECK(delegate);
if (is_disabled_) {
@@ -993,6 +1043,17 @@ void AppCacheStorageImpl::FindResponseForSubRequest(
AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
bool* found_network_namespace) {
DCHECK(cache && cache->is_complete());
+
+ // When a group is forcibly deleted, all subresource loads for pages
+ // using caches in the group will result in a synthesized network errors.
+ // Forcible deletion is not a function that is covered by the HTML5 spec.
+ if (cache->owning_group()->is_being_deleted()) {
+ *found_entry = AppCacheEntry();
+ *found_fallback_entry = AppCacheEntry();
+ *found_network_namespace = false;
+ return;
+ }
+
GURL fallback_namespace_not_used;
cache->FindResponseForRequest(
url, found_entry, found_fallback_entry,
diff --git a/webkit/appcache/appcache_storage_impl.h b/webkit/appcache/appcache_storage_impl.h
index b644eff..5771dd4 100644
--- a/webkit/appcache/appcache_storage_impl.h
+++ b/webkit/appcache/appcache_storage_impl.h
@@ -27,7 +27,8 @@ class AppCacheStorageImpl : public AppCacheStorage {
void Disable();
bool is_disabled() const { return is_disabled_; }
- // AppCacheStorage methods
+ // AppCacheStorage methods, see the base class for doc comments.
+ virtual void GetAllInfo(Delegate* delegate);
virtual void LoadCache(int64 id, Delegate* delegate);
virtual void LoadOrCreateGroup(const GURL& manifest_url, Delegate* delegate);
virtual void StoreGroupAndNewestCache(
@@ -59,6 +60,7 @@ class AppCacheStorageImpl : public AppCacheStorage {
class InitTask;
class CloseConnectionTask;
class DisableDatabaseTask;
+ class GetAllInfoTask;
class StoreOrLoadTask;
class CacheLoadTask;
class GroupLoadTask;
diff --git a/webkit/appcache/mock_appcache_storage.h b/webkit/appcache/mock_appcache_storage.h
index 48834bd..10bd780 100644
--- a/webkit/appcache/mock_appcache_storage.h
+++ b/webkit/appcache/mock_appcache_storage.h
@@ -28,6 +28,7 @@ class MockAppCacheStorage : public AppCacheStorage {
explicit MockAppCacheStorage(AppCacheService* service);
virtual ~MockAppCacheStorage();
+ virtual void GetAllInfo(Delegate* delegate) {} // not implemented
virtual void LoadCache(int64 id, Delegate* delegate);
virtual void LoadOrCreateGroup(const GURL& manifest_url, Delegate* delegate);
virtual void StoreGroupAndNewestCache(