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 |