summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authortmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-05 15:23:08 +0000
committertmdiep@chromium.org <tmdiep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-05 15:23:08 +0000
commit583f96cbe459b514f3f7df9d9bf7c1d62d6a327f (patch)
tree783fe1fd26eeeec4c52f534f3a7066b0d6aca81d /webkit
parente2b132080b7a13fd9f9a740a1aa15c502857ab98 (diff)
downloadchromium_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.cc14
-rw-r--r--webkit/browser/quota/storage_monitor.h1
-rw-r--r--webkit/browser/quota/storage_monitor_unittest.cc56
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;