From 9830d77aa9cc9efd03d64226b15cfd94c39e66f8 Mon Sep 17 00:00:00 2001 From: "michaeln@google.com" Date: Mon, 16 May 2011 18:39:39 +0000 Subject: Enough appcache + quota integration to call NotifyOriginInUse/NotifyOriginNoLongerInUse when frames are loaded/unloaded. BUG=61676 TEST=appcache_host_unittest.cc Review URL: http://codereview.chromium.org/6999008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85507 0039d316-1c4b-4281-b951-d872f2087c98 --- .../extensions/extension_service_unittest.cc | 2 +- chrome/browser/profiles/profile.cc | 25 ++++---- chrome/browser/profiles/profile_impl.cc | 25 ++++---- .../browser/appcache/chrome_appcache_service.cc | 7 +- content/browser/appcache/chrome_appcache_service.h | 2 +- .../appcache/chrome_appcache_service_unittest.cc | 4 +- webkit/appcache/appcache_host.cc | 7 ++ webkit/appcache/appcache_host.h | 3 + webkit/appcache/appcache_host_unittest.cc | 75 +++++++++++++++++----- webkit/appcache/appcache_service.cc | 9 ++- webkit/appcache/appcache_service.h | 9 ++- webkit/appcache/appcache_storage_impl_unittest.cc | 2 +- webkit/appcache/mock_appcache_service.h | 7 +- webkit/tools/test_shell/simple_appcache_system.cc | 2 +- 14 files changed, 125 insertions(+), 54 deletions(-) diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 11b050c..198bd06 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -345,7 +345,7 @@ class ExtensionTestingProfile : public TestingProfile { virtual ChromeAppCacheService* GetAppCacheService() { if (!appcache_service_) { - appcache_service_ = new ChromeAppCacheService; + appcache_service_ = new ChromeAppCacheService(NULL); if (!BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableMethod( diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 20e84ee..c87666c 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -270,19 +270,7 @@ class OffTheRecordProfileImpl : public Profile, } virtual ChromeAppCacheService* GetAppCacheService() { - if (!appcache_service_) { - appcache_service_ = new ChromeAppCacheService; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - appcache_service_.get(), - &ChromeAppCacheService::InitializeOnIOThread, - IsOffTheRecord() - ? FilePath() : GetPath().Append(chrome::kAppCacheDirname), - &GetResourceContext(), - make_scoped_refptr(GetExtensionSpecialStoragePolicy()), - false)); - } + CreateQuotaManagerAndClients(); return appcache_service_; } @@ -720,6 +708,17 @@ class OffTheRecordProfileImpl : public Profile, GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy(), quota_manager_->proxy(), BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); + appcache_service_ = new ChromeAppCacheService(quota_manager_->proxy()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + appcache_service_.get(), + &ChromeAppCacheService::InitializeOnIOThread, + IsOffTheRecord() + ? FilePath() : GetPath().Append(chrome::kAppCacheDirname), + &GetResourceContext(), + make_scoped_refptr(GetExtensionSpecialStoragePolicy()), + false)); } NotificationRegistrar registrar_; diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 4bf4a75..57716423 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -721,19 +721,7 @@ Profile* ProfileImpl::GetOriginalProfile() { } ChromeAppCacheService* ProfileImpl::GetAppCacheService() { - if (!appcache_service_) { - appcache_service_ = new ChromeAppCacheService; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - appcache_service_.get(), - &ChromeAppCacheService::InitializeOnIOThread, - IsOffTheRecord() - ? FilePath() : GetPath().Append(chrome::kAppCacheDirname), - &GetResourceContext(), - make_scoped_refptr(GetExtensionSpecialStoragePolicy()), - clear_local_state_on_exit_)); - } + CreateQuotaManagerAndClients(); return appcache_service_; } @@ -1303,6 +1291,17 @@ void ProfileImpl::CreateQuotaManagerAndClients() { GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy(), quota_manager_->proxy(), BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); + appcache_service_ = new ChromeAppCacheService(quota_manager_->proxy()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + appcache_service_.get(), + &ChromeAppCacheService::InitializeOnIOThread, + IsOffTheRecord() + ? FilePath() : GetPath().Append(chrome::kAppCacheDirname), + &GetResourceContext(), + make_scoped_refptr(GetExtensionSpecialStoragePolicy()), + clear_local_state_on_exit_)); } WebKitContext* ProfileImpl::GetWebKitContext() { diff --git a/content/browser/appcache/chrome_appcache_service.cc b/content/browser/appcache/chrome_appcache_service.cc index e873524..169f59e 100644 --- a/content/browser/appcache/chrome_appcache_service.cc +++ b/content/browser/appcache/chrome_appcache_service.cc @@ -10,6 +10,7 @@ #include "content/common/notification_service.h" #include "net/base/net_errors.h" #include "webkit/appcache/appcache_thread.h" +#include "webkit/quota/quota_manager.h" static bool has_initialized_thread_ids; @@ -29,8 +30,10 @@ void DeleteLocalStateOnIOThread(FilePath cache_path) { // ---------------------------------------------------------------------------- -ChromeAppCacheService::ChromeAppCacheService() - : resource_context_(NULL), clear_local_state_on_exit_(false) { +ChromeAppCacheService::ChromeAppCacheService( + quota::QuotaManagerProxy* quota_manager_proxy) + : AppCacheService(quota_manager_proxy), + resource_context_(NULL), clear_local_state_on_exit_(false) { } void ChromeAppCacheService::InitializeOnIOThread( diff --git a/content/browser/appcache/chrome_appcache_service.h b/content/browser/appcache/chrome_appcache_service.h index a56d31c..4ebff8d 100644 --- a/content/browser/appcache/chrome_appcache_service.h +++ b/content/browser/appcache/chrome_appcache_service.h @@ -35,7 +35,7 @@ class ChromeAppCacheService public appcache::AppCachePolicy, public NotificationObserver { public: - ChromeAppCacheService(); + explicit ChromeAppCacheService(quota::QuotaManagerProxy* proxy); void InitializeOnIOThread( const FilePath& cache_path, // may be empty to use in-memory structures diff --git a/content/browser/appcache/chrome_appcache_service_unittest.cc b/content/browser/appcache/chrome_appcache_service_unittest.cc index 475bf5c..aad4d730 100644 --- a/content/browser/appcache/chrome_appcache_service_unittest.cc +++ b/content/browser/appcache/chrome_appcache_service_unittest.cc @@ -42,7 +42,7 @@ TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname); scoped_refptr appcache_service = - new ChromeAppCacheService; + new ChromeAppCacheService(NULL); const content::ResourceContext* resource_context = NULL; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -74,7 +74,7 @@ TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname); scoped_refptr appcache_service = - new ChromeAppCacheService; + new ChromeAppCacheService(NULL); const content::ResourceContext* resource_context = NULL; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, diff --git a/webkit/appcache/appcache_host.cc b/webkit/appcache/appcache_host.cc index 18809790..6965c1d 100644 --- a/webkit/appcache/appcache_host.cc +++ b/webkit/appcache/appcache_host.cc @@ -10,6 +10,7 @@ #include "webkit/appcache/appcache.h" #include "webkit/appcache/appcache_backend_impl.h" #include "webkit/appcache/appcache_request_handler.h" +#include "webkit/quota/quota_manager.h" namespace appcache { @@ -52,6 +53,8 @@ AppCacheHost::~AppCacheHost() { if (group_being_updated_.get()) group_being_updated_->RemoveUpdateObserver(this); service_->storage()->CancelDelegateCallbacks(this); + if (service()->quota_manager_proxy() && !origin_in_use_.is_empty()) + service()->quota_manager_proxy()->NotifyOriginNoLongerInUse(origin_in_use_); } void AppCacheHost::AddObserver(Observer* observer) { @@ -70,6 +73,10 @@ void AppCacheHost::SelectCache(const GURL& document_url, !pending_get_status_callback_ && !is_selection_pending()); + origin_in_use_ = document_url.GetOrigin(); + if (service()->quota_manager_proxy() && !origin_in_use_.is_empty()) + service()->quota_manager_proxy()->NotifyOriginInUse(origin_in_use_); + if (main_resource_blocked_) frontend_->OnContentBlocked(host_id_, blocked_manifest_url_); diff --git a/webkit/appcache/appcache_host.h b/webkit/appcache/appcache_host.h index 6f25a57..a06cdd3 100644 --- a/webkit/appcache/appcache_host.h +++ b/webkit/appcache/appcache_host.h @@ -242,6 +242,9 @@ class AppCacheHost : public AppCacheStorage::Delegate, // List of objects observing us. ObserverList observers_; + // Used to inform the QuotaManager of what origins are currently in use. + GURL origin_in_use_; + friend class AppCacheRequestHandlerTest; friend class AppCacheUpdateJobTest; FRIEND_TEST_ALL_PREFIXES(AppCacheTest, CleanupUnusedCache); diff --git a/webkit/appcache/appcache_host_unittest.cc b/webkit/appcache/appcache_host_unittest.cc index d648e07..762ed9c 100644 --- a/webkit/appcache/appcache_host_unittest.cc +++ b/webkit/appcache/appcache_host_unittest.cc @@ -11,6 +11,7 @@ #include "webkit/appcache/appcache_group.h" #include "webkit/appcache/appcache_host.h" #include "webkit/appcache/mock_appcache_service.h" +#include "webkit/quota/quota_manager.h" namespace appcache { @@ -76,6 +77,40 @@ class AppCacheHostTest : public testing::Test { appcache::EventID last_event_id_; }; + class MockQuotaManagerProxy : public quota::QuotaManagerProxy { + public: + MockQuotaManagerProxy() : QuotaManagerProxy(NULL, NULL) {} + + // Not needed for our tests. + virtual void RegisterClient(quota::QuotaClient* client) {} + virtual void NotifyStorageAccessed(quota::QuotaClient::ID client_id, + const GURL& origin, + quota::StorageType type) {} + virtual void NotifyStorageModified(quota::QuotaClient::ID client_id, + const GURL& origin, + quota::StorageType type, + int64 delta) {} + + virtual void NotifyOriginInUse(const GURL& origin) { + inuse_[origin] += 1; + } + + virtual void NotifyOriginNoLongerInUse(const GURL& origin) { + inuse_[origin] -= 1; + } + + int GetInUseCount(const GURL& origin) { + return inuse_[origin]; + } + + void reset() { + inuse_.clear(); + } + + // Map from origin to count of inuse notifications. + std::map inuse_; + }; + void GetStatusCallback(Status status, void* param) { last_status_result_ = status; last_callback_param_ = param; @@ -137,26 +172,36 @@ TEST_F(AppCacheHostTest, Basic) { } TEST_F(AppCacheHostTest, SelectNoCache) { + scoped_refptr mock_quota_proxy( + new MockQuotaManagerProxy); + service_.set_quota_manager_proxy(mock_quota_proxy); + // Reset our mock frontend mock_frontend_.last_cache_id_ = -333; mock_frontend_.last_host_id_ = -333; mock_frontend_.last_status_ = OBSOLETE; - AppCacheHost host(1, &mock_frontend_, &service_); - host.SelectCache(GURL("http://whatever/"), kNoCacheId, GURL()); - - // We should have received an OnCacheSelected msg - EXPECT_EQ(1, mock_frontend_.last_host_id_); - EXPECT_EQ(kNoCacheId, mock_frontend_.last_cache_id_); - EXPECT_EQ(UNCACHED, mock_frontend_.last_status_); - - // Otherwise, see that it respond as if there is no cache selected. - EXPECT_EQ(1, host.host_id()); - EXPECT_EQ(&service_, host.service()); - EXPECT_EQ(&mock_frontend_, host.frontend()); - EXPECT_EQ(NULL, host.associated_cache()); - EXPECT_FALSE(host.is_selection_pending()); - EXPECT_TRUE(host.preferred_manifest_url().is_empty()); + const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin()); + { + AppCacheHost host(1, &mock_frontend_, &service_); + host.SelectCache(kDocAndOriginUrl, kNoCacheId, GURL()); + EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + + // We should have received an OnCacheSelected msg + EXPECT_EQ(1, mock_frontend_.last_host_id_); + EXPECT_EQ(kNoCacheId, mock_frontend_.last_cache_id_); + EXPECT_EQ(UNCACHED, mock_frontend_.last_status_); + + // Otherwise, see that it respond as if there is no cache selected. + EXPECT_EQ(1, host.host_id()); + EXPECT_EQ(&service_, host.service()); + EXPECT_EQ(&mock_frontend_, host.frontend()); + EXPECT_EQ(NULL, host.associated_cache()); + EXPECT_FALSE(host.is_selection_pending()); + EXPECT_TRUE(host.preferred_manifest_url().is_empty()); + } + EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + service_.set_quota_manager_proxy(NULL); } TEST_F(AppCacheHostTest, ForeignEntry) { diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc index 5e477ac..fbfd379 100644 --- a/webkit/appcache/appcache_service.cc +++ b/webkit/appcache/appcache_service.cc @@ -10,6 +10,7 @@ #include "webkit/appcache/appcache_backend_impl.h" #include "webkit/appcache/appcache_entry.h" #include "webkit/appcache/appcache_storage_impl.h" +#include "webkit/quota/quota_manager.h" #include "webkit/quota/special_storage_policy.h" namespace appcache { @@ -175,13 +176,14 @@ void AppCacheService::GetInfoHelper::OnAllInfo( // AppCacheService ------- -AppCacheService::AppCacheService() - : appcache_policy_(NULL), request_context_(NULL) { +AppCacheService::AppCacheService(quota::QuotaManagerProxy* quota_manager_proxy) + : appcache_policy_(NULL), quota_manager_proxy_(quota_manager_proxy), + request_context_(NULL) { + // TODO(michaeln): Create and register our QuotaClient. } AppCacheService::~AppCacheService() { DCHECK(backends_.empty()); - std::for_each(pending_helpers_.begin(), pending_helpers_.end(), std::mem_fun(&AsyncHelper::Cancel)); @@ -221,6 +223,7 @@ void AppCacheService::set_special_storage_policy( quota::SpecialStoragePolicy* policy) { special_storage_policy_ = policy; } + 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 d4ece07..2606a7a 100644 --- a/webkit/appcache/appcache_service.h +++ b/webkit/appcache/appcache_service.h @@ -28,6 +28,7 @@ class MessageLoopProxy; } namespace quota { +class QuotaManagerProxy; class SpecialStoragePolicy; } @@ -50,7 +51,8 @@ struct AppCacheInfoCollection // exclusive access to it's cache_directory on disk. class AppCacheService { public: - AppCacheService(); + // If not using quota management, the proxy may be NULL. + explicit AppCacheService(quota::QuotaManagerProxy* quota_manager_proxy); virtual ~AppCacheService(); void Initialize(const FilePath& cache_directory, @@ -104,6 +106,10 @@ class AppCacheService { } void set_special_storage_policy(quota::SpecialStoragePolicy* policy); + quota::QuotaManagerProxy* quota_manager_proxy() const { + return quota_manager_proxy_.get(); + } + // Each child process in chrome uses a distinct backend instance. // See chrome/browser/AppCacheDispatcherHost. void RegisterBackend(AppCacheBackendImpl* backend_impl); @@ -127,6 +133,7 @@ class AppCacheService { AppCachePolicy* appcache_policy_; scoped_ptr storage_; scoped_refptr special_storage_policy_; + scoped_refptr quota_manager_proxy_; PendingAsyncHelpers pending_helpers_; BackendMap backends_; // One 'backend' per child process. // Context for use during cache updates. diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc index af87b08..1237c02 100644 --- a/webkit/appcache/appcache_storage_impl_unittest.cc +++ b/webkit/appcache/appcache_storage_impl_unittest.cc @@ -241,7 +241,7 @@ class AppCacheStorageImplTest : public testing::Test { void SetUpTest() { DCHECK(MessageLoop::current() == io_thread->message_loop()); - service_.reset(new AppCacheService); + service_.reset(new AppCacheService(NULL)); service_->Initialize(FilePath(), NULL); delegate_.reset(new MockStorageDelegate(this)); } diff --git a/webkit/appcache/mock_appcache_service.h b/webkit/appcache/mock_appcache_service.h index 705dc0e..d9f327a 100644 --- a/webkit/appcache/mock_appcache_service.h +++ b/webkit/appcache/mock_appcache_service.h @@ -8,15 +8,20 @@ #include "base/compiler_specific.h" #include "webkit/appcache/appcache_service.h" #include "webkit/appcache/mock_appcache_storage.h" +#include "webkit/quota/quota_manager.h" namespace appcache { // For use by unit tests. class MockAppCacheService : public AppCacheService { public: - MockAppCacheService() { + MockAppCacheService() : AppCacheService(NULL) { storage_.reset(new MockAppCacheStorage(this)); } + + void set_quota_manager_proxy(quota::QuotaManagerProxy* proxy) { + quota_manager_proxy_ = proxy; + } }; } // namespace appcache diff --git a/webkit/tools/test_shell/simple_appcache_system.cc b/webkit/tools/test_shell/simple_appcache_system.cc index af6242d..93d70cf 100644 --- a/webkit/tools/test_shell/simple_appcache_system.cc +++ b/webkit/tools/test_shell/simple_appcache_system.cc @@ -410,7 +410,7 @@ void SimpleAppCacheSystem::InitOnIOThread( db_thread_.Start(); // Recreate and initialize per each IO thread. - service_ = new appcache::AppCacheService(); + service_ = new appcache::AppCacheService(NULL); backend_impl_ = new appcache::AppCacheBackendImpl(); service_->Initialize(cache_directory_, SimpleResourceLoaderBridge::GetCacheThread()); -- cgit v1.1