Chromium Code Reviews| 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..c027e85a3eb76e5ec410908e13037868c13322fb 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; |
| @@ -103,7 +106,7 @@ FilePath IndexedDBContext::GetIndexedDBFilePath( |
| void IndexedDBContext::DeleteIndexedDBFile(const FilePath& file_path) { |
|
michaeln
2011/08/04 00:23:27
I don't see any external callers of this method, i
dgrogan
2011/08/04 19:47:50
Done.
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)); |
| // TODO(pastarmovj): Close all database connections that use that file. |
| - file_util::Delete(file_path, false); |
| + file_util::Delete(file_path, true /*recursive*/); |
| } |
| void IndexedDBContext::DeleteIndexedDBForOrigin(const string16& origin_id) { |
| @@ -115,6 +118,17 @@ void IndexedDBContext::DeleteIndexedDBForOrigin(const string16& origin_id) { |
| DeleteIndexedDBFile(GetIndexedDBFilePath(origin_id)); |
| } |
| +// TODO(dgrogan): Once we can delete IndexedDB directories out from underneath |
| +// open webkit instances, merge this and DeleteIndexedDBForOrigin. |
| +void IndexedDBContext::EvictOriginIfNotInUse(const GURL& origin_url) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)); |
| + if (connection_count_.find(origin_url) == connection_count_.end()) { |
| + string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url); |
| + FilePath idb_directory = GetIndexedDBFilePath(origin_id); |
| + DeleteIndexedDBFile(idb_directory); |
| + } |
|
michaeln
2011/08/04 00:23:27
I think a call to quota->NotifyStorageModified(ori
dgrogan
2011/08/04 19:47:50
Good idea.
|
| +} |
| + |
| bool IndexedDBContext::IsUnlimitedStorageGranted( |
| const GURL& origin) const { |
| return special_storage_policy_->IsStorageUnlimited(origin); |
| @@ -137,6 +151,145 @@ void IndexedDBContext::GetAllOriginIdentifiers( |
| } |
| } |
| +int64 IndexedDBContext::InitializeDiskUsage(const GURL& origin_url) { |
| + int64 disk_usage = ReadUsageFromDisk(origin_url); |
| + origin_size_map_[origin_url] = disk_usage; |
| + return disk_usage; |
| +} |
| + |
| +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::ConnectionClosed(const GURL& origin_url) { |
| + 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::NewConnection(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); |
| +} |
| + |
| +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; |
|
michaeln
2011/08/04 00:23:27
nit: could return the comparison result w/o the lo
|
| +} |
| + |
| +bool IndexedDBContext::IsOverQuota(const GURL& origin_url) { |
| + // Can we store an additional byte? |
| + return WouldBeOverQuota(origin_url, 1 /*additional_bytes*/); |
|
michaeln
2011/08/04 00:23:27
nit: instead of comments, consider self-documentin
dgrogan
2011/08/04 19:47:50
Done.
|
| +} |
| + |
| +void IndexedDBContext::TransactionComplete(const GURL& origin_url) { |
| + QueryDiskAndUpdateQuotaUsage(origin_url); |
| + QueryAvailableQuota(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) { |
| + quota_manager_proxy()->NotifyStorageModified( |
| + quota::QuotaClient::kIndexedDatabase, |
| + origin_url, |
| + quota::kStorageTypeTemporary, |
| + difference); |
| + origin_size_map_[origin_url] = current_disk_usage; |
| + } |
| +} |
| + |
| +void IndexedDBContext::GotUpdatedQuota(const GURL& origin_url, int64 usage, |
| + int64 quota) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)); |
| + space_available_map_[origin_url] = quota - usage; |
| +} |
| + |
| +class IndexedDBGetUsageAndQuotaCallback : |
|
michaeln
2011/08/04 00:23:27
can this be in the anon namespace too, or maybe we
dgrogan
2011/08/04 19:47:50
I made it a nested class.
|
| + 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_; |
| +}; |
| + |
| +namespace { |
| + |
| +void RequestQuota( |
|
michaeln
2011/08/04 00:23:27
I think some of this can be simplified by posting
dgrogan
2011/08/04 19:47:50
I got rid of this RequestQuota method by following
|
| + scoped_refptr<quota::QuotaManagerProxy> proxy, const GURL& gurl, |
| + IndexedDBGetUsageAndQuotaCallback* idb_quota_callback) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + if (!proxy->quota_manager()) { |
| + // QuotaManager was deleted on the IO thread just before this RequestQuota |
| + // task was run. |
| + return; |
| + } |
| + proxy->quota_manager()->GetUsageAndQuota( |
| + gurl, |
| + quota::kStorageTypeTemporary, |
| + idb_quota_callback); |
| +} |
| + |
| +} |
| + |
| +void IndexedDBContext::QueryAvailableQuota(const GURL& origin_url) { |
| + IndexedDBGetUsageAndQuotaCallback* callback = |
| + new IndexedDBGetUsageAndQuotaCallback(this, origin_url); |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + NewRunnableFunction(&RequestQuota, |
| + make_scoped_refptr(quota_manager_proxy()), |
| + origin_url, |
| + callback)); |
| +} |
| + |
| quota::QuotaManagerProxy* IndexedDBContext::quota_manager_proxy() { |
| return quota_manager_proxy_; |
| } |