| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/dom_storage/local_storage_context_mojo.h" | 5 #include "content/browser/dom_storage/local_storage_context_mojo.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "components/leveldb/public/cpp/util.h" | 10 #include "components/leveldb/public/cpp/util.h" |
| 11 #include "components/leveldb/public/interfaces/leveldb.mojom.h" | 11 #include "components/leveldb/public/interfaces/leveldb.mojom.h" |
| 12 #include "content/browser/dom_storage/dom_storage_area.h" | 12 #include "content/browser/dom_storage/dom_storage_area.h" |
| 13 #include "content/browser/dom_storage/dom_storage_database.h" | 13 #include "content/browser/dom_storage/dom_storage_database.h" |
| 14 #include "content/browser/dom_storage/dom_storage_task_runner.h" | 14 #include "content/browser/dom_storage/dom_storage_task_runner.h" |
| 15 #include "content/browser/dom_storage/local_storage_database.pb.h" | 15 #include "content/browser/dom_storage/local_storage_database.pb.h" |
| 16 #include "content/browser/leveldb_wrapper_impl.h" | 16 #include "content/browser/leveldb_wrapper_impl.h" |
| 17 #include "content/common/dom_storage/dom_storage_types.h" | 17 #include "content/common/dom_storage/dom_storage_types.h" |
| 18 #include "content/public/browser/local_storage_usage_info.h" | 18 #include "content/public/browser/local_storage_usage_info.h" |
| 19 #include "services/file/public/interfaces/constants.mojom.h" | 19 #include "services/file/public/interfaces/constants.mojom.h" |
| 20 #include "services/service_manager/public/cpp/connection.h" | |
| 21 #include "services/service_manager/public/cpp/connector.h" | 20 #include "services/service_manager/public/cpp/connector.h" |
| 22 #include "sql/connection.h" | 21 #include "sql/connection.h" |
| 23 #include "third_party/leveldatabase/env_chromium.h" | 22 #include "third_party/leveldatabase/env_chromium.h" |
| 24 | 23 |
| 25 namespace content { | 24 namespace content { |
| 26 | 25 |
| 27 // LevelDB database schema | 26 // LevelDB database schema |
| 28 // ======================= | 27 // ======================= |
| 29 // | 28 // |
| 30 // Version 1 (in sorted order): | 29 // Version 1 (in sorted order): |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 connection_state_ = CONNECTION_IN_PROGRESS; | 290 connection_state_ = CONNECTION_IN_PROGRESS; |
| 292 leveldb::mojom::LevelDBDatabaseAssociatedRequest request = | 291 leveldb::mojom::LevelDBDatabaseAssociatedRequest request = |
| 293 MakeIsolatedRequest(&database_); | 292 MakeIsolatedRequest(&database_); |
| 294 OnDatabaseOpened(true, leveldb::mojom::DatabaseError::OK); | 293 OnDatabaseOpened(true, leveldb::mojom::DatabaseError::OK); |
| 295 return request; | 294 return request; |
| 296 } | 295 } |
| 297 | 296 |
| 298 void LocalStorageContextMojo::RunWhenConnected(base::OnceClosure callback) { | 297 void LocalStorageContextMojo::RunWhenConnected(base::OnceClosure callback) { |
| 299 // If we don't have a filesystem_connection_, we'll need to establish one. | 298 // If we don't have a filesystem_connection_, we'll need to establish one. |
| 300 if (connection_state_ == NO_CONNECTION) { | 299 if (connection_state_ == NO_CONNECTION) { |
| 301 CHECK(connector_); | |
| 302 file_service_connection_ = connector_->Connect(file::mojom::kServiceName); | |
| 303 connection_state_ = CONNECTION_IN_PROGRESS; | 300 connection_state_ = CONNECTION_IN_PROGRESS; |
| 304 file_service_connection_->AddConnectionCompletedClosure( | |
| 305 base::Bind(&LocalStorageContextMojo::OnUserServiceConnectionComplete, | |
| 306 weak_ptr_factory_.GetWeakPtr())); | |
| 307 file_service_connection_->SetConnectionLostClosure( | |
| 308 base::Bind(&LocalStorageContextMojo::OnUserServiceConnectionError, | |
| 309 weak_ptr_factory_.GetWeakPtr())); | |
| 310 | |
| 311 InitiateConnection(); | 301 InitiateConnection(); |
| 312 } | 302 } |
| 313 | 303 |
| 314 if (connection_state_ == CONNECTION_IN_PROGRESS) { | 304 if (connection_state_ == CONNECTION_IN_PROGRESS) { |
| 315 // Queue this OpenLocalStorage call for when we have a level db pointer. | 305 // Queue this OpenLocalStorage call for when we have a level db pointer. |
| 316 on_database_opened_callbacks_.push_back(std::move(callback)); | 306 on_database_opened_callbacks_.push_back(std::move(callback)); |
| 317 return; | 307 return; |
| 318 } | 308 } |
| 319 | 309 |
| 320 std::move(callback).Run(); | 310 std::move(callback).Run(); |
| 321 } | 311 } |
| 322 | 312 |
| 323 void LocalStorageContextMojo::OnUserServiceConnectionComplete() { | |
| 324 CHECK_EQ(service_manager::mojom::ConnectResult::SUCCEEDED, | |
| 325 file_service_connection_->GetResult()); | |
| 326 } | |
| 327 | |
| 328 void LocalStorageContextMojo::OnUserServiceConnectionError() { | |
| 329 CHECK(false); | |
| 330 } | |
| 331 | |
| 332 void LocalStorageContextMojo::InitiateConnection(bool in_memory_only) { | 313 void LocalStorageContextMojo::InitiateConnection(bool in_memory_only) { |
| 333 DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS); | 314 DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS); |
| 315 CHECK(connector_); |
| 334 if (!subdirectory_.empty() && !in_memory_only) { | 316 if (!subdirectory_.empty() && !in_memory_only) { |
| 335 // We were given a subdirectory to write to. Get it and use a disk backed | 317 // We were given a subdirectory to write to. Get it and use a disk backed |
| 336 // database. | 318 // database. |
| 337 file_service_connection_->GetInterface(&file_system_); | 319 connector_->BindInterface(file::mojom::kServiceName, &file_system_); |
| 338 file_system_->GetSubDirectory( | 320 file_system_->GetSubDirectory( |
| 339 subdirectory_.AsUTF8Unsafe(), MakeRequest(&directory_), | 321 subdirectory_.AsUTF8Unsafe(), MakeRequest(&directory_), |
| 340 base::Bind(&LocalStorageContextMojo::OnDirectoryOpened, | 322 base::Bind(&LocalStorageContextMojo::OnDirectoryOpened, |
| 341 weak_ptr_factory_.GetWeakPtr())); | 323 weak_ptr_factory_.GetWeakPtr())); |
| 342 } else { | 324 } else { |
| 343 // We were not given a subdirectory. Use a memory backed database. | 325 // We were not given a subdirectory. Use a memory backed database. |
| 344 file_service_connection_->GetInterface(&leveldb_service_); | 326 connector_->BindInterface(file::mojom::kServiceName, &leveldb_service_); |
| 345 leveldb_service_->OpenInMemory( | 327 leveldb_service_->OpenInMemory( |
| 346 MakeRequest(&database_), | 328 MakeRequest(&database_), |
| 347 base::Bind(&LocalStorageContextMojo::OnDatabaseOpened, | 329 base::Bind(&LocalStorageContextMojo::OnDatabaseOpened, |
| 348 weak_ptr_factory_.GetWeakPtr(), true)); | 330 weak_ptr_factory_.GetWeakPtr(), true)); |
| 349 } | 331 } |
| 350 } | 332 } |
| 351 | 333 |
| 352 void LocalStorageContextMojo::OnDirectoryOpened( | 334 void LocalStorageContextMojo::OnDirectoryOpened( |
| 353 filesystem::mojom::FileError err) { | 335 filesystem::mojom::FileError err) { |
| 354 if (err != filesystem::mojom::FileError::OK) { | 336 if (err != filesystem::mojom::FileError::OK) { |
| 355 // We failed to open the directory; continue with startup so that we create | 337 // We failed to open the directory; continue with startup so that we create |
| 356 // the |level_db_wrappers_|. | 338 // the |level_db_wrappers_|. |
| 357 UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError", | 339 UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError", |
| 358 -static_cast<base::File::Error>(err), | 340 -static_cast<base::File::Error>(err), |
| 359 -base::File::FILE_ERROR_MAX); | 341 -base::File::FILE_ERROR_MAX); |
| 360 UMA_HISTOGRAM_ENUMERATION( | 342 UMA_HISTOGRAM_ENUMERATION( |
| 361 kStorageOpenHistogramName, | 343 kStorageOpenHistogramName, |
| 362 static_cast<int>(LocalStorageOpenHistogram::DIRECTORY_OPEN_FAILED), | 344 static_cast<int>(LocalStorageOpenHistogram::DIRECTORY_OPEN_FAILED), |
| 363 static_cast<int>(LocalStorageOpenHistogram::MAX)); | 345 static_cast<int>(LocalStorageOpenHistogram::MAX)); |
| 364 OnDatabaseOpened(false, leveldb::mojom::DatabaseError::OK); | 346 OnDatabaseOpened(false, leveldb::mojom::DatabaseError::OK); |
| 365 return; | 347 return; |
| 366 } | 348 } |
| 367 | 349 |
| 368 // Now that we have a directory, connect to the LevelDB service and get our | 350 // Now that we have a directory, connect to the LevelDB service and get our |
| 369 // database. | 351 // database. |
| 370 file_service_connection_->GetInterface(&leveldb_service_); | 352 connector_->BindInterface(file::mojom::kServiceName, &leveldb_service_); |
| 371 leveldb_service_->SetEnvironmentName("LevelDBEnv.LocalStorage"); | 353 leveldb_service_->SetEnvironmentName("LevelDBEnv.LocalStorage"); |
| 372 | 354 |
| 373 // We might still need to use the directory, so create a clone. | 355 // We might still need to use the directory, so create a clone. |
| 374 filesystem::mojom::DirectoryPtr directory_clone; | 356 filesystem::mojom::DirectoryPtr directory_clone; |
| 375 directory_->Clone(MakeRequest(&directory_clone)); | 357 directory_->Clone(MakeRequest(&directory_clone)); |
| 376 | 358 |
| 377 auto options = leveldb::mojom::OpenOptions::New(); | 359 auto options = leveldb::mojom::OpenOptions::New(); |
| 378 options->create_if_missing = true; | 360 options->create_if_missing = true; |
| 379 leveldb_service_->OpenWithOptions( | 361 leveldb_service_->OpenWithOptions( |
| 380 std::move(options), std::move(directory_clone), "leveldb", | 362 std::move(options), std::move(directory_clone), "leveldb", |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 recreate_in_memory = true; | 469 recreate_in_memory = true; |
| 488 } else if (tried_to_recreate_) { | 470 } else if (tried_to_recreate_) { |
| 489 // Give up completely, run without any database. | 471 // Give up completely, run without any database. |
| 490 database_ = nullptr; | 472 database_ = nullptr; |
| 491 OnConnectionFinished(); | 473 OnConnectionFinished(); |
| 492 return; | 474 return; |
| 493 } | 475 } |
| 494 | 476 |
| 495 tried_to_recreate_ = true; | 477 tried_to_recreate_ = true; |
| 496 | 478 |
| 497 // Unit tests might not have a file_service_connection_, in which case there | 479 // Unit tests might not have a bound file_service_, in which case there is |
| 498 // is nothing to retry. | 480 // nothing to retry. |
| 499 if (!file_service_connection_) { | 481 if (!file_system_.is_bound()) { |
| 500 database_ = nullptr; | 482 database_ = nullptr; |
| 501 OnConnectionFinished(); | 483 OnConnectionFinished(); |
| 502 return; | 484 return; |
| 503 } | 485 } |
| 504 | 486 |
| 505 // Close and destroy database, and try again. | 487 // Close and destroy database, and try again. |
| 506 database_ = nullptr; | 488 database_ = nullptr; |
| 507 if (directory_.is_bound()) { | 489 if (directory_.is_bound()) { |
| 508 leveldb_service_->Destroy( | 490 leveldb_service_->Destroy( |
| 509 std::move(directory_), "leveldb", | 491 std::move(directory_), "leveldb", |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 for (const auto& info : usage) { | 571 for (const auto& info : usage) { |
| 590 url::Origin origin_candidate(info.origin); | 572 url::Origin origin_candidate(info.origin); |
| 591 if (!origin_candidate.IsSameOriginWith(origin) && | 573 if (!origin_candidate.IsSameOriginWith(origin) && |
| 592 origin_candidate.IsSamePhysicalOriginWith(origin)) | 574 origin_candidate.IsSamePhysicalOriginWith(origin)) |
| 593 DeleteStorage(origin_candidate); | 575 DeleteStorage(origin_candidate); |
| 594 } | 576 } |
| 595 DeleteStorage(origin); | 577 DeleteStorage(origin); |
| 596 } | 578 } |
| 597 | 579 |
| 598 } // namespace content | 580 } // namespace content |
| OLD | NEW |