| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 special_storage_policy_(special_storage_policy), | 115 special_storage_policy_(special_storage_policy), |
| 116 quota_manager_proxy_(quota_manager_proxy), | 116 quota_manager_proxy_(quota_manager_proxy), |
| 117 task_runner_(task_runner) { | 117 task_runner_(task_runner) { |
| 118 IDB_TRACE("init"); | 118 IDB_TRACE("init"); |
| 119 if (!data_path.empty()) | 119 if (!data_path.empty()) |
| 120 data_path_ = data_path.Append(kIndexedDBDirectory); | 120 data_path_ = data_path.Append(kIndexedDBDirectory); |
| 121 quota_manager_proxy->RegisterClient(new IndexedDBQuotaClient(this)); | 121 quota_manager_proxy->RegisterClient(new IndexedDBQuotaClient(this)); |
| 122 } | 122 } |
| 123 | 123 |
| 124 IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() { | 124 IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() { |
| 125 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 125 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 126 if (!factory_.get()) { | 126 if (!factory_.get()) { |
| 127 // Prime our cache of origins with existing databases so we can | 127 // Prime our cache of origins with existing databases so we can |
| 128 // detect when dbs are newly created. | 128 // detect when dbs are newly created. |
| 129 GetOriginSet(); | 129 GetOriginSet(); |
| 130 factory_ = new IndexedDBFactoryImpl(this); | 130 factory_ = new IndexedDBFactoryImpl(this); |
| 131 } | 131 } |
| 132 return factory_.get(); | 132 return factory_.get(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 std::vector<Origin> IndexedDBContextImpl::GetAllOrigins() { | 135 std::vector<Origin> IndexedDBContextImpl::GetAllOrigins() { |
| 136 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 136 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 137 std::set<Origin>* origins_set = GetOriginSet(); | 137 std::set<Origin>* origins_set = GetOriginSet(); |
| 138 return std::vector<Origin>(origins_set->begin(), origins_set->end()); | 138 return std::vector<Origin>(origins_set->begin(), origins_set->end()); |
| 139 } | 139 } |
| 140 | 140 |
| 141 bool IndexedDBContextImpl::HasOrigin(const Origin& origin) { | 141 bool IndexedDBContextImpl::HasOrigin(const Origin& origin) { |
| 142 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 142 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 143 std::set<Origin>* set = GetOriginSet(); | 143 std::set<Origin>* set = GetOriginSet(); |
| 144 return set->find(origin) != set->end(); | 144 return set->find(origin) != set->end(); |
| 145 } | 145 } |
| 146 | 146 |
| 147 std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() { | 147 std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() { |
| 148 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 148 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 149 std::vector<Origin> origins = GetAllOrigins(); | 149 std::vector<Origin> origins = GetAllOrigins(); |
| 150 std::vector<IndexedDBInfo> result; | 150 std::vector<IndexedDBInfo> result; |
| 151 for (const auto& origin : origins) { | 151 for (const auto& origin : origins) { |
| 152 size_t connection_count = GetConnectionCount(origin); | 152 size_t connection_count = GetConnectionCount(origin); |
| 153 result.push_back(IndexedDBInfo(origin.GetURL(), GetOriginDiskUsage(origin), | 153 result.push_back(IndexedDBInfo(origin.GetURL(), GetOriginDiskUsage(origin), |
| 154 GetOriginLastModified(origin), | 154 GetOriginLastModified(origin), |
| 155 connection_count)); | 155 connection_count)); |
| 156 } | 156 } |
| 157 return result; | 157 return result; |
| 158 } | 158 } |
| 159 | 159 |
| 160 static bool HostNameComparator(const Origin& i, const Origin& j) { | 160 static bool HostNameComparator(const Origin& i, const Origin& j) { |
| 161 return i.host() < j.host(); | 161 return i.host() < j.host(); |
| 162 } | 162 } |
| 163 | 163 |
| 164 base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() { | 164 base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() { |
| 165 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 165 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 166 std::vector<Origin> origins = GetAllOrigins(); | 166 std::vector<Origin> origins = GetAllOrigins(); |
| 167 | 167 |
| 168 std::sort(origins.begin(), origins.end(), HostNameComparator); | 168 std::sort(origins.begin(), origins.end(), HostNameComparator); |
| 169 | 169 |
| 170 std::unique_ptr<base::ListValue> list(base::MakeUnique<base::ListValue>()); | 170 std::unique_ptr<base::ListValue> list(base::MakeUnique<base::ListValue>()); |
| 171 for (const auto& origin : origins) { | 171 for (const auto& origin : origins) { |
| 172 std::unique_ptr<base::DictionaryValue> info( | 172 std::unique_ptr<base::DictionaryValue> info( |
| 173 base::MakeUnique<base::DictionaryValue>()); | 173 base::MakeUnique<base::DictionaryValue>()); |
| 174 info->SetString("url", origin.Serialize()); | 174 info->SetString("url", origin.Serialize()); |
| 175 info->SetString("size", ui::FormatBytes(GetOriginDiskUsage(origin))); | 175 info->SetString("size", ui::FormatBytes(GetOriginDiskUsage(origin))); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 } | 269 } |
| 270 info->Set("databases", database_list.release()); | 270 info->Set("databases", database_list.release()); |
| 271 } | 271 } |
| 272 | 272 |
| 273 list->Append(std::move(info)); | 273 list->Append(std::move(info)); |
| 274 } | 274 } |
| 275 return list.release(); | 275 return list.release(); |
| 276 } | 276 } |
| 277 | 277 |
| 278 int IndexedDBContextImpl::GetOriginBlobFileCount(const Origin& origin) { | 278 int IndexedDBContextImpl::GetOriginBlobFileCount(const Origin& origin) { |
| 279 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 279 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 280 int count = 0; | 280 int count = 0; |
| 281 base::FileEnumerator file_enumerator(GetBlobStorePath(origin), true, | 281 base::FileEnumerator file_enumerator(GetBlobStorePath(origin), true, |
| 282 base::FileEnumerator::FILES); | 282 base::FileEnumerator::FILES); |
| 283 for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty(); | 283 for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty(); |
| 284 file_path = file_enumerator.Next()) { | 284 file_path = file_enumerator.Next()) { |
| 285 count++; | 285 count++; |
| 286 } | 286 } |
| 287 return count; | 287 return count; |
| 288 } | 288 } |
| 289 | 289 |
| 290 // TODO(jsbell): Update callers to use url::Origin overload and remove. | 290 // TODO(jsbell): Update callers to use url::Origin overload and remove. |
| 291 int64_t IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) { | 291 int64_t IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) { |
| 292 return GetOriginDiskUsage(Origin(origin_url)); | 292 return GetOriginDiskUsage(Origin(origin_url)); |
| 293 } | 293 } |
| 294 | 294 |
| 295 int64_t IndexedDBContextImpl::GetOriginDiskUsage(const Origin& origin) { | 295 int64_t IndexedDBContextImpl::GetOriginDiskUsage(const Origin& origin) { |
| 296 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 296 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 297 if (data_path_.empty() || !HasOrigin(origin)) | 297 if (data_path_.empty() || !HasOrigin(origin)) |
| 298 return 0; | 298 return 0; |
| 299 EnsureDiskUsageCacheInitialized(origin); | 299 EnsureDiskUsageCacheInitialized(origin); |
| 300 return origin_size_map_[origin]; | 300 return origin_size_map_[origin]; |
| 301 } | 301 } |
| 302 | 302 |
| 303 base::Time IndexedDBContextImpl::GetOriginLastModified(const Origin& origin) { | 303 base::Time IndexedDBContextImpl::GetOriginLastModified(const Origin& origin) { |
| 304 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 304 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 305 if (data_path_.empty() || !HasOrigin(origin)) | 305 if (data_path_.empty() || !HasOrigin(origin)) |
| 306 return base::Time(); | 306 return base::Time(); |
| 307 base::FilePath idb_directory = GetLevelDBPath(origin); | 307 base::FilePath idb_directory = GetLevelDBPath(origin); |
| 308 base::File::Info file_info; | 308 base::File::Info file_info; |
| 309 if (!base::GetFileInfo(idb_directory, &file_info)) | 309 if (!base::GetFileInfo(idb_directory, &file_info)) |
| 310 return base::Time(); | 310 return base::Time(); |
| 311 return file_info.last_modified; | 311 return file_info.last_modified; |
| 312 } | 312 } |
| 313 | 313 |
| 314 // TODO(jsbell): Update callers to use url::Origin overload and remove. | 314 // TODO(jsbell): Update callers to use url::Origin overload and remove. |
| 315 void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) { | 315 void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) { |
| 316 DeleteForOrigin(Origin(origin_url)); | 316 DeleteForOrigin(Origin(origin_url)); |
| 317 } | 317 } |
| 318 | 318 |
| 319 void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) { | 319 void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) { |
| 320 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 320 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 321 ForceClose(origin, FORCE_CLOSE_DELETE_ORIGIN); | 321 ForceClose(origin, FORCE_CLOSE_DELETE_ORIGIN); |
| 322 if (data_path_.empty() || !HasOrigin(origin)) | 322 if (data_path_.empty() || !HasOrigin(origin)) |
| 323 return; | 323 return; |
| 324 | 324 |
| 325 base::FilePath idb_directory = GetLevelDBPath(origin); | 325 base::FilePath idb_directory = GetLevelDBPath(origin); |
| 326 EnsureDiskUsageCacheInitialized(origin); | 326 EnsureDiskUsageCacheInitialized(origin); |
| 327 leveldb::Status s = LevelDBDatabase::Destroy(idb_directory); | 327 leveldb::Status s = LevelDBDatabase::Destroy(idb_directory); |
| 328 if (!s.ok()) { | 328 if (!s.ok()) { |
| 329 LOG(WARNING) << "Failed to delete LevelDB database: " | 329 LOG(WARNING) << "Failed to delete LevelDB database: " |
| 330 << idb_directory.AsUTF8Unsafe(); | 330 << idb_directory.AsUTF8Unsafe(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 344 } | 344 } |
| 345 | 345 |
| 346 // TODO(jsbell): Update callers to use url::Origin overload and remove. | 346 // TODO(jsbell): Update callers to use url::Origin overload and remove. |
| 347 void IndexedDBContextImpl::CopyOriginData(const GURL& origin_url, | 347 void IndexedDBContextImpl::CopyOriginData(const GURL& origin_url, |
| 348 IndexedDBContext* dest_context) { | 348 IndexedDBContext* dest_context) { |
| 349 CopyOriginData(Origin(origin_url), dest_context); | 349 CopyOriginData(Origin(origin_url), dest_context); |
| 350 } | 350 } |
| 351 | 351 |
| 352 void IndexedDBContextImpl::CopyOriginData(const Origin& origin, | 352 void IndexedDBContextImpl::CopyOriginData(const Origin& origin, |
| 353 IndexedDBContext* dest_context) { | 353 IndexedDBContext* dest_context) { |
| 354 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 354 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 355 if (data_path_.empty() || !HasOrigin(origin)) | 355 if (data_path_.empty() || !HasOrigin(origin)) |
| 356 return; | 356 return; |
| 357 | 357 |
| 358 IndexedDBContextImpl* dest_context_impl = | 358 IndexedDBContextImpl* dest_context_impl = |
| 359 static_cast<IndexedDBContextImpl*>(dest_context); | 359 static_cast<IndexedDBContextImpl*>(dest_context); |
| 360 | 360 |
| 361 ForceClose(origin, FORCE_CLOSE_COPY_ORIGIN); | 361 ForceClose(origin, FORCE_CLOSE_COPY_ORIGIN); |
| 362 | 362 |
| 363 // Make sure we're not about to delete our own database. | 363 // Make sure we're not about to delete our own database. |
| 364 CHECK_NE(dest_context_impl->data_path().value(), data_path().value()); | 364 CHECK_NE(dest_context_impl->data_path().value(), data_path().value()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 375 | 375 |
| 376 for (const base::FilePath& src_data_path : GetStoragePaths(origin)) { | 376 for (const base::FilePath& src_data_path : GetStoragePaths(origin)) { |
| 377 if (base::PathExists(src_data_path)) { | 377 if (base::PathExists(src_data_path)) { |
| 378 base::CopyDirectory(src_data_path, dest_data_path, true); | 378 base::CopyDirectory(src_data_path, dest_data_path, true); |
| 379 } | 379 } |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 | 382 |
| 383 void IndexedDBContextImpl::ForceClose(const Origin origin, | 383 void IndexedDBContextImpl::ForceClose(const Origin origin, |
| 384 ForceCloseReason reason) { | 384 ForceCloseReason reason) { |
| 385 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 385 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 386 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Context.ForceCloseReason", | 386 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Context.ForceCloseReason", |
| 387 reason, | 387 reason, |
| 388 FORCE_CLOSE_REASON_MAX); | 388 FORCE_CLOSE_REASON_MAX); |
| 389 | 389 |
| 390 if (data_path_.empty() || !HasOrigin(origin)) | 390 if (data_path_.empty() || !HasOrigin(origin)) |
| 391 return; | 391 return; |
| 392 | 392 |
| 393 if (factory_.get()) | 393 if (factory_.get()) |
| 394 factory_->ForceClose(origin); | 394 factory_->ForceClose(origin); |
| 395 DCHECK_EQ(0UL, GetConnectionCount(origin)); | 395 DCHECK_EQ(0UL, GetConnectionCount(origin)); |
| 396 } | 396 } |
| 397 | 397 |
| 398 size_t IndexedDBContextImpl::GetConnectionCount(const Origin& origin) { | 398 size_t IndexedDBContextImpl::GetConnectionCount(const Origin& origin) { |
| 399 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 399 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 400 if (data_path_.empty() || !HasOrigin(origin)) | 400 if (data_path_.empty() || !HasOrigin(origin)) |
| 401 return 0; | 401 return 0; |
| 402 | 402 |
| 403 if (!factory_.get()) | 403 if (!factory_.get()) |
| 404 return 0; | 404 return 0; |
| 405 | 405 |
| 406 return factory_->GetConnectionCount(origin); | 406 return factory_->GetConnectionCount(origin); |
| 407 } | 407 } |
| 408 | 408 |
| 409 std::vector<base::FilePath> IndexedDBContextImpl::GetStoragePaths( | 409 std::vector<base::FilePath> IndexedDBContextImpl::GetStoragePaths( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 426 } | 426 } |
| 427 | 427 |
| 428 void IndexedDBContextImpl::SetTaskRunnerForTesting( | 428 void IndexedDBContextImpl::SetTaskRunnerForTesting( |
| 429 base::SequencedTaskRunner* task_runner) { | 429 base::SequencedTaskRunner* task_runner) { |
| 430 DCHECK(!task_runner_.get()); | 430 DCHECK(!task_runner_.get()); |
| 431 task_runner_ = task_runner; | 431 task_runner_ = task_runner; |
| 432 } | 432 } |
| 433 | 433 |
| 434 void IndexedDBContextImpl::ConnectionOpened(const Origin& origin, | 434 void IndexedDBContextImpl::ConnectionOpened(const Origin& origin, |
| 435 IndexedDBConnection* connection) { | 435 IndexedDBConnection* connection) { |
| 436 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 436 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 437 quota_manager_proxy()->NotifyStorageAccessed( | 437 quota_manager_proxy()->NotifyStorageAccessed( |
| 438 storage::QuotaClient::kIndexedDatabase, origin.GetURL(), | 438 storage::QuotaClient::kIndexedDatabase, origin.GetURL(), |
| 439 storage::kStorageTypeTemporary); | 439 storage::kStorageTypeTemporary); |
| 440 if (AddToOriginSet(origin)) { | 440 if (AddToOriginSet(origin)) { |
| 441 // A newly created db, notify the quota system. | 441 // A newly created db, notify the quota system. |
| 442 QueryDiskAndUpdateQuotaUsage(origin); | 442 QueryDiskAndUpdateQuotaUsage(origin); |
| 443 } else { | 443 } else { |
| 444 EnsureDiskUsageCacheInitialized(origin); | 444 EnsureDiskUsageCacheInitialized(origin); |
| 445 } | 445 } |
| 446 } | 446 } |
| 447 | 447 |
| 448 void IndexedDBContextImpl::ConnectionClosed(const Origin& origin, | 448 void IndexedDBContextImpl::ConnectionClosed(const Origin& origin, |
| 449 IndexedDBConnection* connection) { | 449 IndexedDBConnection* connection) { |
| 450 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 450 DCHECK(TaskRunner()->RunsTasksInCurrentSequence()); |
| 451 quota_manager_proxy()->NotifyStorageAccessed( | 451 quota_manager_proxy()->NotifyStorageAccessed( |
| 452 storage::QuotaClient::kIndexedDatabase, origin.GetURL(), | 452 storage::QuotaClient::kIndexedDatabase, origin.GetURL(), |
| 453 storage::kStorageTypeTemporary); | 453 storage::kStorageTypeTemporary); |
| 454 if (factory_.get() && factory_->GetConnectionCount(origin) == 0) | 454 if (factory_.get() && factory_->GetConnectionCount(origin) == 0) |
| 455 QueryDiskAndUpdateQuotaUsage(origin); | 455 QueryDiskAndUpdateQuotaUsage(origin); |
| 456 } | 456 } |
| 457 | 457 |
| 458 void IndexedDBContextImpl::TransactionComplete(const Origin& origin) { | 458 void IndexedDBContextImpl::TransactionComplete(const Origin& origin) { |
| 459 DCHECK(!factory_.get() || factory_->GetConnectionCount(origin) > 0); | 459 DCHECK(!factory_.get() || factory_->GetConnectionCount(origin) > 0); |
| 460 QueryDiskAndUpdateQuotaUsage(origin); | 460 QueryDiskAndUpdateQuotaUsage(origin); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 void IndexedDBContextImpl::ResetCaches() { | 563 void IndexedDBContextImpl::ResetCaches() { |
| 564 origin_set_.reset(); | 564 origin_set_.reset(); |
| 565 origin_size_map_.clear(); | 565 origin_size_map_.clear(); |
| 566 } | 566 } |
| 567 | 567 |
| 568 base::SequencedTaskRunner* IndexedDBContextImpl::TaskRunner() const { | 568 base::SequencedTaskRunner* IndexedDBContextImpl::TaskRunner() const { |
| 569 return task_runner_.get(); | 569 return task_runner_.get(); |
| 570 } | 570 } |
| 571 | 571 |
| 572 } // namespace content | 572 } // namespace content |
| OLD | NEW |