web_database_service.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_database_service.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_request_manager.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_results.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_service_backend.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_service_consumer.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::Bind; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::FilePath; 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Receives messages from the backend on the DB thread, posts them to 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// WebDatabaseService on the UI thread. 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebDatabaseService::BackendDelegate : 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public WebDataServiceBackend::Delegate { 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BackendDelegate( 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::WeakPtr<WebDatabaseService>& web_database_service) 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : web_database_service_(web_database_service), 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_thread_(base::MessageLoopProxy::current()) { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void DBLoaded(sql::InitStatus status) OVERRIDE { 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_thread_->PostTask( 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&WebDatabaseService::OnDatabaseLoadDone, 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_database_service_, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status)); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::WeakPtr<WebDatabaseService> web_database_service_; 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> callback_thread_; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDatabaseService::WebDatabaseService( 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::FilePath& path, 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& ui_thread, 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& db_thread) 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : base::RefCountedDeleteOnMessageLoop<WebDatabaseService>(ui_thread), 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) path_(path), 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_ptr_factory_(this), 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_loaded_(false), 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_(db_thread) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // WebDatabaseService should be instantiated on UI thread. 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(ui_thread->BelongsToCurrentThread()); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // WebDatabaseService requires DB thread if instantiated. 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(db_thread.get()); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDatabaseService::~WebDatabaseService() { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::AddTable(scoped_ptr<WebDatabaseTable> table) { 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_ = new WebDataServiceBackend( 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) path_, new BackendDelegate(weak_ptr_factory_.GetWeakPtr()), 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_->AddTable(table.Pass()); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::LoadDatabase() { 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(wds_backend_.get()); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask( 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::InitDatabase, wds_backend_)); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::UnloadDatabase() { 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_loaded_ = false; 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(FROM_HERE, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::ShutdownDatabase, 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_, true)); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::ShutdownDatabase() { 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_loaded_ = false; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.clear(); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.clear(); 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(FROM_HERE, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::ShutdownDatabase, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_, false)); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDatabase* WebDatabaseService::GetDatabaseOnDB() const { 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(db_thread_->BelongsToCurrentThread()); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return wds_backend_->database(); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_refptr<WebDataServiceBackend> WebDatabaseService::GetBackend() const { 104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return wds_backend_; 105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::ScheduleDBTask( 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const WriteTask& task) { 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) { 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "Task scheduled after Shutdown()"; 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request( 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new WebDataRequest(NULL, wds_backend_->request_manager().get())); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(from_here, 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::DBWriteTaskWrapper, wds_backend_, 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task, base::Passed(&request))); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult( 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ReadTask& task, 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebDataServiceConsumer* consumer) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(consumer); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebDataServiceBase::Handle handle = 0; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) { 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "Task scheduled after Shutdown()"; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return handle; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request( 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new WebDataRequest(consumer, wds_backend_->request_manager().get())); 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handle = request->GetHandle(); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(from_here, 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::DBReadTaskWrapper, wds_backend_, 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task, base::Passed(&request))); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return handle; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) { 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!wds_backend_.get()) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_->request_manager()->CancelRequest(h); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebDatabaseService::RegisterDBLoadedCallback( 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DBLoadedCallback& callback) { 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.push_back(callback); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebDatabaseService::RegisterDBErrorCallback( 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DBLoadErrorCallback& callback) { 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.push_back(callback); 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status) { 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status == sql::INIT_OK) { 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_loaded_ = true; 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < loaded_callbacks_.size(); i++) { 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!loaded_callbacks_[i].is_null()) 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_[i].Run(); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.clear(); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Notify that the database load failed. 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < error_callbacks_.size(); i++) { 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!error_callbacks_[i].is_null()) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_[i].Run(status); 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.clear(); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 182