| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 5 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 IDB_TRACE("init"); | 112 IDB_TRACE("init"); |
| 113 if (!data_path.empty()) | 113 if (!data_path.empty()) |
| 114 data_path_ = data_path.Append(kIndexedDBDirectory); | 114 data_path_ = data_path.Append(kIndexedDBDirectory); |
| 115 if (quota_manager_proxy) { | 115 if (quota_manager_proxy) { |
| 116 quota_manager_proxy->RegisterClient(new IndexedDBQuotaClient(this)); | 116 quota_manager_proxy->RegisterClient(new IndexedDBQuotaClient(this)); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 | 119 |
| 120 IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() { | 120 IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() { |
| 121 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 121 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 122 if (!factory_) { | 122 if (!factory_.get()) { |
| 123 // Prime our cache of origins with existing databases so we can | 123 // Prime our cache of origins with existing databases so we can |
| 124 // detect when dbs are newly created. | 124 // detect when dbs are newly created. |
| 125 GetOriginSet(); | 125 GetOriginSet(); |
| 126 factory_ = new IndexedDBFactoryImpl(this); | 126 factory_ = new IndexedDBFactoryImpl(this); |
| 127 } | 127 } |
| 128 return factory_; | 128 return factory_.get(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 std::vector<GURL> IndexedDBContextImpl::GetAllOrigins() { | 131 std::vector<GURL> IndexedDBContextImpl::GetAllOrigins() { |
| 132 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 132 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 133 std::vector<GURL> origins; | 133 std::vector<GURL> origins; |
| 134 std::set<GURL>* origins_set = GetOriginSet(); | 134 std::set<GURL>* origins_set = GetOriginSet(); |
| 135 for (std::set<GURL>::const_iterator iter = origins_set->begin(); | 135 for (std::set<GURL>::const_iterator iter = origins_set->begin(); |
| 136 iter != origins_set->end(); | 136 iter != origins_set->end(); |
| 137 ++iter) { | 137 ++iter) { |
| 138 origins.push_back(*iter); | 138 origins.push_back(*iter); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 info->SetDouble("last_modified", | 182 info->SetDouble("last_modified", |
| 183 GetOriginLastModified(origin_url).ToJsTime()); | 183 GetOriginLastModified(origin_url).ToJsTime()); |
| 184 if (!is_incognito()) | 184 if (!is_incognito()) |
| 185 info->SetString("path", GetFilePath(origin_url).value()); | 185 info->SetString("path", GetFilePath(origin_url).value()); |
| 186 info->SetDouble("connection_count", GetConnectionCount(origin_url)); | 186 info->SetDouble("connection_count", GetConnectionCount(origin_url)); |
| 187 | 187 |
| 188 // This ends up being O(n^2) since we iterate over all open databases | 188 // This ends up being O(n^2) since we iterate over all open databases |
| 189 // to extract just those in the origin, and we're iterating over all | 189 // to extract just those in the origin, and we're iterating over all |
| 190 // origins in the outer loop. | 190 // origins in the outer loop. |
| 191 | 191 |
| 192 if (factory_) { | 192 if (factory_.get()) { |
| 193 std::pair<IndexedDBFactory::OriginDBMapIterator, | 193 std::pair<IndexedDBFactory::OriginDBMapIterator, |
| 194 IndexedDBFactory::OriginDBMapIterator> range = | 194 IndexedDBFactory::OriginDBMapIterator> range = |
| 195 factory_->GetOpenDatabasesForOrigin(origin_url); | 195 factory_->GetOpenDatabasesForOrigin(origin_url); |
| 196 // TODO(jsbell): Sort by name? | 196 // TODO(jsbell): Sort by name? |
| 197 scoped_ptr<base::ListValue> database_list(new base::ListValue()); | 197 scoped_ptr<base::ListValue> database_list(new base::ListValue()); |
| 198 | 198 |
| 199 for (IndexedDBFactory::OriginDBMapIterator it = range.first; | 199 for (IndexedDBFactory::OriginDBMapIterator it = range.first; |
| 200 it != range.second; | 200 it != range.second; |
| 201 ++it) { | 201 ++it) { |
| 202 const IndexedDBDatabase* db = it->second; | 202 const IndexedDBDatabase* db = it->second; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 void IndexedDBContextImpl::ForceClose(const GURL origin_url, | 339 void IndexedDBContextImpl::ForceClose(const GURL origin_url, |
| 340 ForceCloseReason reason) { | 340 ForceCloseReason reason) { |
| 341 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 341 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 342 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Context.ForceCloseReason", | 342 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Context.ForceCloseReason", |
| 343 reason, | 343 reason, |
| 344 FORCE_CLOSE_REASON_MAX); | 344 FORCE_CLOSE_REASON_MAX); |
| 345 | 345 |
| 346 if (data_path_.empty() || !IsInOriginSet(origin_url)) | 346 if (data_path_.empty() || !IsInOriginSet(origin_url)) |
| 347 return; | 347 return; |
| 348 | 348 |
| 349 if (factory_) | 349 if (factory_.get()) |
| 350 factory_->ForceClose(origin_url); | 350 factory_->ForceClose(origin_url); |
| 351 DCHECK_EQ(0UL, GetConnectionCount(origin_url)); | 351 DCHECK_EQ(0UL, GetConnectionCount(origin_url)); |
| 352 } | 352 } |
| 353 | 353 |
| 354 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { | 354 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { |
| 355 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 355 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 356 if (data_path_.empty() || !IsInOriginSet(origin_url)) | 356 if (data_path_.empty() || !IsInOriginSet(origin_url)) |
| 357 return 0; | 357 return 0; |
| 358 | 358 |
| 359 if (!factory_) | 359 if (!factory_.get()) |
| 360 return 0; | 360 return 0; |
| 361 | 361 |
| 362 return factory_->GetConnectionCount(origin_url); | 362 return factory_->GetConnectionCount(origin_url); |
| 363 } | 363 } |
| 364 | 364 |
| 365 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { | 365 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { |
| 366 std::string origin_id = storage::GetIdentifierFromOrigin(origin_url); | 366 std::string origin_id = storage::GetIdentifierFromOrigin(origin_url); |
| 367 return GetIndexedDBFilePath(origin_id); | 367 return GetIndexedDBFilePath(origin_id); |
| 368 } | 368 } |
| 369 | 369 |
| 370 base::FilePath IndexedDBContextImpl::GetFilePathForTesting( | 370 base::FilePath IndexedDBContextImpl::GetFilePathForTesting( |
| 371 const std::string& origin_id) const { | 371 const std::string& origin_id) const { |
| 372 return GetIndexedDBFilePath(origin_id); | 372 return GetIndexedDBFilePath(origin_id); |
| 373 } | 373 } |
| 374 | 374 |
| 375 void IndexedDBContextImpl::SetTaskRunnerForTesting( | 375 void IndexedDBContextImpl::SetTaskRunnerForTesting( |
| 376 base::SequencedTaskRunner* task_runner) { | 376 base::SequencedTaskRunner* task_runner) { |
| 377 DCHECK(!task_runner_); | 377 DCHECK(!task_runner_.get()); |
| 378 task_runner_ = task_runner; | 378 task_runner_ = task_runner; |
| 379 } | 379 } |
| 380 | 380 |
| 381 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, | 381 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, |
| 382 IndexedDBConnection* connection) { | 382 IndexedDBConnection* connection) { |
| 383 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 383 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 384 if (quota_manager_proxy()) { | 384 if (quota_manager_proxy()) { |
| 385 quota_manager_proxy()->NotifyStorageAccessed( | 385 quota_manager_proxy()->NotifyStorageAccessed( |
| 386 storage::QuotaClient::kIndexedDatabase, | 386 storage::QuotaClient::kIndexedDatabase, |
| 387 origin_url, | 387 origin_url, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 398 | 398 |
| 399 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, | 399 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, |
| 400 IndexedDBConnection* connection) { | 400 IndexedDBConnection* connection) { |
| 401 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 401 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
| 402 if (quota_manager_proxy()) { | 402 if (quota_manager_proxy()) { |
| 403 quota_manager_proxy()->NotifyStorageAccessed( | 403 quota_manager_proxy()->NotifyStorageAccessed( |
| 404 storage::QuotaClient::kIndexedDatabase, | 404 storage::QuotaClient::kIndexedDatabase, |
| 405 origin_url, | 405 origin_url, |
| 406 storage::kStorageTypeTemporary); | 406 storage::kStorageTypeTemporary); |
| 407 } | 407 } |
| 408 if (factory_ && factory_->GetConnectionCount(origin_url) == 0) | 408 if (factory_.get() && factory_->GetConnectionCount(origin_url) == 0) |
| 409 QueryDiskAndUpdateQuotaUsage(origin_url); | 409 QueryDiskAndUpdateQuotaUsage(origin_url); |
| 410 } | 410 } |
| 411 | 411 |
| 412 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { | 412 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { |
| 413 DCHECK(!factory_ || factory_->GetConnectionCount(origin_url) > 0); | 413 DCHECK(!factory_.get() || factory_->GetConnectionCount(origin_url) > 0); |
| 414 QueryDiskAndUpdateQuotaUsage(origin_url); | 414 QueryDiskAndUpdateQuotaUsage(origin_url); |
| 415 QueryAvailableQuota(origin_url); | 415 QueryAvailableQuota(origin_url); |
| 416 } | 416 } |
| 417 | 417 |
| 418 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { | 418 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { |
| 419 AddToOriginSet(origin_url); | 419 AddToOriginSet(origin_url); |
| 420 QueryDiskAndUpdateQuotaUsage(origin_url); | 420 QueryDiskAndUpdateQuotaUsage(origin_url); |
| 421 QueryAvailableQuota(origin_url); | 421 QueryAvailableQuota(origin_url); |
| 422 } | 422 } |
| 423 | 423 |
| 424 bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url, | 424 bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url, |
| 425 int64 additional_bytes) { | 425 int64 additional_bytes) { |
| 426 if (space_available_map_.find(origin_url) == space_available_map_.end()) { | 426 if (space_available_map_.find(origin_url) == space_available_map_.end()) { |
| 427 // We haven't heard back from the QuotaManager yet, just let it through. | 427 // We haven't heard back from the QuotaManager yet, just let it through. |
| 428 return false; | 428 return false; |
| 429 } | 429 } |
| 430 bool over_quota = additional_bytes > space_available_map_[origin_url]; | 430 bool over_quota = additional_bytes > space_available_map_[origin_url]; |
| 431 return over_quota; | 431 return over_quota; |
| 432 } | 432 } |
| 433 | 433 |
| 434 bool IndexedDBContextImpl::IsOverQuota(const GURL& origin_url) { | 434 bool IndexedDBContextImpl::IsOverQuota(const GURL& origin_url) { |
| 435 const int kOneAdditionalByte = 1; | 435 const int kOneAdditionalByte = 1; |
| 436 return WouldBeOverQuota(origin_url, kOneAdditionalByte); | 436 return WouldBeOverQuota(origin_url, kOneAdditionalByte); |
| 437 } | 437 } |
| 438 | 438 |
| 439 storage::QuotaManagerProxy* IndexedDBContextImpl::quota_manager_proxy() { | 439 storage::QuotaManagerProxy* IndexedDBContextImpl::quota_manager_proxy() { |
| 440 return quota_manager_proxy_; | 440 return quota_manager_proxy_.get(); |
| 441 } | 441 } |
| 442 | 442 |
| 443 IndexedDBContextImpl::~IndexedDBContextImpl() { | 443 IndexedDBContextImpl::~IndexedDBContextImpl() { |
| 444 if (factory_) { | 444 if (factory_.get()) { |
| 445 TaskRunner()->PostTask( | 445 TaskRunner()->PostTask( |
| 446 FROM_HERE, base::Bind(&IndexedDBFactory::ContextDestroyed, factory_)); | 446 FROM_HERE, base::Bind(&IndexedDBFactory::ContextDestroyed, factory_)); |
| 447 factory_ = NULL; | 447 factory_ = NULL; |
| 448 } | 448 } |
| 449 | 449 |
| 450 if (data_path_.empty()) | 450 if (data_path_.empty()) |
| 451 return; | 451 return; |
| 452 | 452 |
| 453 if (force_keep_session_state_) | 453 if (force_keep_session_state_) |
| 454 return; | 454 return; |
| 455 | 455 |
| 456 bool has_session_only_databases = | 456 bool has_session_only_databases = |
| 457 special_storage_policy_ && | 457 special_storage_policy_.get() && |
| 458 special_storage_policy_->HasSessionOnlyOrigins(); | 458 special_storage_policy_->HasSessionOnlyOrigins(); |
| 459 | 459 |
| 460 // Clearing only session-only databases, and there are none. | 460 // Clearing only session-only databases, and there are none. |
| 461 if (!has_session_only_databases) | 461 if (!has_session_only_databases) |
| 462 return; | 462 return; |
| 463 | 463 |
| 464 TaskRunner()->PostTask( | 464 TaskRunner()->PostTask( |
| 465 FROM_HERE, | 465 FROM_HERE, |
| 466 base::Bind( | 466 base::Bind( |
| 467 &ClearSessionOnlyOrigins, data_path_, special_storage_policy_)); | 467 &ClearSessionOnlyOrigins, data_path_, special_storage_policy_)); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 return origin_set_.get(); | 567 return origin_set_.get(); |
| 568 } | 568 } |
| 569 | 569 |
| 570 void IndexedDBContextImpl::ResetCaches() { | 570 void IndexedDBContextImpl::ResetCaches() { |
| 571 origin_set_.reset(); | 571 origin_set_.reset(); |
| 572 origin_size_map_.clear(); | 572 origin_size_map_.clear(); |
| 573 space_available_map_.clear(); | 573 space_available_map_.clear(); |
| 574 } | 574 } |
| 575 | 575 |
| 576 base::SequencedTaskRunner* IndexedDBContextImpl::TaskRunner() const { | 576 base::SequencedTaskRunner* IndexedDBContextImpl::TaskRunner() const { |
| 577 return task_runner_; | 577 return task_runner_.get(); |
| 578 } | 578 } |
| 579 | 579 |
| 580 } // namespace content | 580 } // namespace content |
| OLD | NEW |