1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "android_webview/browser/aw_form_database_service.h" 6 #include "base/logging.h" 7 #include "base/synchronization/waitable_event.h" 8 #include "components/autofill/core/browser/webdata/autofill_table.h" 9 #include "components/webdata/common/webdata_constants.h" 10 #include "content/public/browser/browser_thread.h" 11 #include "ui/base/l10n/l10n_util_android.h" 12 13 using base::WaitableEvent; 14 using content::BrowserThread; 15 16 namespace { 17 18 // Callback to handle database error. It seems chrome uses this to 19 // display an error dialog box only. 20 void DatabaseErrorCallback(sql::InitStatus status) { 21 LOG(WARNING) << "initializing autocomplete database failed"; 22 } 23 24 } // namespace 25 26 namespace android_webview { 27 28 AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path) { 29 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 30 web_database_ = new WebDatabaseService(path.Append(kWebDataFilename), 31 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 32 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)); 33 web_database_->AddTable( 34 scoped_ptr<WebDatabaseTable>(new autofill::AutofillTable( 35 l10n_util::GetDefaultLocale()))); 36 web_database_->LoadDatabase(); 37 38 autofill_data_ = new autofill::AutofillWebDataService( 39 web_database_, 40 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 41 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), 42 base::Bind(&DatabaseErrorCallback)); 43 autofill_data_->Init(); 44 } 45 46 AwFormDatabaseService::~AwFormDatabaseService() { 47 Shutdown(); 48 } 49 50 void AwFormDatabaseService::Shutdown() { 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 52 DCHECK(result_map_.empty()); 53 // TODO(sgurun) we don't run into this logic right now, 54 // but if we do, then we need to implement cancellation 55 // of pending queries. 56 autofill_data_->ShutdownOnUIThread(); 57 web_database_->ShutdownDatabase(); 58 } 59 60 scoped_refptr<autofill::AutofillWebDataService> 61 AwFormDatabaseService::get_autofill_webdata_service() { 62 return autofill_data_; 63 } 64 65 void AwFormDatabaseService::ClearFormData() { 66 BrowserThread::PostTask( 67 BrowserThread::DB, 68 FROM_HERE, 69 base::Bind(&AwFormDatabaseService::ClearFormDataImpl, 70 base::Unretained(this))); 71 } 72 73 void AwFormDatabaseService::ClearFormDataImpl() { 74 base::Time begin; 75 base::Time end = base::Time::Max(); 76 autofill_data_->RemoveFormElementsAddedBetween(begin, end); 77 autofill_data_->RemoveAutofillDataModifiedBetween(begin, end); 78 } 79 80 bool AwFormDatabaseService::HasFormData() { 81 WaitableEvent completion(false, false); 82 bool result = false; 83 BrowserThread::PostTask( 84 BrowserThread::DB, 85 FROM_HERE, 86 base::Bind(&AwFormDatabaseService::HasFormDataImpl, 87 base::Unretained(this), 88 &completion, 89 &result)); 90 completion.Wait(); 91 return result; 92 } 93 94 void AwFormDatabaseService::HasFormDataImpl( 95 WaitableEvent* completion, 96 bool* result) { 97 WebDataServiceBase::Handle pending_query_handle = 98 autofill_data_->HasFormElements(this); 99 PendingQuery query; 100 query.result = result; 101 query.completion = completion; 102 result_map_[pending_query_handle] = query; 103 } 104 105 void AwFormDatabaseService::OnWebDataServiceRequestDone( 106 WebDataServiceBase::Handle h, 107 const WDTypedResult* result) { 108 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 110 bool has_form_data = false; 111 if (result) { 112 DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType()); 113 const WDResult<bool>* autofill_result = 114 static_cast<const WDResult<bool>*>(result); 115 has_form_data = autofill_result->GetValue(); 116 } 117 QueryMap::const_iterator it = result_map_.find(h); 118 if (it == result_map_.end()) { 119 LOG(WARNING) << "Received unexpected callback from web data service"; 120 return; 121 } 122 *(it->second.result) = has_form_data; 123 it->second.completion->Signal(); 124 result_map_.erase(h); 125 } 126 127 } // namespace android_webview 128