diff options
author | tmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-05 15:23:08 +0000 |
---|---|---|
committer | tmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-05 15:23:08 +0000 |
commit | 583f96cbe459b514f3f7df9d9bf7c1d62d6a327f (patch) | |
tree | 783fe1fd26eeeec4c52f534f3a7066b0d6aca81d /webkit | |
parent | e2b132080b7a13fd9f9a740a1aa15c502857ab98 (diff) | |
download | chromium_src-583f96cbe459b514f3f7df9d9bf7c1d62d6a327f.zip chromium_src-583f96cbe459b514f3f7df9d9bf7c1d62d6a327f.tar.gz chromium_src-583f96cbe459b514f3f7df9d9bf7c1d62d6a327f.tar.bz2 |
Fixed initialization of HostStorageObservers
Fixes a case where a usage change occurs before
QuotaManager::GetUsageAndQuotaForWebApps() invokes the callback.
The usage delta needs to be saved in order to initialize the
cached usage correctly.
BUG=347801
TEST=content_unittests
Review URL: https://codereview.chromium.org/225323003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/browser/quota/storage_monitor.cc | 14 | ||||
-rw-r--r-- | webkit/browser/quota/storage_monitor.h | 1 | ||||
-rw-r--r-- | webkit/browser/quota/storage_monitor_unittest.cc | 56 |
3 files changed, 68 insertions, 3 deletions
diff --git a/webkit/browser/quota/storage_monitor.cc b/webkit/browser/quota/storage_monitor.cc index fbb0151..bb56af3 100644 --- a/webkit/browser/quota/storage_monitor.cc +++ b/webkit/browser/quota/storage_monitor.cc @@ -116,6 +116,7 @@ HostStorageObservers::HostStorageObservers(QuotaManager* quota_manager) initialized_(false), initializing_(false), event_occurred_before_init_(false), + usage_deltas_during_init_(0), cached_usage_(0), cached_quota_(0), weak_factory_(this) { @@ -164,6 +165,17 @@ void HostStorageObservers::NotifyUsageChange( // If a storage change occurs before initialization, ensure all observers will // receive an event once initialization is complete. event_occurred_before_init_ = true; + + // During QuotaManager::GetUsageAndQuotaForWebApps(), cached data is read + // synchronously, but other data may be retrieved asynchronously. A usage + // change may occur between the function call and callback. These deltas need + // to be added to the usage received by GotHostUsageAndQuota() to ensure + // |cached_usage_| is correctly initialized. + if (initializing_) { + usage_deltas_during_init_ += delta; + return; + } + StartInitialization(filter); } @@ -192,7 +204,7 @@ void HostStorageObservers::GotHostUsageAndQuota( initialized_ = true; cached_quota_ = quota; - cached_usage_ = usage; + cached_usage_ = usage + usage_deltas_during_init_; DispatchEvent(filter, event_occurred_before_init_); } diff --git a/webkit/browser/quota/storage_monitor.h b/webkit/browser/quota/storage_monitor.h index 0503a66..2ac6053 100644 --- a/webkit/browser/quota/storage_monitor.h +++ b/webkit/browser/quota/storage_monitor.h @@ -99,6 +99,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT_PRIVATE HostStorageObservers { bool initialized_; bool initializing_; bool event_occurred_before_init_; + int64 usage_deltas_during_init_; // Cached accumulated usage and quota for the host. int64 cached_usage_; diff --git a/webkit/browser/quota/storage_monitor_unittest.cc b/webkit/browser/quota/storage_monitor_unittest.cc index da1d695..f1e287c 100644 --- a/webkit/browser/quota/storage_monitor_unittest.cc +++ b/webkit/browser/quota/storage_monitor_unittest.cc @@ -56,20 +56,29 @@ class UsageMockQuotaManager : public QuotaManager { special_storage_policy), callback_usage_(0), callback_quota_(0), - callback_status_(kQuotaStatusOk) { + callback_status_(kQuotaStatusOk), + initialized_(false) { } void SetCallbackParams(int64 usage, int64 quota, QuotaStatusCode status) { + initialized_ = true; callback_quota_ = quota; callback_usage_ = usage; callback_status_ = status; } + void InvokeCallback() { + delayed_callback_.Run(callback_status_, callback_usage_, callback_quota_); + } + virtual void GetUsageAndQuotaForWebApps( const GURL& origin, StorageType type, const GetUsageAndQuotaCallback& callback) OVERRIDE { - callback.Run(callback_status_, callback_usage_, callback_quota_); + if (initialized_) + callback.Run(callback_status_, callback_usage_, callback_quota_); + else + delayed_callback_ = callback; } protected: @@ -79,6 +88,8 @@ class UsageMockQuotaManager : public QuotaManager { int64 callback_usage_; int64 callback_quota_; QuotaStatusCode callback_status_; + bool initialized_; + GetUsageAndQuotaCallback delayed_callback_; }; } // namespace @@ -429,6 +440,47 @@ TEST_F(HostStorageObserversTest, RecoverFromBadUsageInit) { EXPECT_TRUE(host_observers.is_initialized()); } +// Verify that HostStorageObservers handle initialization of the cached usage +// and quota correctly. +TEST_F(HostStorageObserversTest, AsyncInitialization) { + StorageObserver::MonitorParams params(kStorageTypePersistent, + GURL(kDefaultOrigin), + base::TimeDelta::FromHours(1), + false); + MockObserver mock_observer; + HostStorageObservers host_observers(quota_manager_.get()); + host_observers.AddObserver(&mock_observer, params); + + // Trigger initialization. Leave the mock quota manager uninitialized so that + // the callback is not invoked. + host_observers.NotifyUsageChange(params.filter, 7645); + EXPECT_EQ(0, mock_observer.EventCount()); + EXPECT_FALSE(host_observers.is_initialized()); + EXPECT_EQ(NULL, GetPendingEvent(host_observers)); + EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers)); + + // Simulate notifying |host_observers| of a usage change before initialization + // is complete. + const int64 kUsage = 6656; + const int64 kQuota = 99585556; + const int64 kDelta = 327643; + host_observers.NotifyUsageChange(params.filter, kDelta); + EXPECT_EQ(0, mock_observer.EventCount()); + EXPECT_FALSE(host_observers.is_initialized()); + EXPECT_EQ(NULL, GetPendingEvent(host_observers)); + EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers)); + + // Simulate an asynchronous callback from QuotaManager. + quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk); + quota_manager_->InvokeCallback(); + StorageObserver::Event expected_event(params.filter, kUsage + kDelta, kQuota); + EXPECT_EQ(1, mock_observer.EventCount()); + EXPECT_EQ(expected_event, mock_observer.LastEvent()); + EXPECT_TRUE(host_observers.is_initialized()); + EXPECT_EQ(NULL, GetPendingEvent(host_observers)); + EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers)); +} + // Tests for StorageTypeObservers: typedef StorageTestWithManagerBase StorageTypeObserversTest; |