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), 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_loaded_(false), 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) db_thread_(db_thread), 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_(this) { 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) { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!wds_backend_) { 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() { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(wds_backend_); 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask( 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Bind(&WebDataServiceBackend::InitDatabase, wds_backend_)); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::ShutdownDatabase() { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_loaded_ = false; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.clear(); 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.clear(); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!wds_backend_) 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) db_thread_->PostTask( 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, Bind(&WebDataServiceBackend::ShutdownDatabase, wds_backend_)); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDatabase* WebDatabaseService::GetDatabaseOnDB() const { 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(db_thread_->BelongsToCurrentThread()); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return wds_backend_ ? wds_backend_->database() : NULL; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_refptr<WebDataServiceBackend> WebDatabaseService::GetBackend() const { 91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return wds_backend_; 92a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::ScheduleDBTask( 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const WriteTask& task) { 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(wds_backend_); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request( 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new WebDataRequest(NULL, wds_backend_->request_manager().get())); 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(from_here, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Bind(&WebDataServiceBackend::DBWriteTaskWrapper, 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wds_backend_, task, base::Passed(&request))); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult( 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ReadTask& task, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebDataServiceConsumer* consumer) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(consumer); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(wds_backend_); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request( 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new WebDataRequest(consumer, wds_backend_->request_manager().get())); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebDataServiceBase::Handle handle = request->GetHandle(); 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_thread_->PostTask(from_here, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Bind(&WebDataServiceBackend::DBReadTaskWrapper, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wds_backend_, task, base::Passed(&request))); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return handle; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) { 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!wds_backend_) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wds_backend_->request_manager()->CancelRequest(h); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebDatabaseService::RegisterDBLoadedCallback( 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DBLoadedCallback& callback) { 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.push_back(callback); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void WebDatabaseService::RegisterDBErrorCallback( 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DBLoadErrorCallback& callback) { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.push_back(callback); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status) { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status == sql::INIT_OK) { 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_loaded_ = true; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < loaded_callbacks_.size(); i++) { 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!loaded_callbacks_[i].is_null()) 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_[i].Run(); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loaded_callbacks_.clear(); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Notify that the database load failed. 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < error_callbacks_.size(); i++) { 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!error_callbacks_[i].is_null()) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_[i].Run(status); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callbacks_.clear(); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156