Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Unified Diff: content/browser/in_process_webkit/indexed_db_context.cc

Issue 7470008: Improve IndexedDB's quota support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove NOTREACHED Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/in_process_webkit/indexed_db_context.cc
diff --git a/content/browser/in_process_webkit/indexed_db_context.cc b/content/browser/in_process_webkit/indexed_db_context.cc
index 8e091c1678572dca7c3192b74addfff3e3a338cf..4b9a5d52fa1d6e4b00b7a76f8e5b20dc4dd3bd75 100644
--- a/content/browser/in_process_webkit/indexed_db_context.cc
+++ b/content/browser/in_process_webkit/indexed_db_context.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
+#include "base/task.h"
#include "base/utf_string_conversions.h"
#include "content/browser/browser_thread.h"
#include "content/browser/in_process_webkit/indexed_db_quota_client.h"
@@ -18,10 +19,12 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+#include "webkit/database/database_util.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/special_storage_policy.h"
+using webkit_database::DatabaseUtil;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBFactory;
using WebKit::WebSecurityOrigin;
@@ -56,6 +59,41 @@ const FilePath::CharType IndexedDBContext::kIndexedDBDirectory[] =
const FilePath::CharType IndexedDBContext::kIndexedDBExtension[] =
FILE_PATH_LITERAL(".leveldb");
+class IndexedDBContext::IndexedDBGetUsageAndQuotaCallback :
+ public quota::QuotaManager::GetUsageAndQuotaCallback {
+ public:
+ IndexedDBGetUsageAndQuotaCallback(IndexedDBContext* context,
+ const GURL& origin_url)
+ : context_(context),
+ origin_url_(origin_url) {
+ }
+
+ void Run(quota::QuotaStatusCode status, int64 usage, int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(status == quota::kQuotaStatusOk || status == quota::kQuotaErrorAbort)
+ << "status was " << status;
+ if (status == quota::kQuotaErrorAbort) {
+ // We seem to no longer care to wait around for the answer.
+ return;
+ }
+ BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE,
+ NewRunnableMethod(context_.get(),
+ &IndexedDBContext::GotUpdatedQuota,
+ origin_url_,
+ usage,
+ quota));
+ }
+
+ virtual void RunWithParams(
+ const Tuple3<quota::QuotaStatusCode, int64, int64>& params) {
+ Run(params.a, params.b, params.c);
+ }
+
+ private:
+ scoped_refptr<IndexedDBContext> context_;
+ const GURL origin_url_;
+};
+
IndexedDBContext::IndexedDBContext(
WebKitContext* webkit_context,
quota::SpecialStoragePolicy* special_storage_policy,
@@ -100,19 +138,19 @@ FilePath IndexedDBContext::GetIndexedDBFilePath(
return data_path_.Append(id.append(kIndexedDBExtension));
}
-void IndexedDBContext::DeleteIndexedDBFile(const FilePath& file_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
- // TODO(pastarmovj): Close all database connections that use that file.
- file_util::Delete(file_path, false);
-}
-
-void IndexedDBContext::DeleteIndexedDBForOrigin(const string16& origin_id) {
+// Note: This is not called in response to a UI action in Content Settings. Only
+// extension data deleter and quota manager currently call this.
+void IndexedDBContext::DeleteIndexedDBForOrigin(const GURL& origin_url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
- // TODO(pastarmovj): Remove this check once we are safe to delete any time.
- FilePath idb_file = GetIndexedDBFilePath(origin_id);
- DCHECK_EQ(idb_file.BaseName().value().substr(0, strlen("chrome-extension")),
- FILE_PATH_LITERAL("chrome-extension"));
- DeleteIndexedDBFile(GetIndexedDBFilePath(origin_id));
+ string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ FilePath idb_directory = GetIndexedDBFilePath(origin_id);
+ if (idb_directory.BaseName().value().substr(0, strlen("chrome-extension")) ==
+ FILE_PATH_LITERAL("chrome-extension") ||
+ connection_count_.find(origin_url) == connection_count_.end()) {
+ EnsureDiskUsageCacheInitialized(origin_url);
+ file_util::Delete(idb_directory, true /*recursive*/);
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ }
}
bool IndexedDBContext::IsUnlimitedStorageGranted(
@@ -137,6 +175,114 @@ void IndexedDBContext::GetAllOriginIdentifiers(
}
}
+int64 IndexedDBContext::GetOriginDiskUsage(const GURL& origin_url) {
+ return ResetDiskUsageCache(origin_url);
+}
+
+void IndexedDBContext::ConnectionOpened(const GURL& origin_url) {
+ if (quota_manager_proxy()) {
+ quota_manager_proxy()->NotifyStorageAccessed(
+ quota::QuotaClient::kIndexedDatabase, origin_url,
+ quota::kStorageTypeTemporary);
+ }
+ connection_count_[origin_url]++;
+ QueryAvailableQuota(origin_url);
+ EnsureDiskUsageCacheInitialized(origin_url);
+}
+
+void IndexedDBContext::ConnectionClosed(const GURL& origin_url) {
+ DCHECK(connection_count_[origin_url] > 0);
+ if (quota_manager_proxy()) {
+ quota_manager_proxy()->NotifyStorageAccessed(
+ quota::QuotaClient::kIndexedDatabase, origin_url,
+ quota::kStorageTypeTemporary);
+ }
+ connection_count_[origin_url]--;
+ if (connection_count_[origin_url] == 0) {
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ connection_count_.erase(origin_url);
+ }
+}
+
+void IndexedDBContext::TransactionComplete(const GURL& origin_url) {
+ DCHECK(connection_count_[origin_url] > 0);
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ QueryAvailableQuota(origin_url);
+}
+
+bool IndexedDBContext::WouldBeOverQuota(const GURL& origin_url,
+ int64 additional_bytes) {
+ if (space_available_map_.find(origin_url) == space_available_map_.end()) {
+ // We haven't heard back from the QuotaManager yet, just let it through.
+ return false;
+ }
+ bool over_quota = additional_bytes > space_available_map_[origin_url];
+ return over_quota;
+}
+
+bool IndexedDBContext::IsOverQuota(const GURL& origin_url) {
+ const int kOneAdditionalByte = 1;
+ return WouldBeOverQuota(origin_url, kOneAdditionalByte);
+}
+
quota::QuotaManagerProxy* IndexedDBContext::quota_manager_proxy() {
return quota_manager_proxy_;
}
+
+int64 IndexedDBContext::ReadUsageFromDisk(const GURL& origin_url) const {
+ string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ FilePath file_path = GetIndexedDBFilePath(origin_id);
+ return file_util::ComputeDirectorySize(file_path);
+}
+
+void IndexedDBContext::EnsureDiskUsageCacheInitialized(const GURL& origin_url) {
+ if (origin_size_map_.find(origin_url) == origin_size_map_.end())
+ ResetDiskUsageCache(origin_url);
+}
+
+void IndexedDBContext::QueryDiskAndUpdateQuotaUsage(const GURL& origin_url) {
+ int64 former_disk_usage = origin_size_map_[origin_url];
+ int64 current_disk_usage = ReadUsageFromDisk(origin_url);
+ int64 difference = current_disk_usage - former_disk_usage;
+ if (difference) {
+ origin_size_map_[origin_url] = current_disk_usage;
+ // quota_manager_proxy() is NULL in unit tests.
+ if (quota_manager_proxy())
+ quota_manager_proxy()->NotifyStorageModified(
+ quota::QuotaClient::kIndexedDatabase,
+ origin_url,
+ quota::kStorageTypeTemporary,
+ difference);
+ }
+}
+
+void IndexedDBContext::GotUpdatedQuota(const GURL& origin_url, int64 usage,
+ int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ space_available_map_[origin_url] = quota - usage;
+}
+
+void IndexedDBContext::QueryAvailableQuota(const GURL& origin_url) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ if (quota_manager_proxy())
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &IndexedDBContext::QueryAvailableQuota,
+ origin_url));
+ return;
+ }
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!quota_manager_proxy()->quota_manager())
+ return;
+ IndexedDBGetUsageAndQuotaCallback* callback =
+ new IndexedDBGetUsageAndQuotaCallback(this, origin_url);
+ quota_manager_proxy()->quota_manager()->GetUsageAndQuota(
+ origin_url,
+ quota::kStorageTypeTemporary,
+ callback);
+}
+
+int64 IndexedDBContext::ResetDiskUsageCache(const GURL& origin_url) {
+ origin_size_map_[origin_url] = ReadUsageFromDisk(origin_url);
+ return origin_size_map_[origin_url];
+}
« no previous file with comments | « content/browser/in_process_webkit/indexed_db_context.h ('k') | content/browser/in_process_webkit/indexed_db_dispatcher_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698