summaryrefslogtreecommitdiffstats
path: root/components/webdata/common
diff options
context:
space:
mode:
authorcaitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-29 17:55:50 +0000
committercaitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-29 17:55:50 +0000
commitdfa114dabb2d62ef25bcc3799aa83c48b6aeae95 (patch)
treebe9a0befbc558fb966f30c2e08c9b05b8dfb6d8f /components/webdata/common
parent69921772fb52161c4f6bcf6d8048da946b3273df (diff)
downloadchromium_src-dfa114dabb2d62ef25bcc3799aa83c48b6aeae95.zip
chromium_src-dfa114dabb2d62ef25bcc3799aa83c48b6aeae95.tar.gz
chromium_src-dfa114dabb2d62ef25bcc3799aa83c48b6aeae95.tar.bz2
Use Observer to notify of WebDB load instead of callbacks. We were already partially doing this for Autofill, this CL just makes it so that all WebDB clients can use an observer interface, instead of passing callbacks.
Also: -Split WebDatabaseService and WebDataServiceBackend into separate files TBR=isherman@chromium.org,akalin@chromium.org (c/b/password_manager/, c/b/sync/) BUG=230920 Review URL: https://chromiumcodereview.appspot.com/14103021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197078 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/webdata/common')
-rw-r--r--components/webdata/common/web_data_service_backend.cc106
-rw-r--r--components/webdata/common/web_data_service_backend.h121
-rw-r--r--components/webdata/common/web_data_service_base.cc50
-rw-r--r--components/webdata/common/web_data_service_base.h19
-rw-r--r--components/webdata/common/web_database_observer.h26
-rw-r--r--components/webdata/common/web_database_service.cc220
-rw-r--r--components/webdata/common/web_database_service.h17
7 files changed, 347 insertions, 212 deletions
diff --git a/components/webdata/common/web_data_service_backend.cc b/components/webdata/common/web_data_service_backend.cc
new file mode 100644
index 0000000..3b945b0b
--- /dev/null
+++ b/components/webdata/common/web_data_service_backend.cc
@@ -0,0 +1,106 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/webdata/common/web_data_service_backend.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "components/webdata/common/web_data_request_manager.h"
+#include "components/webdata/common/web_database.h"
+#include "components/webdata/common/web_database_table.h"
+
+
+using base::Bind;
+using base::FilePath;
+using content::BrowserThread;
+
+WebDataServiceBackend::WebDataServiceBackend(
+ const FilePath& path, Delegate* delegate)
+ : db_path_(path),
+ request_manager_(new WebDataRequestManager()),
+ init_status_(sql::INIT_FAILURE),
+ init_complete_(false),
+ delegate_(delegate) {
+}
+
+void WebDataServiceBackend::AddTable(scoped_ptr<WebDatabaseTable> table) {
+ DCHECK(!db_.get());
+ tables_.push_back(table.release());
+}
+
+void WebDataServiceBackend::InitDatabase() {
+ LoadDatabaseIfNecessary();
+ if (delegate_) {
+ delegate_->DBLoaded(init_status_);
+ }
+}
+
+sql::InitStatus WebDataServiceBackend::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_;
+ }
+
+ db_->BeginTransaction();
+ return init_status_;
+}
+
+void WebDataServiceBackend::ShutdownDatabase(bool should_reinit) {
+ if (db_ && init_status_ == sql::INIT_OK)
+ db_->CommitTransaction();
+ db_.reset(NULL);
+ init_complete_ = !should_reinit; // Setting init_complete_ to true will ensure
+ // that the init sequence is not re-run.
+
+ init_status_ = sql::INIT_FAILURE;
+}
+
+void WebDataServiceBackend::DBWriteTaskWrapper(
+ const WebDatabaseService::WriteTask& task,
+ scoped_ptr<WebDataRequest> request) {
+ LoadDatabaseIfNecessary();
+ if (db_ && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
+ WebDatabase::State state = task.Run(db_.get());
+ if (state == WebDatabase::COMMIT_NEEDED)
+ Commit();
+ }
+ request_manager_->RequestCompleted(request.Pass());
+}
+
+void WebDataServiceBackend::DBReadTaskWrapper(
+ const WebDatabaseService::ReadTask& task,
+ scoped_ptr<WebDataRequest> request) {
+ LoadDatabaseIfNecessary();
+ if (db_ && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
+ request->SetResult(task.Run(db_.get()).Pass());
+ }
+ request_manager_->RequestCompleted(request.Pass());
+}
+
+WebDataServiceBackend::~WebDataServiceBackend() {
+ ShutdownDatabase(false);
+}
+
+void WebDataServiceBackend::Commit() {
+ if (db_ && init_status_ == sql::INIT_OK) {
+ db_->CommitTransaction();
+ db_->BeginTransaction();
+ } else {
+ NOTREACHED() << "Commit scheduled after Shutdown()";
+ }
+}
diff --git a/components/webdata/common/web_data_service_backend.h b/components/webdata/common/web_data_service_backend.h
new file mode 100644
index 0000000..0e1d8f2
--- /dev/null
+++ b/components/webdata/common/web_data_service_backend.h
@@ -0,0 +1,121 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_WEBDATA_COMMON_WEB_DATA_SERVICE_BACKEND_H_
+#define COMPONENTS_WEBDATA_COMMON_WEB_DATA_SERVICE_BACKEND_H_
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "components/webdata/common/web_database_service.h"
+#include "content/public/browser/browser_thread.h"
+
+
+class WebDatabase;
+class WebDatabaseTable;
+class WebDataRequest;
+class WebDataRequestManager;
+
+namespace tracked_objects {
+class Location;
+}
+
+// WebDataServiceBackend handles all database tasks posted by
+// WebDatabaseService. It is refcounted to allow asynchronous destruction on the
+// DB thread.
+
+class WebDataServiceBackend
+ : public base::RefCountedThreadSafe<
+ WebDataServiceBackend,
+ content::BrowserThread::DeleteOnDBThread> {
+ public:
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Invoked when the backend has finished loading the db.
+ virtual void DBLoaded(sql::InitStatus status) = 0;
+ };
+
+ explicit WebDataServiceBackend(const base::FilePath& path,
+ Delegate* delegate);
+
+ // Must call only before InitDatabaseWithCallback.
+ void AddTable(scoped_ptr<WebDatabaseTable> table);
+
+ // Initializes the database and notifies caller via callback when complete.
+ // 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 database. |should_reinit| tells us whether or not it should be
+ // possible to re-initialize the DB after the shutdown.
+ void ShutdownDatabase(bool should_reinit);
+
+ // Task wrappers to run database tasks.
+ void DBWriteTaskWrapper(
+ const WebDatabaseService::WriteTask& task,
+ scoped_ptr<WebDataRequest> request);
+ void DBReadTaskWrapper(
+ const WebDatabaseService::ReadTask& task,
+ scoped_ptr<WebDataRequest> request);
+
+ const scoped_refptr<WebDataRequestManager>& request_manager() {
+ return request_manager_;
+ }
+
+ WebDatabase* database() { return db_.get(); }
+
+ private:
+ friend struct content::BrowserThread::DeleteOnThread<
+ content::BrowserThread::DB>;
+ friend class base::DeleteHelper<WebDataServiceBackend>;
+
+ virtual ~WebDataServiceBackend();
+
+ // Commit the current transaction.
+ void Commit();
+
+ // Path to database file.
+ base::FilePath db_path_;
+
+ // The tables that participate in managing the database. These are
+ // owned here but other than that this class does nothing with
+ // them. Their initialization is in whatever factory creates
+ // WebDatabaseService, and lookup by type is provided by the
+ // WebDatabase class. The tables need to be owned by this refcounted
+ // object, or they themselves would need to be refcounted. Owning
+ // them here rather than having WebDatabase own them makes for
+ // easier unit testing of WebDatabase.
+ ScopedVector<WebDatabaseTable> tables_;
+
+ scoped_ptr<WebDatabase> db_;
+
+ // Keeps track of all pending requests made to the db.
+ scoped_refptr<WebDataRequestManager> request_manager_;
+
+ // State of database initialization. Used to prevent the executing of tasks
+ // before the db is ready.
+ sql::InitStatus init_status_;
+
+ // True if an attempt has been made to load the database (even if the attempt
+ // fails), used to avoid continually trying to reinit if the db init fails.
+ bool init_complete_;
+
+ // Delegate. See the class definition above for more information.
+ scoped_ptr<Delegate> delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebDataServiceBackend);
+};
+
+#endif // COMPONENTS_WEBDATA_COMMON_WEB_DATA_SERVICE_BACKEND_H_
diff --git a/components/webdata/common/web_data_service_base.cc b/components/webdata/common/web_data_service_base.cc
index 58e9873..e1a67a5 100644
--- a/components/webdata/common/web_data_service_base.cc
+++ b/components/webdata/common/web_data_service_base.cc
@@ -34,6 +34,15 @@ WebDataServiceBase::WebDataServiceBase(scoped_refptr<WebDatabaseService> wdbs,
DCHECK(BrowserThread::IsWellKnownThread(BrowserThread::DB));
}
+void WebDataServiceBase::WebDatabaseLoaded() {
+ db_loaded_ = true;
+}
+
+void WebDataServiceBase::WebDatabaseLoadFailed(sql::InitStatus status) {
+ if (!profile_error_callback_.is_null())
+ profile_error_callback_.Run(status);
+}
+
void WebDataServiceBase::ShutdownOnUIThread() {
db_loaded_ = false;
BrowserThread::PostTask(
@@ -43,7 +52,8 @@ void WebDataServiceBase::ShutdownOnUIThread() {
void WebDataServiceBase::Init() {
DCHECK(wdbs_.get());
- wdbs_->LoadDatabase(Bind(&WebDataServiceBase::DatabaseInitOnDB, this));
+ wdbs_->AddObserver(this);
+ wdbs_->LoadDatabase();
}
void WebDataServiceBase::UnloadDatabase() {
@@ -72,6 +82,18 @@ bool WebDataServiceBase::IsDatabaseLoaded() {
return db_loaded_;
}
+void WebDataServiceBase::AddDBObserver(WebDatabaseObserver* observer) {
+ if (!wdbs_)
+ return;
+ wdbs_->AddObserver(observer);
+}
+
+void WebDataServiceBase::RemoveDBObserver(WebDatabaseObserver* observer) {
+ if (!wdbs_)
+ return;
+ wdbs_->RemoveObserver(observer);
+}
+
WebDatabase* WebDataServiceBase::GetDatabase() {
if (!wdbs_)
return NULL;
@@ -93,29 +115,3 @@ void WebDataServiceBase::ShutdownOnDBThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
db_thread_user_data_.reset();
}
-
-void WebDataServiceBase::NotifyDatabaseLoadedOnUIThread() {}
-
-void WebDataServiceBase::DBInitFailed(sql::InitStatus sql_status) {
- if (!profile_error_callback_.is_null())
- profile_error_callback_.Run(sql_status);
-}
-
-void WebDataServiceBase::DBInitSucceeded() {
- db_loaded_ = true;
- NotifyDatabaseLoadedOnUIThread();
-}
-
-// Executed on DB thread.
-void WebDataServiceBase::DatabaseInitOnDB(sql::InitStatus status) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- if (status == sql::INIT_OK) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&WebDataServiceBase::DBInitSucceeded, this));
- } else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&WebDataServiceBase::DBInitFailed, this, status));
- }
-}
diff --git a/components/webdata/common/web_data_service_base.h b/components/webdata/common/web_data_service_base.h
index dec0a0d..2ce81a0 100644
--- a/components/webdata/common/web_data_service_base.h
+++ b/components/webdata/common/web_data_service_base.h
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/supports_user_data.h"
+#include "components/webdata/common/web_database_observer.h"
#include "components/webdata/common/webdata_export.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
@@ -25,7 +26,8 @@ class Thread;
// Base for WebDataService class hierarchy.
class WEBDATA_EXPORT WebDataServiceBase
- : public base::RefCountedThreadSafe<WebDataServiceBase,
+ : public WebDatabaseObserver,
+ public base::RefCountedThreadSafe<WebDataServiceBase,
content::BrowserThread::DeleteOnUIThread> {
public:
// All requests return an opaque handle of the following type.
@@ -49,6 +51,10 @@ class WEBDATA_EXPORT WebDataServiceBase
WebDataServiceBase(scoped_refptr<WebDatabaseService> wdbs,
const ProfileErrorCallback& callback);
+ // WebDatabaseObserver implementation.
+ virtual void WebDatabaseLoaded() OVERRIDE;
+ virtual void WebDatabaseLoadFailed(sql::InitStatus status) OVERRIDE;
+
// Cancel any pending request. You need to call this method if your
// WebDataServiceConsumer is about to be deleted.
virtual void CancelRequest(Handle h);
@@ -71,6 +77,9 @@ class WEBDATA_EXPORT WebDataServiceBase
// Unloads the database permanently and shuts down service.
void ShutdownDatabase();
+ virtual void AddDBObserver(WebDatabaseObserver* observer);
+ virtual void RemoveDBObserver(WebDatabaseObserver* observer);
+
// Returns true if the database load has completetd successfully, and
// ShutdownOnUIThread has not yet been called.
virtual bool IsDatabaseLoaded();
@@ -122,14 +131,6 @@ class WEBDATA_EXPORT WebDataServiceBase
// be used e.g. for SyncableService subclasses that need to be owned
// by this object. Is created on first call to |GetDBUserData()|.
scoped_ptr<SupportsUserDataAggregatable> db_thread_user_data_;
-
- // Called after database is successfully loaded. By default this function does
- // nothing. Subclasses can override to support notification.
- virtual void NotifyDatabaseLoadedOnUIThread();
-
- void DBInitFailed(sql::InitStatus sql_status);
- void DBInitSucceeded();
- void DatabaseInitOnDB(sql::InitStatus status);
};
#endif // COMPONENTS_WEBDATA_COMMON_WEB_DATA_SERVICE_BASE_H_
diff --git a/components/webdata/common/web_database_observer.h b/components/webdata/common/web_database_observer.h
new file mode 100644
index 0000000..5ea8002
--- /dev/null
+++ b/components/webdata/common/web_database_observer.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_OBSERVER_H_
+#define COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_OBSERVER_H_
+
+#include "components/webdata/common/webdata_export.h"
+#include "sql/init_status.h"
+
+// WebDatabase loads asynchronously on the DB thread. Clients on the UI thread
+// can use this interface to be notified when the load is complete, or if it
+// fails.
+class WEBDATA_EXPORT WebDatabaseObserver {
+ public:
+ // Called when DB has been loaded successfully.
+ virtual void WebDatabaseLoaded() = 0;
+ // Called when load failed. |status| contains error code.
+ virtual void WebDatabaseLoadFailed(sql::InitStatus status) {};
+
+ protected:
+ virtual ~WebDatabaseObserver() {}
+};
+
+
+#endif // COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_OBSERVER_H_
diff --git a/components/webdata/common/web_database_service.cc b/components/webdata/common/web_database_service.cc
index a1c8c71..da5517b 100644
--- a/components/webdata/common/web_database_service.cc
+++ b/components/webdata/common/web_database_service.cc
@@ -6,192 +6,41 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/memory/scoped_vector.h"
#include "components/webdata/common/web_data_request_manager.h"
#include "components/webdata/common/web_data_results.h"
+#include "components/webdata/common/web_data_service_backend.h"
#include "components/webdata/common/web_data_service_consumer.h"
using base::Bind;
using base::FilePath;
using content::BrowserThread;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// WebDataServiceBackend implementation.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-// Refcounted to allow asynchronous destruction on the DB thread.
-class WebDataServiceBackend
- : public base::RefCountedThreadSafe<WebDataServiceBackend,
- BrowserThread::DeleteOnDBThread> {
+// Receives messages from the backend on the DB thread, posts them to
+// WebDatabaseService on the UI thread.
+class WebDatabaseService::BackendDelegate :
+ public WebDataServiceBackend::Delegate {
public:
- explicit WebDataServiceBackend(const FilePath& path);
-
- // Must call only before InitDatabaseWithCallback.
- void AddTable(scoped_ptr<WebDatabaseTable> table);
-
- // Initializes the database and notifies caller via callback when complete.
- // Callback is called synchronously.
- void InitDatabaseWithCallback(
- const WebDatabaseService::InitCallback& callback);
-
- // 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 database. |should_reinit| tells us whether or not it should be
- // possible to re-initialize the DB after the shutdown.
- void ShutdownDatabase(bool should_reinit);
-
- // Task wrappers to run database tasks.
- void DBWriteTaskWrapper(
- const WebDatabaseService::WriteTask& task,
- scoped_ptr<WebDataRequest> request);
- void DBReadTaskWrapper(
- const WebDatabaseService::ReadTask& task,
- scoped_ptr<WebDataRequest> request);
-
- const scoped_refptr<WebDataRequestManager>& request_manager() {
- return request_manager_;
+ BackendDelegate(
+ const base::WeakPtr<WebDatabaseService>& web_database_service)
+ : web_database_service_(web_database_service) {
}
- WebDatabase* database() { return db_.get(); }
-
+ virtual void DBLoaded(sql::InitStatus status) OVERRIDE {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&WebDatabaseService::OnDatabaseLoadDone,
+ web_database_service_,
+ status));
+ }
private:
- friend struct BrowserThread::DeleteOnThread<BrowserThread::DB>;
- friend class base::DeleteHelper<WebDataServiceBackend>;
-
- virtual ~WebDataServiceBackend();
-
- // Commit the current transaction.
- void Commit();
-
- // Path to database file.
- FilePath db_path_;
-
- // The tables that participate in managing the database. These are
- // owned here but other than that this class does nothing with
- // them. Their initialization is in whatever factory creates
- // WebDatabaseService, and lookup by type is provided by the
- // WebDatabase class. The tables need to be owned by this refcounted
- // object, or they themselves would need to be refcounted. Owning
- // them here rather than having WebDatabase own them makes for
- // easier unit testing of WebDatabase.
- ScopedVector<WebDatabaseTable> tables_;
-
- scoped_ptr<WebDatabase> db_;
-
- // Keeps track of all pending requests made to the db.
- scoped_refptr<WebDataRequestManager> request_manager_;
-
- // State of database initialization. Used to prevent the executing of tasks
- // before the db is ready.
- sql::InitStatus init_status_;
-
- // True if an attempt has been made to load the database (even if the attempt
- // fails), used to avoid continually trying to reinit if the db init fails.
- bool init_complete_;
-
- DISALLOW_COPY_AND_ASSIGN(WebDataServiceBackend);
+ const base::WeakPtr<WebDatabaseService> web_database_service_;
};
-WebDataServiceBackend::WebDataServiceBackend(
- const FilePath& path)
- : db_path_(path),
- request_manager_(new WebDataRequestManager()),
- init_status_(sql::INIT_FAILURE),
- init_complete_(false) {
-}
-
-void WebDataServiceBackend::AddTable(scoped_ptr<WebDatabaseTable> table) {
- DCHECK(!db_.get());
- tables_.push_back(table.release());
-}
-
-void WebDataServiceBackend::InitDatabaseWithCallback(
- const WebDatabaseService::InitCallback& callback) {
- if (!callback.is_null()) {
- callback.Run(LoadDatabaseIfNecessary());
- }
-}
-
-sql::InitStatus WebDataServiceBackend::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_;
- }
-
- db_->BeginTransaction();
- return init_status_;
-}
-
-void WebDataServiceBackend::ShutdownDatabase(bool should_reinit) {
- if (db_ && init_status_ == sql::INIT_OK)
- db_->CommitTransaction();
- db_.reset(NULL);
- init_complete_ = !should_reinit; // Setting init_complete_ to true will ensure
- // that the init sequence is not re-run.
-
- init_status_ = sql::INIT_FAILURE;
-}
-
-void WebDataServiceBackend::DBWriteTaskWrapper(
- const WebDatabaseService::WriteTask& task,
- scoped_ptr<WebDataRequest> request) {
- LoadDatabaseIfNecessary();
- if (db_ && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
- WebDatabase::State state = task.Run(db_.get());
- if (state == WebDatabase::COMMIT_NEEDED)
- Commit();
- }
- request_manager_->RequestCompleted(request.Pass());
-}
-
-void WebDataServiceBackend::DBReadTaskWrapper(
- const WebDatabaseService::ReadTask& task,
- scoped_ptr<WebDataRequest> request) {
- LoadDatabaseIfNecessary();
- if (db_ && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
- request->SetResult(task.Run(db_.get()).Pass());
- }
- request_manager_->RequestCompleted(request.Pass());
-}
-
-WebDataServiceBackend::~WebDataServiceBackend() {
- ShutdownDatabase(false);
-}
-
-void WebDataServiceBackend::Commit() {
- if (db_ && init_status_ == sql::INIT_OK) {
- db_->CommitTransaction();
- db_->BeginTransaction();
- } else {
- NOTREACHED() << "Commit scheduled after Shutdown()";
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
WebDatabaseService::WebDatabaseService(
const base::FilePath& path)
- : path_(path) {
+ : path_(path),
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
// WebDatabaseService should be instantiated on UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// WebDatabaseService requires DB thread if instantiated.
@@ -203,19 +52,19 @@ WebDatabaseService::~WebDatabaseService() {
void WebDatabaseService::AddTable(scoped_ptr<WebDatabaseTable> table) {
if (!wds_backend_) {
- wds_backend_ = new WebDataServiceBackend(path_);
+ wds_backend_ = new WebDataServiceBackend(
+ path_, new BackendDelegate(weak_ptr_factory_.GetWeakPtr()));
}
wds_backend_->AddTable(table.Pass());
}
-void WebDatabaseService::LoadDatabase(const InitCallback& callback) {
+void WebDatabaseService::LoadDatabase() {
DCHECK(wds_backend_);
BrowserThread::PostTask(
BrowserThread::DB,
FROM_HERE,
- Bind(&WebDataServiceBackend::InitDatabaseWithCallback,
- wds_backend_, callback));
+ Bind(&WebDataServiceBackend::InitDatabase, wds_backend_));
}
void WebDatabaseService::UnloadDatabase() {
@@ -229,6 +78,7 @@ void WebDatabaseService::UnloadDatabase() {
void WebDatabaseService::ShutdownDatabase() {
if (!wds_backend_)
return;
+ weak_ptr_factory_.InvalidateWeakPtrs();
BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
Bind(&WebDataServiceBackend::ShutdownDatabase,
wds_backend_, false));
@@ -285,3 +135,25 @@ void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) {
return;
wds_backend_->request_manager()->CancelRequest(h);
}
+
+void WebDatabaseService::AddObserver(WebDatabaseObserver* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void WebDatabaseService::RemoveObserver(WebDatabaseObserver* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
+void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status) {
+ if (status == sql::INIT_OK) {
+ // Notify that the database has been initialized.
+ FOR_EACH_OBSERVER(WebDatabaseObserver,
+ observer_list_,
+ WebDatabaseLoaded());
+ } else {
+ // Notify that the database load failed.
+ FOR_EACH_OBSERVER(WebDatabaseObserver,
+ observer_list_,
+ WebDatabaseLoadFailed(status));
+ }
+}
diff --git a/components/webdata/common/web_database_service.h b/components/webdata/common/web_database_service.h
index 624660d..1bdfca8 100644
--- a/components/webdata/common/web_database_service.h
+++ b/components/webdata/common/web_database_service.h
@@ -15,6 +15,8 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
#include "components/webdata/common/web_data_service_base.h"
#include "components/webdata/common/web_database.h"
#include "components/webdata/common/webdata_export.h"
@@ -49,7 +51,6 @@ class WEBDATA_EXPORT WebDatabaseService
public:
typedef base::Callback<scoped_ptr<WDTypedResult>(WebDatabase*)> ReadTask;
typedef base::Callback<WebDatabase::State(WebDatabase*)> WriteTask;
- typedef base::Callback<void(sql::InitStatus)> InitCallback;
// Takes the path to the WebDatabase file.
explicit WebDatabaseService(const base::FilePath& path);
@@ -61,7 +62,7 @@ class WEBDATA_EXPORT WebDatabaseService
// Initializes the web database service. Takes a callback which will return
// the status of the DB after the init.
- virtual void LoadDatabase(const InitCallback& callback);
+ virtual void LoadDatabase();
// Unloads the database without actually shutting down the service. This can
// be used to temporarily reduce the browser process' memory footprint.
@@ -90,21 +91,33 @@ class WEBDATA_EXPORT WebDatabaseService
// somewhere else.
virtual void CancelRequest(WebDataServiceBase::Handle h);
+ void AddObserver(WebDatabaseObserver* observer);
+ void RemoveObserver(WebDatabaseObserver* observer);
+
private:
+ class BackendDelegate;
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<WebDatabaseService>;
// We have to friend RCTS<> so WIN shared-lib build is happy (crbug/112250).
friend class base::RefCountedThreadSafe<WebDatabaseService,
content::BrowserThread::DeleteOnUIThread>;
+ friend class BackendDelegate;
virtual ~WebDatabaseService();
+ void OnDatabaseLoadDone(sql::InitStatus status);
+
base::FilePath path_;
// The primary owner is |WebDatabaseService| but is refcounted because
// PostTask on DB thread may outlive us.
scoped_refptr<WebDataServiceBackend> wds_backend_;
+
+ ObserverList<WebDatabaseObserver> observer_list_;
+
+ // All vended weak pointers are invalidated in ShutdownDatabase().
+ base::WeakPtrFactory<WebDatabaseService> weak_ptr_factory_;
};
#endif // COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_SERVICE_H_