web_database_service.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/webdata/common/web_database_service.h"
  5. #include <stddef.h>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/location.h"
  9. #include "base/threading/thread_task_runner_handle.h"
  10. #include "components/webdata/common/web_data_request_manager.h"
  11. #include "components/webdata/common/web_data_results.h"
  12. #include "components/webdata/common/web_data_service_consumer.h"
  13. #include "components/webdata/common/web_database_backend.h"
  14. // Receives messages from the backend on the DB sequence, posts them to
  15. // WebDatabaseService on the UI sequence.
  16. class WebDatabaseService::BackendDelegate
  17. : public WebDatabaseBackend::Delegate {
  18. public:
  19. BackendDelegate(const base::WeakPtr<WebDatabaseService>& web_database_service)
  20. : web_database_service_(web_database_service),
  21. callback_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
  22. void DBLoaded(sql::InitStatus status,
  23. const std::string& diagnostics) override {
  24. callback_task_runner_->PostTask(
  25. FROM_HERE, base::BindOnce(&WebDatabaseService::OnDatabaseLoadDone,
  26. web_database_service_, status, diagnostics));
  27. }
  28. private:
  29. const base::WeakPtr<WebDatabaseService> web_database_service_;
  30. scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
  31. };
  32. WebDatabaseService::WebDatabaseService(
  33. const base::FilePath& path,
  34. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  35. scoped_refptr<base::SingleThreadTaskRunner> db_task_runner)
  36. : base::RefCountedDeleteOnSequence<WebDatabaseService>(ui_task_runner),
  37. path_(path),
  38. db_task_runner_(db_task_runner) {
  39. DCHECK(ui_task_runner->RunsTasksInCurrentSequence());
  40. DCHECK(db_task_runner_);
  41. }
  42. WebDatabaseService::~WebDatabaseService() = default;
  43. void WebDatabaseService::AddTable(std::unique_ptr<WebDatabaseTable> table) {
  44. if (!web_db_backend_) {
  45. web_db_backend_ = base::MakeRefCounted<WebDatabaseBackend>(
  46. path_,
  47. std::make_unique<BackendDelegate>(weak_ptr_factory_.GetWeakPtr()),
  48. db_task_runner_);
  49. }
  50. web_db_backend_->AddTable(std::move(table));
  51. }
  52. void WebDatabaseService::LoadDatabase() {
  53. DCHECK(web_db_backend_);
  54. db_task_runner_->PostTask(
  55. FROM_HERE, BindOnce(&WebDatabaseBackend::InitDatabase, web_db_backend_));
  56. }
  57. void WebDatabaseService::ShutdownDatabase() {
  58. error_callbacks_.clear();
  59. weak_ptr_factory_.InvalidateWeakPtrs();
  60. if (!web_db_backend_)
  61. return;
  62. db_task_runner_->PostTask(
  63. FROM_HERE,
  64. BindOnce(&WebDatabaseBackend::ShutdownDatabase, web_db_backend_));
  65. }
  66. WebDatabase* WebDatabaseService::GetDatabaseOnDB() const {
  67. DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
  68. return web_db_backend_ ? web_db_backend_->database() : nullptr;
  69. }
  70. scoped_refptr<WebDatabaseBackend> WebDatabaseService::GetBackend() const {
  71. return web_db_backend_;
  72. }
  73. void WebDatabaseService::ScheduleDBTask(const base::Location& from_here,
  74. WriteTask task) {
  75. DCHECK(web_db_backend_);
  76. std::unique_ptr<WebDataRequest> request =
  77. web_db_backend_->request_manager()->NewRequest(nullptr);
  78. db_task_runner_->PostTask(
  79. from_here,
  80. BindOnce(&WebDatabaseBackend::DBWriteTaskWrapper, web_db_backend_,
  81. std::move(task), std::move(request)));
  82. }
  83. WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult(
  84. const base::Location& from_here,
  85. ReadTask task,
  86. WebDataServiceConsumer* consumer) {
  87. DCHECK(consumer);
  88. DCHECK(web_db_backend_);
  89. std::unique_ptr<WebDataRequest> request =
  90. web_db_backend_->request_manager()->NewRequest(consumer);
  91. WebDataServiceBase::Handle handle = request->GetHandle();
  92. db_task_runner_->PostTask(
  93. from_here,
  94. BindOnce(&WebDatabaseBackend::DBReadTaskWrapper, web_db_backend_,
  95. std::move(task), std::move(request)));
  96. return handle;
  97. }
  98. void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) {
  99. if (web_db_backend_)
  100. web_db_backend_->request_manager()->CancelRequest(h);
  101. }
  102. void WebDatabaseService::RegisterDBErrorCallback(DBLoadErrorCallback callback) {
  103. error_callbacks_.push_back(std::move(callback));
  104. }
  105. void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status,
  106. const std::string& diagnostics) {
  107. // The INIT_OK_WITH_DATA_LOSS status is an initialization success but with
  108. // suspected data loss, so we also run the error callbacks.
  109. if (status == sql::INIT_OK)
  110. return;
  111. // Notify that the database load failed.
  112. while (!error_callbacks_.empty()) {
  113. // The profile error callback is a message box that runs in a nested run
  114. // loop. While it's being displayed, other OnDatabaseLoadDone() will run
  115. // (posted from WebDatabaseBackend::Delegate::DBLoaded()). We need to make
  116. // sure that after the callback running the message box returns, it checks
  117. // |error_callbacks_| before it accesses it.
  118. DBLoadErrorCallback error_callback = std::move(error_callbacks_.back());
  119. error_callbacks_.pop_back();
  120. if (!error_callback.is_null())
  121. std::move(error_callback).Run(status, diagnostics);
  122. }
  123. }