summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/profiles/profile.cc10
-rw-r--r--chrome/browser/profiles/profile_impl.cc10
-rw-r--r--chrome/test/testing_profile.cc2
-rw-r--r--webkit/database/database_quota_client.cc218
-rw-r--r--webkit/database/database_quota_client.h81
-rw-r--r--webkit/database/database_quota_client_unittest.cc218
-rw-r--r--webkit/database/database_tracker.cc78
-rw-r--r--webkit/database/database_tracker.h24
-rw-r--r--webkit/database/database_tracker_unittest.cc6
-rw-r--r--webkit/database/webkit_database.gypi3
-rw-r--r--webkit/support/simple_database_system.cc2
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
12 files changed, 629 insertions, 24 deletions
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index bcb812a..20e84ee 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -287,10 +287,7 @@ class OffTheRecordProfileImpl : public Profile,
}
virtual webkit_database::DatabaseTracker* GetDatabaseTracker() {
- if (!db_tracker_.get()) {
- db_tracker_ = new webkit_database::DatabaseTracker(
- GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
- }
+ CreateQuotaManagerAndClients();
return db_tracker_;
}
@@ -699,6 +696,7 @@ class OffTheRecordProfileImpl : public Profile,
void CreateQuotaManagerAndClients() {
if (quota_manager_.get()) {
DCHECK(file_system_context_.get());
+ DCHECK(db_tracker_.get());
return;
}
@@ -718,6 +716,10 @@ class OffTheRecordProfileImpl : public Profile,
GetPath(), IsOffTheRecord(),
GetExtensionSpecialStoragePolicy(),
quota_manager_->proxy());
+ db_tracker_ = new webkit_database::DatabaseTracker(
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy(),
+ quota_manager_->proxy(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}
NotificationRegistrar registrar_;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index ae2a519..e168882 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -727,10 +727,7 @@ ChromeAppCacheService* ProfileImpl::GetAppCacheService() {
}
webkit_database::DatabaseTracker* ProfileImpl::GetDatabaseTracker() {
- if (!db_tracker_) {
- db_tracker_ = new webkit_database::DatabaseTracker(
- GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
- }
+ CreateQuotaManagerAndClients();
return db_tracker_;
}
@@ -1273,6 +1270,7 @@ ExtensionPrefValueMap* ProfileImpl::GetExtensionPrefValueMap() {
void ProfileImpl::CreateQuotaManagerAndClients() {
if (quota_manager_.get()) {
DCHECK(file_system_context_.get());
+ DCHECK(db_tracker_.get());
return;
}
@@ -1292,6 +1290,10 @@ void ProfileImpl::CreateQuotaManagerAndClients() {
GetPath(), IsOffTheRecord(),
GetExtensionSpecialStoragePolicy(),
quota_manager_->proxy());
+ db_tracker_ = new webkit_database::DatabaseTracker(
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy(),
+ quota_manager_->proxy(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}
WebKitContext* ProfileImpl::GetWebKitContext() {
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index 06c08d6..1dd64b4 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -417,7 +417,7 @@ ChromeAppCacheService* TestingProfile::GetAppCacheService() {
webkit_database::DatabaseTracker* TestingProfile::GetDatabaseTracker() {
if (!db_tracker_) {
db_tracker_ = new webkit_database::DatabaseTracker(
- GetPath(), false, GetExtensionSpecialStoragePolicy());
+ GetPath(), false, GetExtensionSpecialStoragePolicy(), NULL, NULL);
}
return db_tracker_;
}
diff --git a/webkit/database/database_quota_client.cc b/webkit/database/database_quota_client.cc
new file mode 100644
index 0000000..4f3da01
--- /dev/null
+++ b/webkit/database/database_quota_client.cc
@@ -0,0 +1,218 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/database/database_quota_client.h"
+
+#include "base/message_loop_proxy.h"
+#include "net/base/net_util.h"
+#include "webkit/database/database_tracker.h"
+#include "webkit/database/database_util.h"
+
+using quota::QuotaClient;
+
+namespace webkit_database {
+
+// Helper tasks ---------------------------------------------------------------
+
+class DatabaseQuotaClient::HelperTask : public quota::QuotaThreadTask {
+ protected:
+ HelperTask(
+ DatabaseQuotaClient* client,
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread)
+ : QuotaThreadTask(client, db_tracker_thread),
+ client_(client), db_tracker_(client->db_tracker_) {
+ }
+
+ DatabaseQuotaClient* client_;
+ scoped_refptr<DatabaseTracker> db_tracker_;
+};
+
+class DatabaseQuotaClient::GetOriginUsageTask : public HelperTask {
+ public:
+ GetOriginUsageTask(
+ DatabaseQuotaClient* client,
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread,
+ const GURL& origin_url)
+ : HelperTask(client, db_tracker_thread),
+ origin_url_(origin_url), usage_(0) {
+ }
+
+ private:
+ virtual void RunOnTargetThread() OVERRIDE {
+ OriginInfo info;
+ if (db_tracker_->GetOriginInfo(
+ DatabaseUtil::GetOriginIdentifier(origin_url_),
+ &info)) {
+ usage_ = info.TotalSize();
+ }
+ }
+ virtual void Completed() OVERRIDE {
+ client_->DidGetOriginUsage(origin_url_, usage_);
+ }
+ GURL origin_url_;
+ int64 usage_;
+};
+
+class DatabaseQuotaClient::GetOriginsTaskBase : public HelperTask {
+ protected:
+ GetOriginsTaskBase(
+ DatabaseQuotaClient* client,
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread)
+ : HelperTask(client, db_tracker_thread) {
+ }
+
+ virtual bool ShouldAddOrigin(const GURL& origin) = 0;
+
+ virtual void RunOnTargetThread() OVERRIDE {
+ std::vector<string16> origin_identifiers;
+ if (db_tracker_->GetAllOriginIdentifiers(&origin_identifiers)) {
+ for (std::vector<string16>::const_iterator iter =
+ origin_identifiers.begin();
+ iter != origin_identifiers.end(); ++iter) {
+ GURL origin = DatabaseUtil::GetOriginFromIdentifier(*iter);
+ if (ShouldAddOrigin(origin))
+ origins_.insert(origin);
+ }
+ }
+ }
+
+ std::set<GURL> origins_;
+};
+
+class DatabaseQuotaClient::GetAllOriginsTask : public GetOriginsTaskBase {
+ public:
+ GetAllOriginsTask(
+ DatabaseQuotaClient* client,
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread)
+ : GetOriginsTaskBase(client, db_tracker_thread) {
+ }
+
+ protected:
+ virtual bool ShouldAddOrigin(const GURL& origin) OVERRIDE {
+ return true;
+ }
+ virtual void Completed() OVERRIDE {
+ client_->DidGetAllOrigins(origins_);
+ }
+};
+
+class DatabaseQuotaClient::GetOriginsForHostTask : public GetOriginsTaskBase {
+ public:
+ GetOriginsForHostTask(
+ DatabaseQuotaClient* client,
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread,
+ const std::string& host)
+ : GetOriginsTaskBase(client, db_tracker_thread),
+ host_(host) {
+ }
+
+ private:
+ virtual bool ShouldAddOrigin(const GURL& origin) OVERRIDE {
+ return host_ == net::GetHostOrSpecFromURL(origin);
+ }
+ virtual void Completed() OVERRIDE {
+ client_->DidGetOriginsForHost(host_, origins_);
+ }
+ std::string host_;
+};
+
+// DatabaseQuotaClient --------------------------------------------------------
+
+DatabaseQuotaClient::DatabaseQuotaClient(
+ base::MessageLoopProxy* db_tracker_thread,
+ DatabaseTracker* db_tracker)
+ : db_tracker_thread_(db_tracker_thread), db_tracker_(db_tracker) {
+}
+
+DatabaseQuotaClient::~DatabaseQuotaClient() {
+}
+
+QuotaClient::ID DatabaseQuotaClient::id() const {
+ return kDatabase;
+}
+
+void DatabaseQuotaClient::OnQuotaManagerDestroyed() {
+ delete this;
+}
+
+void DatabaseQuotaClient::GetOriginUsage(
+ const GURL& origin_url,
+ quota::StorageType type,
+ GetUsageCallback* callback_ptr) {
+ DCHECK(callback_ptr);
+ DCHECK(db_tracker_.get());
+ scoped_ptr<GetUsageCallback> callback(callback_ptr);
+
+ // All databases are in the temp namespace for now.
+ if (type != quota::kStorageTypeTemporary) {
+ callback->Run(0);
+ return;
+ }
+
+ if (usage_for_origin_callbacks_.Add(origin_url, callback.release())) {
+ scoped_refptr<GetOriginUsageTask> task(
+ new GetOriginUsageTask(this, db_tracker_thread_, origin_url));
+ task->Start();
+ }
+}
+
+void DatabaseQuotaClient::GetOriginsForType(
+ quota::StorageType type,
+ GetOriginsCallback* callback_ptr) {
+ DCHECK(callback_ptr);
+ DCHECK(db_tracker_.get());
+ scoped_ptr<GetOriginsCallback> callback(callback_ptr);
+
+ // All databases are in the temp namespace for now.
+ if (type != quota::kStorageTypeTemporary) {
+ callback->Run(std::set<GURL>());
+ return;
+ }
+
+ if (origins_for_type_callbacks_.Add(callback.release())) {
+ scoped_refptr<GetAllOriginsTask> task(
+ new GetAllOriginsTask(this, db_tracker_thread_));
+ task->Start();
+ }
+}
+
+void DatabaseQuotaClient::GetOriginsForHost(
+ quota::StorageType type,
+ const std::string& host,
+ GetOriginsCallback* callback_ptr) {
+ DCHECK(callback_ptr);
+ DCHECK(db_tracker_.get());
+ scoped_ptr<GetOriginsCallback> callback(callback_ptr);
+
+ // All databases are in the temp namespace for now.
+ if (type != quota::kStorageTypeTemporary) {
+ callback->Run(std::set<GURL>());
+ return;
+ }
+
+ if (origins_for_host_callbacks_.Add(host, callback.release())) {
+ scoped_refptr<GetOriginsForHostTask> task(
+ new GetOriginsForHostTask(this, db_tracker_thread_, host));
+ task->Start();
+ }
+}
+
+void DatabaseQuotaClient::DidGetOriginUsage(
+ const GURL& origin_url, int64 usage) {
+ DCHECK(usage_for_origin_callbacks_.HasCallbacks(origin_url));
+ usage_for_origin_callbacks_.Run(origin_url, usage);
+}
+
+void DatabaseQuotaClient::DidGetAllOrigins(const std::set<GURL>& origins) {
+ DCHECK(origins_for_type_callbacks_.HasCallbacks());
+ origins_for_type_callbacks_.Run(origins);
+}
+
+void DatabaseQuotaClient::DidGetOriginsForHost(
+ const std::string& host, const std::set<GURL>& origins) {
+ DCHECK(origins_for_host_callbacks_.HasCallbacks(host));
+ origins_for_host_callbacks_.Run(host, origins);
+}
+
+} // namespace webkit_database
diff --git a/webkit/database/database_quota_client.h b/webkit/database/database_quota_client.h
new file mode 100644
index 0000000..5733e57
--- /dev/null
+++ b/webkit/database/database_quota_client.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_DATABASE_DATABASE_QUOTA_CLIENT_H_
+#define WEBKIT_DATABASE_DATABASE_QUOTA_CLIENT_H_
+
+#include <set>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/message_loop_proxy.h"
+#include "webkit/quota/quota_client.h"
+#include "webkit/quota/quota_task.h"
+#include "webkit/quota/quota_types.h"
+
+namespace webkit_database {
+
+class DatabaseTracker;
+
+// A QuotaClient implementation to integrate WebSQLDatabases
+// with the quota management system. This interface is used
+// on the IO thread by the quota manager.
+class DatabaseQuotaClient : public quota::QuotaClient,
+ public quota::QuotaTaskObserver {
+ public:
+ DatabaseQuotaClient(
+ base::MessageLoopProxy* tracker_thread,
+ DatabaseTracker* tracker);
+ virtual ~DatabaseQuotaClient();
+
+ // QuotaClient method overrides
+ virtual ID id() const OVERRIDE;
+ virtual void OnQuotaManagerDestroyed();
+ virtual void GetOriginUsage(const GURL& origin_url,
+ quota::StorageType type,
+ GetUsageCallback* callback) OVERRIDE;
+ virtual void GetOriginsForType(quota::StorageType type,
+ GetOriginsCallback* callback) OVERRIDE;
+ virtual void GetOriginsForHost(quota::StorageType type,
+ const std::string& host,
+ GetOriginsCallback* callback) OVERRIDE;
+ private:
+ class HelperTask;
+ class GetOriginUsageTask;
+ class GetOriginsTaskBase;
+ class GetAllOriginsTask;
+ class GetOriginsForHostTask;
+
+ typedef quota::CallbackQueueMap1
+ <GetUsageCallback*,
+ GURL, // origin
+ int64
+ > UsageForOriginCallbackMap;
+ typedef quota::CallbackQueue1
+ <GetOriginsCallback*,
+ const std::set<GURL>&
+ > OriginsForTypeCallbackQueue;
+ typedef quota::CallbackQueueMap1
+ <GetOriginsCallback*,
+ std::string, // host
+ const std::set<GURL>&
+ > OriginsForHostCallbackMap;
+
+ void DidGetOriginUsage(const GURL& origin_url, int64 usage);
+ void DidGetAllOrigins(const std::set<GURL>& origins);
+ void DidGetOriginsForHost(
+ const std::string& host, const std::set<GURL>& origins);
+
+ scoped_refptr<base::MessageLoopProxy> db_tracker_thread_;
+ scoped_refptr<DatabaseTracker> db_tracker_; // only used on its thread
+ UsageForOriginCallbackMap usage_for_origin_callbacks_;
+ OriginsForTypeCallbackQueue origins_for_type_callbacks_;
+ OriginsForHostCallbackMap origins_for_host_callbacks_;
+
+ DISALLOW_COPY_AND_ASSIGN(DatabaseQuotaClient);
+};
+
+} // namespace webkit_database
+
+#endif // WEBKIT_DATABASE_DATABASE_QUOTA_CLIENT_H_
diff --git a/webkit/database/database_quota_client_unittest.cc b/webkit/database/database_quota_client_unittest.cc
new file mode 100644
index 0000000..38e3742
--- /dev/null
+++ b/webkit/database/database_quota_client_unittest.cc
@@ -0,0 +1,218 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <map>
+
+#include "base/file_path.h"
+#include "base/memory/scoped_callback_factory.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/database/database_quota_client.h"
+#include "webkit/database/database_tracker.h"
+#include "webkit/database/database_util.h"
+
+namespace webkit_database {
+
+// Declared to shorten the line lengths.
+static const quota::StorageType kTemp = quota::kStorageTypeTemporary;
+static const quota::StorageType kPerm = quota::kStorageTypePersistent;
+
+// Mock tracker class the mocks up those methods of the tracker
+// that are used by the QuotaClient.
+class MockDatabaseTracker : public DatabaseTracker {
+ public:
+ MockDatabaseTracker()
+ : DatabaseTracker(FilePath(), false, NULL, NULL, NULL) {}
+
+ virtual ~MockDatabaseTracker() {}
+
+ virtual bool GetOriginInfo(
+ const string16& origin_identifier,
+ OriginInfo* info) OVERRIDE {
+ std::map<GURL, MockOriginInfo>::const_iterator found =
+ mock_origin_infos_.find(
+ DatabaseUtil::GetOriginFromIdentifier(origin_identifier));
+ if (found == mock_origin_infos_.end())
+ return false;
+ *info = OriginInfo(found->second);
+ return true;
+ }
+
+ virtual bool GetAllOriginIdentifiers(
+ std::vector<string16>* origins_identifiers) OVERRIDE {
+ std::map<GURL, MockOriginInfo>::const_iterator iter;
+ for (iter = mock_origin_infos_.begin();
+ iter != mock_origin_infos_.end();
+ ++iter) {
+ origins_identifiers->push_back(iter->second.GetOrigin());
+ }
+ return true;
+ }
+
+ virtual bool GetAllOriginsInfo(
+ std::vector<OriginInfo>* origins_info) OVERRIDE {
+ std::map<GURL, MockOriginInfo>::const_iterator iter;
+ for (iter = mock_origin_infos_.begin();
+ iter != mock_origin_infos_.end();
+ ++iter) {
+ origins_info->push_back(OriginInfo(iter->second));
+ }
+ return true;
+ }
+
+ void AddMockDatabase(const GURL& origin, const char* name, int size) {
+ MockOriginInfo& info = mock_origin_infos_[origin];
+ info.set_origin(DatabaseUtil::GetOriginIdentifier(origin));
+ info.AddMockDatabase(ASCIIToUTF16(name), size);
+ }
+
+ private:
+ class MockOriginInfo : public OriginInfo {
+ public:
+ void set_origin(const string16& origin_id) {
+ origin_ = origin_id;
+ }
+
+ void AddMockDatabase(const string16& name, int size) {
+ EXPECT_TRUE(database_info_.find(name) == database_info_.end());
+ database_info_[name].first = size;
+ total_size_ += size;
+ }
+ };
+
+ std::map<GURL, MockOriginInfo> mock_origin_infos_;
+};
+
+
+// Base class for our test fixtures.
+class DatabaseQuotaClientTest : public testing::Test {
+ public:
+ const GURL kOriginA;
+ const GURL kOriginB;
+ const GURL kOriginOther;
+
+ DatabaseQuotaClientTest()
+ : kOriginA("http://host"),
+ kOriginB("http://host:8000"),
+ kOriginOther("http://other"),
+ usage_(0),
+ mock_tracker_(new MockDatabaseTracker),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ }
+
+ int64 GetOriginUsage(
+ quota::QuotaClient* client,
+ const GURL& origin,
+ quota::StorageType type) {
+ usage_ = 0;
+ client->GetOriginUsage(origin, type,
+ callback_factory_.NewCallback(
+ &DatabaseQuotaClientTest::OnGetOriginUsageComplete));
+ MessageLoop::current()->RunAllPending();
+ return usage_;
+ }
+
+ const std::set<GURL>& GetOriginsForType(
+ quota::QuotaClient* client,
+ quota::StorageType type) {
+ origins_.clear();
+ client->GetOriginsForType(type,
+ callback_factory_.NewCallback(
+ &DatabaseQuotaClientTest::OnGetOriginsComplete));
+ MessageLoop::current()->RunAllPending();
+ return origins_;
+ }
+
+ const std::set<GURL>& GetOriginsForHost(
+ quota::QuotaClient* client,
+ quota::StorageType type,
+ const std::string& host) {
+ origins_.clear();
+ client->GetOriginsForHost(type, host,
+ callback_factory_.NewCallback(
+ &DatabaseQuotaClientTest::OnGetOriginsComplete));
+ MessageLoop::current()->RunAllPending();
+ return origins_;
+ }
+
+ MockDatabaseTracker* mock_tracker() { return mock_tracker_.get(); }
+
+
+ private:
+ void OnGetOriginUsageComplete(int64 usage) {
+ usage_ = usage;
+ }
+
+ void OnGetOriginsComplete(const std::set<GURL>& origins) {
+ origins_ = origins;
+ }
+
+ int64 usage_;
+ std::set<GURL> origins_;
+ scoped_refptr<MockDatabaseTracker> mock_tracker_;
+ base::ScopedCallbackFactory<DatabaseQuotaClientTest> callback_factory_;
+};
+
+
+TEST_F(DatabaseQuotaClientTest, GetOriginUsage) {
+ DatabaseQuotaClient client(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ mock_tracker());
+
+ EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kTemp));
+ EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
+
+ mock_tracker()->AddMockDatabase(kOriginA, "fooDB", 1000);
+ EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
+ EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
+
+ EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kPerm));
+ EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kTemp));
+}
+
+TEST_F(DatabaseQuotaClientTest, GetOriginsForHost) {
+ DatabaseQuotaClient client(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ mock_tracker());
+
+ EXPECT_EQ(kOriginA.host(), kOriginB.host());
+ EXPECT_NE(kOriginA.host(), kOriginOther.host());
+
+ std::set<GURL> origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
+ EXPECT_TRUE(origins.empty());
+
+ mock_tracker()->AddMockDatabase(kOriginA, "fooDB", 1000);
+ origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
+ EXPECT_EQ(origins.size(), 1ul);
+ EXPECT_TRUE(origins.find(kOriginA) != origins.end());
+
+ mock_tracker()->AddMockDatabase(kOriginB, "barDB", 1000);
+ origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
+ EXPECT_EQ(origins.size(), 2ul);
+ EXPECT_TRUE(origins.find(kOriginA) != origins.end());
+ EXPECT_TRUE(origins.find(kOriginB) != origins.end());
+
+ EXPECT_TRUE(GetOriginsForHost(&client, kPerm, kOriginA.host()).empty());
+ EXPECT_TRUE(GetOriginsForHost(&client, kTemp, kOriginOther.host()).empty());
+}
+
+TEST_F(DatabaseQuotaClientTest, GetOriginsForType) {
+ DatabaseQuotaClient client(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ mock_tracker());
+
+ EXPECT_TRUE(GetOriginsForType(&client, kTemp).empty());
+ EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
+
+ mock_tracker()->AddMockDatabase(kOriginA, "fooDB", 1000);
+ std::set<GURL> origins = GetOriginsForType(&client, kTemp);
+ EXPECT_EQ(origins.size(), 1ul);
+ EXPECT_TRUE(origins.find(kOriginA) != origins.end());
+
+ EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
+}
+
+} // namespace webkit_database
diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc
index 5911ad2..1dc29db 100644
--- a/webkit/database/database_tracker.cc
+++ b/webkit/database/database_tracker.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,12 +14,15 @@
#include "app/sql/transaction.h"
#include "base/basictypes.h"
#include "base/file_util.h"
+#include "base/message_loop_proxy.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_errors.h"
+#include "webkit/database/database_quota_client.h"
#include "webkit/database/database_util.h"
#include "webkit/database/databases_table.h"
#include "webkit/database/quota_table.h"
+#include "webkit/quota/quota_manager.h"
#include "webkit/quota/special_storage_policy.h"
namespace {
@@ -47,6 +50,10 @@ static const int kCurrentVersion = 2;
static const int kCompatibleVersion = 1;
static const char* kExtensionOriginIdentifierPrefix = "chrome-extension_";
+OriginInfo::OriginInfo()
+ : total_size_(0),
+ quota_(0) {}
+
OriginInfo::OriginInfo(const OriginInfo& origin_info)
: origin_(origin_info.origin_),
total_size_(origin_info.total_size_),
@@ -83,7 +90,9 @@ OriginInfo::OriginInfo(const string16& origin, int64 total_size, int64 quota)
DatabaseTracker::DatabaseTracker(
const FilePath& profile_path,
bool is_incognito,
- quota::SpecialStoragePolicy* special_storage_policy)
+ quota::SpecialStoragePolicy* special_storage_policy,
+ quota::QuotaManagerProxy* quota_manager_proxy,
+ base::MessageLoopProxy* db_tracker_thread)
: is_initialized_(false),
is_incognito_(is_incognito),
shutting_down_(false),
@@ -96,7 +105,12 @@ DatabaseTracker::DatabaseTracker(
meta_table_(NULL),
default_quota_(5 * 1024 * 1024),
special_storage_policy_(special_storage_policy),
+ quota_manager_proxy_(quota_manager_proxy),
incognito_origin_directories_generator_(0) {
+ if (quota_manager_proxy) {
+ quota_manager_proxy->RegisterClient(
+ new DatabaseQuotaClient(db_tracker_thread, this));
+ }
}
DatabaseTracker::~DatabaseTracker() {
@@ -140,6 +154,17 @@ void DatabaseTracker::DatabaseModified(const string16& origin_identifier,
int64 space_available = GetOriginSpaceAvailable(origin_identifier);
FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged(
origin_identifier, database_name, updated_db_size, space_available));
+
+ if (quota_manager_proxy_) {
+ // TODO(michaeln): notify the quota manager
+ // CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier);
+ // if (origin_info)
+ // quota_manager_proxy_->NotifyStorageConsumed(
+ // quota::QuotaClient::kDatabase,
+ // DatabaseUtil::GetOriginFromIdentifier(origin_identifier),
+ // quota::kStorageTypeTemporary,
+ // origin_info->TotalSize());
+ }
}
void DatabaseTracker::DatabaseClosed(const string16& origin_identifier,
@@ -259,14 +284,31 @@ FilePath DatabaseTracker::GetFullDBFilePath(
UTF16ToWide(GetOriginDirectory(origin_identifier)))).Append(file_name);
}
+bool DatabaseTracker::GetOriginInfo(const string16& origin_identifier,
+ OriginInfo* info) {
+ DCHECK(info);
+ CachedOriginInfo* cached_info = GetCachedOriginInfo(origin_identifier);
+ if (!cached_info)
+ return false;
+ *info = OriginInfo(*cached_info);
+ return true;
+}
+
+bool DatabaseTracker::GetAllOriginIdentifiers(
+ std::vector<string16>* origin_identifiers) {
+ DCHECK(origin_identifiers);
+ DCHECK(origin_identifiers->empty());
+ if (!LazyInit())
+ return false;
+ return databases_table_->GetAllOrigins(origin_identifiers);
+}
+
bool DatabaseTracker::GetAllOriginsInfo(std::vector<OriginInfo>* origins_info) {
DCHECK(origins_info);
DCHECK(origins_info->empty());
- if (!LazyInit())
- return false;
std::vector<string16> origins;
- if (!databases_table_->GetAllOrigins(&origins))
+ if (!GetAllOriginIdentifiers(&origins))
return false;
for (std::vector<string16>::const_iterator it = origins.begin();
@@ -314,11 +356,21 @@ bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier,
databases_table_->DeleteDatabaseDetails(origin_identifier, database_name);
origins_info_map_.erase(origin_identifier);
- // Try to delete the origin in case this was the last database.
std::vector<DatabaseDetails> details;
if (databases_table_->GetAllDatabaseDetailsForOrigin(
- origin_identifier, &details) && details.empty())
+ origin_identifier, &details) && details.empty()) {
+ // Try to delete the origin in case this was the last database.
DeleteOrigin(origin_identifier);
+ } else if (quota_manager_proxy_) {
+ // TODO(michaeln): notify the quota manager
+ // CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier);
+ // if (origin_info)
+ // quota_manager_proxy_->NotifyStorageConsumed(
+ // quota::QuotaClient::kDatabase,
+ // DatabaseUtil::GetOriginFromIdentifier(origin_identifier),
+ // quota::kStorageTypeTemporary,
+ // origin_info->TotalSize());
+ }
return true;
}
@@ -340,6 +392,16 @@ bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) {
return false;
databases_table_->DeleteOrigin(origin_identifier);
+
+ if (quota_manager_proxy_) {
+ // TODO(michaeln): notify the quota manager
+ // quota_manager_proxy_->NotifyStorageConsumed(
+ // quota::QuotaClient::kDatabase,
+ // DatabaseUtil::GetOriginFromIdentifier(origin_identifier),
+ // quota::kStorageTypeTemporary,
+ // 0);
+ }
+
return true;
}
@@ -488,6 +550,7 @@ int64 DatabaseTracker::GetDBFileSize(const string16& origin_identifier,
int64 DatabaseTracker::GetOriginSpaceAvailable(
const string16& origin_identifier) {
+ // TODO(michaeln): Come up with a value according to the the QuotaMgr.
CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier);
if (!origin_info)
return 0;
@@ -687,6 +750,7 @@ void DatabaseTracker::DeleteIncognitoDBDirectory() {
// static
void DatabaseTracker::ClearLocalState(const FilePath& profile_path) {
+ // TODO(michaeln): use SpecialStoragePolicy instead of kExtensionOriginPrefix
FilePath db_dir = profile_path.Append(FilePath(kDatabaseDirectoryName));
FilePath db_tracker = db_dir.Append(FilePath(kTrackerDatabaseFileName));
if (file_util::DirectoryExists(db_dir) &&
diff --git a/webkit/database/database_tracker.h b/webkit/database/database_tracker.h
index 69130a5..2246a13 100644
--- a/webkit/database/database_tracker.h
+++ b/webkit/database/database_tracker.h
@@ -20,12 +20,17 @@
#include "net/base/completion_callback.h"
#include "webkit/database/database_connections.h"
+namespace base {
+class MessageLoopProxy;
+}
+
namespace sql {
class Connection;
class MetaTable;
}
namespace quota {
+class QuotaManagerProxy;
class SpecialStoragePolicy;
}
@@ -40,6 +45,7 @@ class QuotaTable;
// This class is used to store information about all databases in an origin.
class OriginInfo {
public:
+ OriginInfo();
OriginInfo(const OriginInfo& origin_info);
~OriginInfo();
@@ -88,7 +94,9 @@ class DatabaseTracker
};
DatabaseTracker(const FilePath& profile_path, bool is_incognito,
- quota::SpecialStoragePolicy* special_storage_policy);
+ quota::SpecialStoragePolicy* special_storage_policy,
+ quota::QuotaManagerProxy* quota_manager_proxy,
+ base::MessageLoopProxy* db_tracker_thread);
void DatabaseOpened(const string16& origin_identifier,
const string16& database_name,
@@ -111,9 +119,12 @@ class DatabaseTracker
FilePath GetFullDBFilePath(const string16& origin_identifier,
const string16& database_name);
- bool GetAllOriginsInfo(std::vector<OriginInfo>* origins_info);
- void SetOriginQuota(const string16& origin_identifier, int64 new_quota);
+ // virtual for unittesting only
+ virtual bool GetOriginInfo(const string16& origin_id, OriginInfo* info);
+ virtual bool GetAllOriginIdentifiers(std::vector<string16>* origin_ids);
+ virtual bool GetAllOriginsInfo(std::vector<OriginInfo>* origins_info);
+ void SetOriginQuota(const string16& origin_identifier, int64 new_quota);
int64 GetDefaultQuota() { return default_quota_; }
// Sets the default quota for all origins. Should be used in tests only.
void SetDefaultQuota(int64 quota);
@@ -158,8 +169,8 @@ class DatabaseTracker
static void ClearLocalState(const FilePath& profile_path);
private:
- // Need this here to allow RefCountedThreadSafe to call ~DatabaseTracker().
friend class base::RefCountedThreadSafe<DatabaseTracker>;
+ friend class MockDatabaseTracker; // for testing
typedef std::map<string16, std::set<string16> > DatabaseSet;
typedef std::map<net::CompletionCallback*, DatabaseSet> PendingCompletionMap;
@@ -185,7 +196,8 @@ class DatabaseTracker
}
};
- ~DatabaseTracker();
+ // virtual for unittesting only
+ virtual ~DatabaseTracker();
bool DeleteClosedDatabase(const string16& origin_identifier,
const string16& database_name);
@@ -243,6 +255,8 @@ class DatabaseTracker
// Apps and Extensions can have special rights.
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
+ scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
+
// When in incognito mode, store a DELETE_ON_CLOSE handle to each
// main DB and journal file that was accessed. When the incognito profile
// goes away (or when the browser crashes), all these handles will be
diff --git a/webkit/database/database_tracker_unittest.cc b/webkit/database/database_tracker_unittest.cc
index 4ba3a54..66469bf 100644
--- a/webkit/database/database_tracker_unittest.cc
+++ b/webkit/database/database_tracker_unittest.cc
@@ -106,7 +106,8 @@ class DatabaseTracker_TestHelper_Test {
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), incognito_mode,
- new TestSpecialStoragePolicy));
+ new TestSpecialStoragePolicy,
+ NULL, NULL));
// Create and open three databases.
int64 database_size = 0;
@@ -209,7 +210,8 @@ class DatabaseTracker_TestHelper_Test {
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), incognito_mode,
- new TestSpecialStoragePolicy));
+ new TestSpecialStoragePolicy,
+ NULL, NULL));
// Add two observers.
TestObserver observer1;
diff --git a/webkit/database/webkit_database.gypi b/webkit/database/webkit_database.gypi
index 83ecf6b..11c30f5 100644
--- a/webkit/database/webkit_database.gypi
+++ b/webkit/database/webkit_database.gypi
@@ -12,12 +12,15 @@
'<(DEPTH)/app/app.gyp:app_base',
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/third_party/sqlite/sqlite.gyp:sqlite',
+ '<(DEPTH)/webkit/support/webkit_support.gyp:quota',
],
'sources': [
'databases_table.cc',
'databases_table.h',
'database_connections.cc',
'database_connections.h',
+ 'database_quota_client.cc',
+ 'database_quota_client.h',
'database_tracker.cc',
'database_tracker.h',
'database_util.cc',
diff --git a/webkit/support/simple_database_system.cc b/webkit/support/simple_database_system.cc
index 62bd03e..a2f37ad 100644
--- a/webkit/support/simple_database_system.cc
+++ b/webkit/support/simple_database_system.cc
@@ -34,7 +34,7 @@ SimpleDatabaseSystem::SimpleDatabaseSystem()
DCHECK(!instance_);
instance_ = this;
CHECK(temp_dir_.CreateUniqueTempDir());
- db_tracker_ = new DatabaseTracker(temp_dir_.path(), false, NULL);
+ db_tracker_ = new DatabaseTracker(temp_dir_.path(), false, NULL, NULL, NULL);
db_tracker_->AddObserver(this);
db_thread_.Start();
db_thread_proxy_ = db_thread_.message_loop_proxy();
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 699901e..d289200 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -372,6 +372,7 @@
'../../blob/blob_url_request_job_unittest.cc',
'../../blob/deletable_file_reference_unittest.cc',
'../../database/database_connections_unittest.cc',
+ '../../database/database_quota_client_unittest.cc',
'../../database/databases_table_unittest.cc',
'../../database/database_tracker_unittest.cc',
'../../database/database_util_unittest.cc',