diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 23:40:02 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 23:40:02 +0000 |
commit | d68a4fc6f448c6ebf407e2817320e7736c4735ee (patch) | |
tree | d76e2c91aa67af5a880ec81eddcbf2d12887e865 /webkit | |
parent | 63eb6c0bebc31046bbd954ef21dee86dca9d7fe3 (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | webkit/appcache/appcache_group.h | 7 | ||||
-rw-r--r-- | webkit/appcache/appcache_host.cc | 14 | ||||
-rw-r--r-- | webkit/appcache/appcache_service.cc | 138 | ||||
-rw-r--r-- | webkit/appcache/appcache_service.h | 64 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage.h | 9 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl.cc | 61 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl.h | 4 | ||||
-rw-r--r-- | webkit/appcache/mock_appcache_storage.h | 1 |
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( |