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 |