diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-04 14:17:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-05 10:05:06 +0000 |
commit | 39d357e3248f80abea0159765ff39554affb40db (patch) | |
tree | aba0e6bfb76de0244bba0f5fdbd64b830dd6e621 /chromium/components/webdata | |
parent | 87778abf5a1f89266f37d1321b92a21851d8244d (diff) | |
download | qtwebengine-chromium-39d357e3248f80abea0159765ff39554affb40db.tar.gz |
BASELINE: Update Chromium to 55.0.2883.105
And updates ninja to 1.7.2
Change-Id: I20d43c737f82764d857ada9a55586901b18b9243
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/webdata')
8 files changed, 125 insertions, 62 deletions
diff --git a/chromium/components/webdata/common/web_data_service_base.h b/chromium/components/webdata/common/web_data_service_base.h index adad9f10480..2783beb2d81 100644 --- a/chromium/components/webdata/common/web_data_service_base.h +++ b/chromium/components/webdata/common/web_data_service_base.h @@ -36,7 +36,8 @@ class WEBDATA_EXPORT WebDataServiceBase // takes a single parameter, the sql::InitStatus value from trying // to open the database. // TODO(joi): Should we combine this with WebDatabaseService::InitCallback? - typedef base::Callback<void(sql::InitStatus)> ProfileErrorCallback; + typedef base::Callback<void(sql::InitStatus, const std::string&)> + ProfileErrorCallback; typedef base::Closure DBLoadedCallback; diff --git a/chromium/components/webdata/common/web_database.cc b/chromium/components/webdata/common/web_database.cc index a24a4b88a51..c731270a2f7 100644 --- a/chromium/components/webdata/common/web_database.cc +++ b/chromium/components/webdata/common/web_database.cc @@ -65,6 +65,11 @@ void WebDatabase::CommitTransaction() { db_.CommitTransaction(); } +std::string WebDatabase::GetDiagnosticInfo(int extended_error, + sql::Statement* statement) { + return db_.GetDiagnosticInfo(extended_error, statement); +} + sql::Connection* WebDatabase::GetSQLConnection() { return &db_; } diff --git a/chromium/components/webdata/common/web_database.h b/chromium/components/webdata/common/web_database.h index bd914f446ef..79931bedba7 100644 --- a/chromium/components/webdata/common/web_database.h +++ b/chromium/components/webdata/common/web_database.h @@ -41,6 +41,13 @@ class WEBDATA_EXPORT WebDatabase { // Retrieves a table based on its |key|. WebDatabaseTable* GetTable(WebDatabaseTable::TypeKey key); + // Call before Init() to set the error callback to be used for the + // underlying database connection. + void set_error_callback( + const sql::Connection::ErrorCallback& error_callback) { + db_.set_error_callback(error_callback); + } + // Initialize the database given a name. The name defines where the SQLite // file is. If this returns an error code, no other method should be called. // @@ -53,6 +60,8 @@ class WEBDATA_EXPORT WebDatabase { void BeginTransaction(); void CommitTransaction(); + std::string GetDiagnosticInfo(int extended_error, sql::Statement* statement); + // Exposed for testing only. sql::Connection* GetSQLConnection(); diff --git a/chromium/components/webdata/common/web_database_backend.cc b/chromium/components/webdata/common/web_database_backend.cc index 7cb343e62f0..a4446061f91 100644 --- a/chromium/components/webdata/common/web_database_backend.cc +++ b/chromium/components/webdata/common/web_database_backend.cc @@ -4,6 +4,7 @@ #include "components/webdata/common/web_database_backend.h" +#include <algorithm> #include <utility> #include "base/bind.h" @@ -11,6 +12,7 @@ #include "components/webdata/common/web_data_request_manager.h" #include "components/webdata/common/web_database.h" #include "components/webdata/common/web_database_table.h" +#include "sql/error_delegate_util.h" using base::Bind; using base::FilePath; @@ -24,8 +26,8 @@ WebDatabaseBackend::WebDatabaseBackend( request_manager_(new WebDataRequestManager()), init_status_(sql::INIT_FAILURE), init_complete_(false), - delegate_(delegate) { -} + catastrophic_error_occurred_(false), + delegate_(delegate) {} void WebDatabaseBackend::AddTable(std::unique_ptr<WebDatabaseTable> table) { DCHECK(!db_.get()); @@ -35,31 +37,8 @@ void WebDatabaseBackend::AddTable(std::unique_ptr<WebDatabaseTable> table) { void WebDatabaseBackend::InitDatabase() { LoadDatabaseIfNecessary(); if (delegate_) { - delegate_->DBLoaded(init_status_); - } -} - -sql::InitStatus WebDatabaseBackend::LoadDatabaseIfNecessary() { - if (init_complete_ || db_path_.empty()) { - return init_status_; - } - init_complete_ = true; - db_.reset(new WebDatabase()); - - for (ScopedVector<WebDatabaseTable>::iterator it = tables_.begin(); - it != tables_.end(); ++it) { - db_->AddTable(*it); - } - - init_status_ = db_->Init(db_path_); - if (init_status_ != sql::INIT_OK) { - LOG(ERROR) << "Cannot initialize the web database: " << init_status_; - db_.reset(NULL); - return init_status_; + delegate_->DBLoaded(init_status_, diagnostics_); } - - db_->BeginTransaction(); - return init_status_; } void WebDatabaseBackend::ShutdownDatabase() { @@ -113,6 +92,50 @@ WebDatabaseBackend::~WebDatabaseBackend() { ShutdownDatabase(); } +void WebDatabaseBackend::LoadDatabaseIfNecessary() { + if (init_complete_ || db_path_.empty()) + return; + + init_complete_ = true; + db_.reset(new WebDatabase()); + + for (const auto& table : tables_) + db_->AddTable(table); + + // Unretained to avoid a ref loop since we own |db_|. + db_->set_error_callback(base::Bind(&WebDatabaseBackend::DatabaseErrorCallback, + base::Unretained(this))); + diagnostics_.clear(); + catastrophic_error_occurred_ = false; + init_status_ = db_->Init(db_path_); + + if (init_status_ != sql::INIT_OK) { + LOG(ERROR) << "Cannot initialize the web database: " << init_status_; + db_.reset(); + return; + } + + // A catastrophic error might have happened and recovered. + if (catastrophic_error_occurred_) { + init_status_ = sql::INIT_OK_WITH_DATA_LOSS; + LOG(WARNING) + << "Webdata recovered from a catastrophic error. Data loss possible."; + } + db_->BeginTransaction(); +} + +void WebDatabaseBackend::DatabaseErrorCallback(int error, + sql::Statement* statement) { + // We ignore any further error callbacks after the first catastrophic error. + if (!catastrophic_error_occurred_ && sql::IsErrorCatastrophic(error)) { + catastrophic_error_occurred_ = true; + diagnostics_ = db_->GetDiagnosticInfo(error, statement); + diagnostics_ += sql::GetCorruptFileDiagnosticsInfo(db_path_); + + db_->GetSQLConnection()->RazeAndClose(); + } +} + void WebDatabaseBackend::Commit() { DCHECK(db_); DCHECK_EQ(sql::INIT_OK, init_status_); diff --git a/chromium/components/webdata/common/web_database_backend.h b/chromium/components/webdata/common/web_database_backend.h index 341bb76d7ac..dbb694aaab3 100644 --- a/chromium/components/webdata/common/web_database_backend.h +++ b/chromium/components/webdata/common/web_database_backend.h @@ -39,7 +39,11 @@ class WEBDATA_EXPORT WebDatabaseBackend virtual ~Delegate() {} // Invoked when the backend has finished loading the db. - virtual void DBLoaded(sql::InitStatus status) = 0; + // |status| is the result of initializing the db. + // |diagnostics| contains diagnostic information about the db, and it will + // only be populated when an error occurs. + virtual void DBLoaded(sql::InitStatus status, + const std::string& diagnostics) = 0; }; WebDatabaseBackend( @@ -54,12 +58,6 @@ class WEBDATA_EXPORT WebDatabaseBackend // Callback is called synchronously. void InitDatabase(); - // Opens the database file from the profile path if an init has not yet been - // attempted. Separated from the constructor to ease construction/destruction - // of this object on one thread but database access on the DB thread. Returns - // the status of the database. - sql::InitStatus LoadDatabaseIfNecessary(); - // Shuts down the database. void ShutdownDatabase(); @@ -90,6 +88,14 @@ class WEBDATA_EXPORT WebDatabaseBackend virtual ~WebDatabaseBackend(); private: + // Opens the database file from the profile path if an init has not yet been + // attempted. Separated from the constructor to ease construction/destruction + // of this object on one thread but database access on the DB thread. + void LoadDatabaseIfNecessary(); + + // Invoked on a db error. + void DatabaseErrorCallback(int error, sql::Statement* statement); + // Commit the current transaction. void Commit(); @@ -119,6 +125,14 @@ class WEBDATA_EXPORT WebDatabaseBackend // fails), used to avoid continually trying to reinit if the db init fails. bool init_complete_; + // True if a catastrophic database error occurs and further error callbacks + // from the database should be ignored. + bool catastrophic_error_occurred_; + + // If a catastrophic database error has occurred, this contains any available + // diagnostic information. + std::string diagnostics_; + // Delegate. See the class definition above for more information. std::unique_ptr<Delegate> delegate_; diff --git a/chromium/components/webdata/common/web_database_migration_unittest.cc b/chromium/components/webdata/common/web_database_migration_unittest.cc index 36d68bb26b9..996f9594d70 100644 --- a/chromium/components/webdata/common/web_database_migration_unittest.cc +++ b/chromium/components/webdata/common/web_database_migration_unittest.cc @@ -88,7 +88,7 @@ class WebDatabaseMigrationTest : public testing::Test { base::FilePath GetDatabasePath() { const base::FilePath::CharType kWebDatabaseFilename[] = FILE_PATH_LITERAL("TestWebDatabase.sqlite3"); - return temp_dir_.path().Append(base::FilePath(kWebDatabaseFilename)); + return temp_dir_.GetPath().Append(base::FilePath(kWebDatabaseFilename)); } // The textual contents of |file| are read from diff --git a/chromium/components/webdata/common/web_database_service.cc b/chromium/components/webdata/common/web_database_service.cc index 3ecd6f3ac6c..79bc298022c 100644 --- a/chromium/components/webdata/common/web_database_service.cc +++ b/chromium/components/webdata/common/web_database_service.cc @@ -27,12 +27,11 @@ class WebDatabaseService::BackendDelegate : web_database_service_(web_database_service), callback_thread_(base::ThreadTaskRunnerHandle::Get()) {} - void DBLoaded(sql::InitStatus status) override { + void DBLoaded(sql::InitStatus status, + const std::string& diagnostics) override { callback_thread_->PostTask( - FROM_HERE, - base::Bind(&WebDatabaseService::OnDatabaseLoadDone, - web_database_service_, - status)); + FROM_HERE, base::Bind(&WebDatabaseService::OnDatabaseLoadDone, + web_database_service_, status, diagnostics)); } private: const base::WeakPtr<WebDatabaseService> web_database_service_; @@ -133,23 +132,33 @@ void WebDatabaseService::RegisterDBErrorCallback( error_callbacks_.push_back(callback); } -void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status) { - if (status == sql::INIT_OK) { - db_loaded_ = true; - - for (size_t i = 0; i < loaded_callbacks_.size(); i++) { - if (!loaded_callbacks_[i].is_null()) - loaded_callbacks_[i].Run(); - } - - loaded_callbacks_.clear(); - } else { +void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status, + const std::string& diagnostics) { + // The INIT_OK_WITH_DATA_LOSS status is an initialization success but with + // suspected data loss, so we also run the error callbacks. + if (status != sql::INIT_OK) { // Notify that the database load failed. - for (size_t i = 0; i < error_callbacks_.size(); i++) { - if (!error_callbacks_[i].is_null()) - error_callbacks_[i].Run(status); + while (!error_callbacks_.empty()) { + // The profile error callback is a message box that runs in a nested run + // loop. While it's being displayed, other OnDatabaseLoadDone() will run + // (posted from WebDatabaseBackend::Delegate::DBLoaded()). We need to make + // sure that after the callback running the message box returns, it checks + // |error_callbacks_| before it accesses it. + DBLoadErrorCallback error_callback = error_callbacks_.back(); + error_callbacks_.pop_back(); + if (!error_callback.is_null()) + error_callback.Run(status, diagnostics); } + } + + if (status == sql::INIT_OK || status == sql::INIT_OK_WITH_DATA_LOSS) { + db_loaded_ = true; - error_callbacks_.clear(); + while (!loaded_callbacks_.empty()) { + DBLoadedCallback loaded_callback = loaded_callbacks_.back(); + loaded_callbacks_.pop_back(); + if (!loaded_callback.is_null()) + loaded_callback.Run(); + } } } diff --git a/chromium/components/webdata/common/web_database_service.h b/chromium/components/webdata/common/web_database_service.h index 2c68a3b0105..5ce19a05709 100644 --- a/chromium/components/webdata/common/web_database_service.h +++ b/chromium/components/webdata/common/web_database_service.h @@ -50,12 +50,13 @@ class WebDataServiceConsumer; class WEBDATA_EXPORT WebDatabaseService : public base::RefCountedDeleteOnMessageLoop<WebDatabaseService> { public: - typedef base::Callback<std::unique_ptr<WDTypedResult>(WebDatabase*)> ReadTask; - typedef base::Callback<WebDatabase::State(WebDatabase*)> WriteTask; + using ReadTask = base::Callback<std::unique_ptr<WDTypedResult>(WebDatabase*)>; + using WriteTask = base::Callback<WebDatabase::State(WebDatabase*)>; // Types for managing DB loading callbacks. - typedef base::Closure DBLoadedCallback; - typedef base::Callback<void(sql::InitStatus)> DBLoadErrorCallback; + using DBLoadedCallback = base::Closure; + using DBLoadErrorCallback = + base::Callback<void(sql::InitStatus, const std::string&)>; // Takes the path to the WebDatabase file. // WebDatabaseService lives on |ui_thread| and posts tasks to |db_thread|. @@ -119,12 +120,13 @@ class WEBDATA_EXPORT WebDatabaseService friend class base::RefCountedDeleteOnMessageLoop<WebDatabaseService>; friend class base::DeleteHelper<WebDatabaseService>; - typedef std::vector<DBLoadedCallback> LoadedCallbacks; - typedef std::vector<DBLoadErrorCallback> ErrorCallbacks; + using LoadedCallbacks = std::vector<DBLoadedCallback>; + using ErrorCallbacks = std::vector<DBLoadErrorCallback>; virtual ~WebDatabaseService(); - void OnDatabaseLoadDone(sql::InitStatus status); + void OnDatabaseLoadDone(sql::InitStatus status, + const std::string& diagnostics); base::FilePath path_; |