diff options
Diffstat (limited to 'webkit/quota')
-rw-r--r-- | webkit/quota/mock_special_storage_policy.h | 4 | ||||
-rw-r--r-- | webkit/quota/quota_manager_unittest.cc | 32 | ||||
-rw-r--r-- | webkit/quota/special_storage_policy.cc | 15 | ||||
-rw-r--r-- | webkit/quota/special_storage_policy.h | 19 | ||||
-rw-r--r-- | webkit/quota/usage_tracker.cc | 37 | ||||
-rw-r--r-- | webkit/quota/usage_tracker.h | 13 |
6 files changed, 109 insertions, 11 deletions
diff --git a/webkit/quota/mock_special_storage_policy.h b/webkit/quota/mock_special_storage_policy.h index ec65fe3..3f3a873 100644 --- a/webkit/quota/mock_special_storage_policy.h +++ b/webkit/quota/mock_special_storage_policy.h @@ -39,6 +39,10 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy { file_handlers_.clear(); } + void NotifyChanged() { + SpecialStoragePolicy::NotifyObservers(); + } + private: std::set<GURL> protected_; std::set<GURL> unlimited_; diff --git a/webkit/quota/quota_manager_unittest.cc b/webkit/quota/quota_manager_unittest.cc index 3e6b32a..2c828b3 100644 --- a/webkit/quota/quota_manager_unittest.cc +++ b/webkit/quota/quota_manager_unittest.cc @@ -710,6 +710,11 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_Unlimited) { SetTemporaryGlobalQuota(1000); MessageLoop::current()->RunAllPending(); + GetGlobalUsage(kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(10 + 50 + 4000, usage()); + EXPECT_EQ(4000, unlimited_usage()); + const int kPerHostQuotaFor1000 = 1000 / QuotaManager::kPerHostTemporaryPortion; @@ -755,6 +760,33 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_Unlimited) { EXPECT_EQ(kQuotaStatusOk, status()); EXPECT_EQ(4000, usage()); EXPECT_EQ(kint64max, quota()); + + // Revoke the unlimited rights and make sure the change is noticed. + mock_special_storage_policy()->Reset(); + mock_special_storage_policy()->NotifyChanged(); + + GetGlobalUsage(kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(10 + 50 + 4000, usage()); + EXPECT_EQ(0, unlimited_usage()); + + GetUsageAndQuota(GURL("http://usage10/"), kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(kQuotaStatusOk, status()); + EXPECT_EQ(10, usage()); + EXPECT_EQ(10, quota()); // should be clamped to our current usage + + GetUsageAndQuota(GURL("http://usage50/"), kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(kQuotaStatusOk, status()); + EXPECT_EQ(50, usage()); + EXPECT_EQ(kPerHostQuotaFor100, quota()); + + GetUsageAndQuota(GURL("http://unlimited/"), kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(kQuotaStatusOk, status()); + EXPECT_EQ(4000, usage()); + EXPECT_EQ(kPerHostQuotaFor100, quota()); } TEST_F(QuotaManagerTest, OriginInUse) { diff --git a/webkit/quota/special_storage_policy.cc b/webkit/quota/special_storage_policy.cc index c428346..8481239 100644 --- a/webkit/quota/special_storage_policy.cc +++ b/webkit/quota/special_storage_policy.cc @@ -6,8 +6,23 @@ namespace quota { +SpecialStoragePolicy::Observer::~Observer() {} + SpecialStoragePolicy::SpecialStoragePolicy() {} SpecialStoragePolicy::~SpecialStoragePolicy() {} +void SpecialStoragePolicy::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void SpecialStoragePolicy::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void SpecialStoragePolicy::NotifyObservers() { + scoped_refptr<SpecialStoragePolicy> protect(this); + FOR_EACH_OBSERVER(Observer, observers_, OnSpecialStoragePolicyChanged()); +} + } // namespace quota diff --git a/webkit/quota/special_storage_policy.h b/webkit/quota/special_storage_policy.h index d9f1728..cc1af6b 100644 --- a/webkit/quota/special_storage_policy.h +++ b/webkit/quota/special_storage_policy.h @@ -8,6 +8,7 @@ #include <string> #include "base/memory/ref_counted.h" +#include "base/observer_list.h" class GURL; @@ -17,10 +18,18 @@ namespace quota { // storage subsystems query this interface to determine which origins // have these rights. Chrome provides an impl that is cognizant of what // is currently installed in the extensions system. -// An implementation must be thread-safe. +// The IsSomething() methods must be thread-safe, however Observers should +// only be notified, added, and removed on the IO thead. class SpecialStoragePolicy : public base::RefCountedThreadSafe<SpecialStoragePolicy> { public: + class Observer { + public: + virtual void OnSpecialStoragePolicyChanged() = 0; + protected: + virtual ~Observer(); + }; + SpecialStoragePolicy(); // Protected storage is not subject to removal by the browsing data remover. @@ -33,9 +42,17 @@ class SpecialStoragePolicy // file handler. virtual bool IsFileHandler(const std::string& extension_id) = 0; + // Adds/removes an observer, the policy does not take + // ownership of the observer. Should only be called on the IO thread. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + protected: friend class base::RefCountedThreadSafe<SpecialStoragePolicy>; virtual ~SpecialStoragePolicy(); + void NotifyObservers(); + + ObserverList<Observer> observers_; }; } // namespace quota diff --git a/webkit/quota/usage_tracker.cc b/webkit/quota/usage_tracker.cc index 9a98bb1..60abf85 100644 --- a/webkit/quota/usage_tracker.cc +++ b/webkit/quota/usage_tracker.cc @@ -12,7 +12,6 @@ #include "base/message_loop_proxy.h" #include "base/stl_util.h" #include "net/base/net_util.h" -#include "webkit/quota/special_storage_policy.h" namespace quota { @@ -334,18 +333,23 @@ ClientUsageTracker::ClientUsageTracker( global_usage_(0), global_unlimited_usage_(0), global_usage_retrieved_(false), + global_unlimited_usage_is_valid_(true), global_usage_task_(NULL), special_storage_policy_(special_storage_policy) { DCHECK(tracker_); DCHECK(client_); + if (special_storage_policy_) + special_storage_policy_->AddObserver(this); } ClientUsageTracker::~ClientUsageTracker() { + if (special_storage_policy_) + special_storage_policy_->RemoveObserver(this); } void ClientUsageTracker::GetGlobalUsage(GlobalUsageCallback* callback) { if (global_usage_retrieved_) { - callback->Run(type_, global_usage_, global_unlimited_usage_); + callback->Run(type_, global_usage_, GetCachedGlobalUnlimitedUsage()); delete callback; return; } @@ -377,7 +381,7 @@ void ClientUsageTracker::UpdateUsageCache( if (cached_hosts_.find(host) != cached_hosts_.end()) { cached_usage_[host][origin] += delta; global_usage_ += delta; - if (IsStorageUnlimited(origin)) + if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin)) global_unlimited_usage_ += delta; DCHECK_GE(cached_usage_[host][origin], 0); DCHECK_GE(global_usage_, 0); @@ -411,7 +415,7 @@ void ClientUsageTracker::AddCachedOrigin( int64 delta = usage - old_usage; if (delta) { global_usage_ += delta; - if (IsStorageUnlimited(origin)) + if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin)) global_unlimited_usage_ += delta; } DCHECK_GE(iter->second, 0); @@ -429,7 +433,8 @@ void ClientUsageTracker::GatherGlobalUsageComplete() { global_usage_retrieved_ = true; DCHECK(global_usage_callback_.HasCallbacks()); - global_usage_callback_.Run(type_, global_usage_, global_unlimited_usage_); + global_usage_callback_.Run(type_, global_usage_, + GetCachedGlobalUnlimitedUsage()); for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin(); iter != host_usage_callbacks_.End(); ++iter) { @@ -458,6 +463,28 @@ int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) { return usage; } +int64 ClientUsageTracker::GetCachedGlobalUnlimitedUsage() { + if (!global_unlimited_usage_is_valid_) { + global_unlimited_usage_ = 0; + for (HostUsageMap::const_iterator host_iter = cached_usage_.begin(); + host_iter != cached_usage_.end(); host_iter++) { + const UsageMap& origin_map = host_iter->second; + for (UsageMap::const_iterator origin_iter = origin_map.begin(); + origin_iter != origin_map.end(); origin_iter++) { + if (IsStorageUnlimited(origin_iter->first)) + global_unlimited_usage_ += origin_iter->second; + } + } + global_unlimited_usage_is_valid_ = true; + } + return global_unlimited_usage_; +} + +void ClientUsageTracker::OnSpecialStoragePolicyChanged() { + DCHECK(CalledOnValidThread()); + global_unlimited_usage_is_valid_ = false; +} + void ClientUsageTracker::NoopHostUsageCallback( const std::string& host, StorageType type, int64 usage) { } diff --git a/webkit/quota/usage_tracker.h b/webkit/quota/usage_tracker.h index b4fc51b..258ef16 100644 --- a/webkit/quota/usage_tracker.h +++ b/webkit/quota/usage_tracker.h @@ -15,15 +15,16 @@ #include "base/callback.h" #include "base/memory/scoped_callback_factory.h" #include "base/memory/scoped_ptr.h" +#include "base/threading/non_thread_safe.h" #include "googleurl/src/gurl.h" #include "webkit/quota/quota_client.h" #include "webkit/quota/quota_task.h" #include "webkit/quota/quota_types.h" +#include "webkit/quota/special_storage_policy.h" namespace quota { class ClientUsageTracker; -class SpecialStoragePolicy; // A helper class that gathers and tracks the amount of data stored in // all quota clients. @@ -79,13 +80,14 @@ class UsageTracker : public QuotaTaskObserver { // This class holds per-client usage tracking information and caches per-host // usage data. An instance of this class is created per client. -class ClientUsageTracker { +class ClientUsageTracker : public SpecialStoragePolicy::Observer, + public base::NonThreadSafe { public: ClientUsageTracker(UsageTracker* tracker, QuotaClient* client, StorageType type, SpecialStoragePolicy* special_storage_policy); - ~ClientUsageTracker(); + virtual ~ClientUsageTracker(); void GetGlobalUsage(GlobalUsageCallback* callback); void GetHostUsage(const std::string& host, HostUsageCallback* callback); @@ -109,10 +111,10 @@ class ClientUsageTracker { void GatherHostUsageComplete(const std::string& host); int64 GetCachedHostUsage(const std::string& host); - + int64 GetCachedGlobalUnlimitedUsage(); + virtual void OnSpecialStoragePolicyChanged() OVERRIDE; void NoopHostUsageCallback( const std::string& host, StorageType type, int64 usage); - bool IsStorageUnlimited(const GURL& origin) const; UsageTracker* tracker_; @@ -122,6 +124,7 @@ class ClientUsageTracker { int64 global_usage_; int64 global_unlimited_usage_; bool global_usage_retrieved_; + bool global_unlimited_usage_is_valid_; HostSet cached_hosts_; HostUsageMap cached_usage_; |