| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/webdata/web_database_service.h" | 5 #include "chrome/browser/webdata/web_database_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/memory/scoped_vector.h" |
| 9 #include "chrome/browser/api/webdata/web_data_results.h" | 10 #include "chrome/browser/api/webdata/web_data_results.h" |
| 10 #include "chrome/browser/api/webdata/web_data_service_consumer.h" | 11 #include "chrome/browser/api/webdata/web_data_service_consumer.h" |
| 11 #include "chrome/browser/webdata/autofill_table.h" | |
| 12 #include "chrome/browser/webdata/keyword_table.h" | |
| 13 #include "chrome/browser/webdata/logins_table.h" | |
| 14 #include "chrome/browser/webdata/token_service_table.h" | |
| 15 #include "chrome/browser/webdata/web_apps_table.h" | |
| 16 #include "chrome/browser/webdata/web_data_request_manager.h" | 12 #include "chrome/browser/webdata/web_data_request_manager.h" |
| 17 #include "chrome/browser/webdata/web_data_service.h" | |
| 18 #include "chrome/browser/webdata/web_intents_table.h" | |
| 19 // TODO(caitkp): Remove this autofill dependency. | 13 // TODO(caitkp): Remove this autofill dependency. |
| 20 #include "components/autofill/browser/autofill_country.h" | 14 #include "components/autofill/browser/autofill_country.h" |
| 21 | 15 |
| 22 using base::Bind; | 16 using base::Bind; |
| 23 using base::FilePath; | 17 using base::FilePath; |
| 24 using content::BrowserThread; | 18 using content::BrowserThread; |
| 25 | 19 |
| 26 | 20 |
| 27 //////////////////////////////////////////////////////////////////////////////// | 21 //////////////////////////////////////////////////////////////////////////////// |
| 28 // | 22 // |
| 29 // WebDataServiceBackend implementation. | 23 // WebDataServiceBackend implementation. |
| 30 // | 24 // |
| 31 //////////////////////////////////////////////////////////////////////////////// | 25 //////////////////////////////////////////////////////////////////////////////// |
| 32 | 26 |
| 33 // Refcounted to allow asynchronous destruction on the DB thread. | 27 // Refcounted to allow asynchronous destruction on the DB thread. |
| 34 class WebDataServiceBackend | 28 class WebDataServiceBackend |
| 35 : public base::RefCountedThreadSafe<WebDataServiceBackend, | 29 : public base::RefCountedThreadSafe<WebDataServiceBackend, |
| 36 BrowserThread::DeleteOnDBThread> { | 30 BrowserThread::DeleteOnDBThread> { |
| 37 public: | 31 public: |
| 38 explicit WebDataServiceBackend(const FilePath& path); | 32 explicit WebDataServiceBackend(const FilePath& path); |
| 39 | 33 |
| 34 // Must call only before InitDatabaseWithCallback. |
| 35 void AddTable(scoped_ptr<WebDatabaseTable> table); |
| 36 |
| 40 // Initializes the database and notifies caller via callback when complete. | 37 // Initializes the database and notifies caller via callback when complete. |
| 41 // Callback is called synchronously. | 38 // Callback is called synchronously. |
| 42 void InitDatabaseWithCallback( | 39 void InitDatabaseWithCallback( |
| 43 const WebDatabaseService::InitCallback& callback); | 40 const WebDatabaseService::InitCallback& callback); |
| 44 | 41 |
| 45 // Opens the database file from the profile path if an init has not yet been | 42 // Opens the database file from the profile path if an init has not yet been |
| 46 // attempted. Separated from the constructor to ease construction/destruction | 43 // attempted. Separated from the constructor to ease construction/destruction |
| 47 // of this object on one thread but database access on the DB thread. Returns | 44 // of this object on one thread but database access on the DB thread. Returns |
| 48 // the status of the database. | 45 // the status of the database. |
| 49 sql::InitStatus LoadDatabaseIfNecessary(); | 46 sql::InitStatus LoadDatabaseIfNecessary(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 71 friend class base::DeleteHelper<WebDataServiceBackend>; | 68 friend class base::DeleteHelper<WebDataServiceBackend>; |
| 72 | 69 |
| 73 virtual ~WebDataServiceBackend(); | 70 virtual ~WebDataServiceBackend(); |
| 74 | 71 |
| 75 // Commit the current transaction. | 72 // Commit the current transaction. |
| 76 void Commit(); | 73 void Commit(); |
| 77 | 74 |
| 78 // Path to database file. | 75 // Path to database file. |
| 79 FilePath db_path_; | 76 FilePath db_path_; |
| 80 | 77 |
| 81 scoped_ptr<AutofillTable> autofill_table_; | 78 // The tables that participate in managing the database. These are |
| 82 scoped_ptr<KeywordTable> keyword_table_; | 79 // owned here but other than that this class does nothing with |
| 83 scoped_ptr<LoginsTable> logins_table_; | 80 // them. Their initialization is in whatever factory creates |
| 84 scoped_ptr<TokenServiceTable> token_service_table_; | 81 // WebDatabaseService, and lookup by type is provided by the |
| 85 scoped_ptr<WebAppsTable> web_apps_table_; | 82 // WebDatabase class. The tables need to be owned by this refcounted |
| 86 scoped_ptr<WebIntentsTable> web_intents_table_; | 83 // object, or they themselves would need to be refcounted. Owning |
| 84 // them here rather than having WebDatabase own them makes for |
| 85 // easier unit testing of WebDatabase. |
| 86 ScopedVector<WebDatabaseTable> tables_; |
| 87 | 87 |
| 88 scoped_ptr<WebDatabase> db_; | 88 scoped_ptr<WebDatabase> db_; |
| 89 | 89 |
| 90 // Keeps track of all pending requests made to the db. | 90 // Keeps track of all pending requests made to the db. |
| 91 scoped_refptr<WebDataRequestManager> request_manager_; | 91 scoped_refptr<WebDataRequestManager> request_manager_; |
| 92 | 92 |
| 93 // State of database initialization. Used to prevent the executing of tasks | 93 // State of database initialization. Used to prevent the executing of tasks |
| 94 // before the db is ready. | 94 // before the db is ready. |
| 95 sql::InitStatus init_status_; | 95 sql::InitStatus init_status_; |
| 96 | 96 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 107 }; | 107 }; |
| 108 | 108 |
| 109 WebDataServiceBackend::WebDataServiceBackend(const FilePath& path) | 109 WebDataServiceBackend::WebDataServiceBackend(const FilePath& path) |
| 110 : db_path_(path), | 110 : db_path_(path), |
| 111 request_manager_(new WebDataRequestManager()), | 111 request_manager_(new WebDataRequestManager()), |
| 112 init_status_(sql::INIT_FAILURE), | 112 init_status_(sql::INIT_FAILURE), |
| 113 init_complete_(false), | 113 init_complete_(false), |
| 114 app_locale_(AutofillCountry::ApplicationLocale()) { | 114 app_locale_(AutofillCountry::ApplicationLocale()) { |
| 115 } | 115 } |
| 116 | 116 |
| 117 void WebDataServiceBackend::AddTable(scoped_ptr<WebDatabaseTable> table) { |
| 118 DCHECK(!db_.get()); |
| 119 tables_.push_back(table.release()); |
| 120 } |
| 121 |
| 117 void WebDataServiceBackend::InitDatabaseWithCallback( | 122 void WebDataServiceBackend::InitDatabaseWithCallback( |
| 118 const WebDatabaseService::InitCallback& callback) { | 123 const WebDatabaseService::InitCallback& callback) { |
| 119 if (!callback.is_null()) { | 124 if (!callback.is_null()) { |
| 120 callback.Run(LoadDatabaseIfNecessary()); | 125 callback.Run(LoadDatabaseIfNecessary()); |
| 121 } | 126 } |
| 122 } | 127 } |
| 123 | 128 |
| 124 sql::InitStatus WebDataServiceBackend::LoadDatabaseIfNecessary() { | 129 sql::InitStatus WebDataServiceBackend::LoadDatabaseIfNecessary() { |
| 125 if (init_complete_ || db_path_.empty()) { | 130 if (init_complete_ || db_path_.empty()) { |
| 126 return init_status_; | 131 return init_status_; |
| 127 } | 132 } |
| 128 init_complete_ = true; | 133 init_complete_ = true; |
| 129 db_.reset(new WebDatabase()); | 134 db_.reset(new WebDatabase()); |
| 130 | 135 |
| 131 // All tables objects that participate in managing the database must | 136 for (ScopedVector<WebDatabaseTable>::iterator it = tables_.begin(); |
| 132 // be added here. | 137 it != tables_.end(); |
| 133 autofill_table_.reset(new AutofillTable()); | 138 ++it) { |
| 134 db_->AddTable(autofill_table_.get()); | 139 db_->AddTable(*it); |
| 135 | 140 } |
| 136 keyword_table_.reset(new KeywordTable()); | |
| 137 db_->AddTable(keyword_table_.get()); | |
| 138 | |
| 139 // TODO(mdm): We only really need the LoginsTable on Windows for IE7 password | |
| 140 // access, but for now, we still create it on all platforms since it deletes | |
| 141 // the old logins table. We can remove this after a while, e.g. in M22 or so. | |
| 142 logins_table_.reset(new LoginsTable()); | |
| 143 db_->AddTable(logins_table_.get()); | |
| 144 | |
| 145 token_service_table_.reset(new TokenServiceTable()); | |
| 146 db_->AddTable(token_service_table_.get()); | |
| 147 | |
| 148 web_apps_table_.reset(new WebAppsTable()); | |
| 149 db_->AddTable(web_apps_table_.get()); | |
| 150 | |
| 151 // TODO(thakis): Add a migration to delete the SQL table used by | |
| 152 // WebIntentsTable, then remove this. | |
| 153 web_intents_table_.reset(new WebIntentsTable()); | |
| 154 db_->AddTable(web_intents_table_.get()); | |
| 155 | 141 |
| 156 init_status_ = db_->Init(db_path_, app_locale_); | 142 init_status_ = db_->Init(db_path_, app_locale_); |
| 157 if (init_status_ != sql::INIT_OK) { | 143 if (init_status_ != sql::INIT_OK) { |
| 158 LOG(ERROR) << "Cannot initialize the web database: " << init_status_; | 144 LOG(ERROR) << "Cannot initialize the web database: " << init_status_; |
| 159 db_.reset(NULL); | 145 db_.reset(NULL); |
| 160 return init_status_; | 146 return init_status_; |
| 161 } | 147 } |
| 162 | 148 |
| 163 db_->BeginTransaction(); | 149 db_->BeginTransaction(); |
| 164 return init_status_; | 150 return init_status_; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 : path_(path) { | 200 : path_(path) { |
| 215 // WebDatabaseService should be instantiated on UI thread. | 201 // WebDatabaseService should be instantiated on UI thread. |
| 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 217 // WebDatabaseService requires DB thread if instantiated. | 203 // WebDatabaseService requires DB thread if instantiated. |
| 218 DCHECK(BrowserThread::IsWellKnownThread(BrowserThread::DB)); | 204 DCHECK(BrowserThread::IsWellKnownThread(BrowserThread::DB)); |
| 219 } | 205 } |
| 220 | 206 |
| 221 WebDatabaseService::~WebDatabaseService() { | 207 WebDatabaseService::~WebDatabaseService() { |
| 222 } | 208 } |
| 223 | 209 |
| 210 void WebDatabaseService::AddTable(scoped_ptr<WebDatabaseTable> table) { |
| 211 if (!wds_backend_) { |
| 212 wds_backend_ = new WebDataServiceBackend(path_); |
| 213 } |
| 214 wds_backend_->AddTable(table.Pass()); |
| 215 } |
| 216 |
| 224 void WebDatabaseService::LoadDatabase(const InitCallback& callback) { | 217 void WebDatabaseService::LoadDatabase(const InitCallback& callback) { |
| 225 if (!wds_backend_) | 218 DCHECK(wds_backend_); |
| 226 wds_backend_ = new WebDataServiceBackend(path_); | |
| 227 | 219 |
| 228 BrowserThread::PostTask( | 220 BrowserThread::PostTask( |
| 229 BrowserThread::DB, | 221 BrowserThread::DB, |
| 230 FROM_HERE, | 222 FROM_HERE, |
| 231 Bind(&WebDataServiceBackend::InitDatabaseWithCallback, | 223 Bind(&WebDataServiceBackend::InitDatabaseWithCallback, |
| 232 wds_backend_, callback)); | 224 wds_backend_, callback)); |
| 233 } | 225 } |
| 234 | 226 |
| 235 void WebDatabaseService::UnloadDatabase() { | 227 void WebDatabaseService::UnloadDatabase() { |
| 236 if (!wds_backend_) | 228 if (!wds_backend_) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 264 } | 256 } |
| 265 | 257 |
| 266 scoped_ptr<WebDataRequest> request( | 258 scoped_ptr<WebDataRequest> request( |
| 267 new WebDataRequest(NULL, wds_backend_->request_manager())); | 259 new WebDataRequest(NULL, wds_backend_->request_manager())); |
| 268 | 260 |
| 269 BrowserThread::PostTask(BrowserThread::DB, from_here, | 261 BrowserThread::PostTask(BrowserThread::DB, from_here, |
| 270 Bind(&WebDataServiceBackend::DBWriteTaskWrapper, wds_backend_, | 262 Bind(&WebDataServiceBackend::DBWriteTaskWrapper, wds_backend_, |
| 271 task, base::Passed(&request))); | 263 task, base::Passed(&request))); |
| 272 } | 264 } |
| 273 | 265 |
| 274 WebDataService::Handle WebDatabaseService::ScheduleDBTaskWithResult( | 266 WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult( |
| 275 const tracked_objects::Location& from_here, | 267 const tracked_objects::Location& from_here, |
| 276 const ReadTask& task, | 268 const ReadTask& task, |
| 277 WebDataServiceConsumer* consumer) { | 269 WebDataServiceConsumer* consumer) { |
| 278 DCHECK(consumer); | 270 DCHECK(consumer); |
| 279 WebDataService::Handle handle = 0; | 271 WebDataServiceBase::Handle handle = 0; |
| 280 | 272 |
| 281 if (!wds_backend_) { | 273 if (!wds_backend_) { |
| 282 NOTREACHED() << "Task scheduled after Shutdown()"; | 274 NOTREACHED() << "Task scheduled after Shutdown()"; |
| 283 return handle; | 275 return handle; |
| 284 } | 276 } |
| 285 | 277 |
| 286 scoped_ptr<WebDataRequest> request( | 278 scoped_ptr<WebDataRequest> request( |
| 287 new WebDataRequest(consumer, wds_backend_->request_manager())); | 279 new WebDataRequest(consumer, wds_backend_->request_manager())); |
| 288 handle = request->GetHandle(); | 280 handle = request->GetHandle(); |
| 289 | 281 |
| 290 BrowserThread::PostTask(BrowserThread::DB, from_here, | 282 BrowserThread::PostTask(BrowserThread::DB, from_here, |
| 291 Bind(&WebDataServiceBackend::DBReadTaskWrapper, wds_backend_, | 283 Bind(&WebDataServiceBackend::DBReadTaskWrapper, wds_backend_, |
| 292 task, base::Passed(&request))); | 284 task, base::Passed(&request))); |
| 293 | 285 |
| 294 return handle; | 286 return handle; |
| 295 } | 287 } |
| 296 | 288 |
| 297 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) { | 289 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) { |
| 298 if (!wds_backend_) | 290 if (!wds_backend_) |
| 299 return; | 291 return; |
| 300 wds_backend_->request_manager()->CancelRequest(h); | 292 wds_backend_->request_manager()->CancelRequest(h); |
| 301 } | 293 } |
| OLD | NEW |