Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: android_webview/browser/aw_form_database_service.cc

Issue 23803005: Fix threading issues in aw form database (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor comment update Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « android_webview/browser/aw_form_database_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 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 "android_webview/browser/aw_form_database_service.h" 5 #include "android_webview/browser/aw_form_database_service.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/synchronization/waitable_event.h"
7 #include "components/autofill/core/browser/webdata/autofill_table.h" 8 #include "components/autofill/core/browser/webdata/autofill_table.h"
8 #include "components/webdata/common/webdata_constants.h" 9 #include "components/webdata/common/webdata_constants.h"
9 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
10 #include "ui/base/l10n/l10n_util_android.h" 11 #include "ui/base/l10n/l10n_util_android.h"
11 12
13 using base::WaitableEvent;
12 using content::BrowserThread; 14 using content::BrowserThread;
13 15
14 namespace { 16 namespace {
15 17
16 // Callback to handle database error. It seems chrome uses this to 18 // Callback to handle database error. It seems chrome uses this to
17 // display an error dialog box only. 19 // display an error dialog box only.
18 void DatabaseErrorCallback(sql::InitStatus status) { 20 void DatabaseErrorCallback(sql::InitStatus status) {
19 LOG(WARNING) << "initializing autocomplete database failed"; 21 LOG(WARNING) << "initializing autocomplete database failed";
20 } 22 }
21 23
22 } // namespace 24 } // namespace
23 25
24 namespace android_webview { 26 namespace android_webview {
25 27
26 AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path) 28 AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path) {
27 : pending_query_handle_(0), 29 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
28 has_form_data_(false),
29 completion_(false, false) {
30
31 web_database_ = new WebDatabaseService(path.Append(kWebDataFilename), 30 web_database_ = new WebDatabaseService(path.Append(kWebDataFilename),
32 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 31 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
33 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)); 32 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB));
34 web_database_->AddTable( 33 web_database_->AddTable(
35 scoped_ptr<WebDatabaseTable>(new autofill::AutofillTable( 34 scoped_ptr<WebDatabaseTable>(new autofill::AutofillTable(
36 l10n_util::GetDefaultLocale()))); 35 l10n_util::GetDefaultLocale())));
37 web_database_->LoadDatabase(); 36 web_database_->LoadDatabase();
38 37
39 autofill_data_ = new autofill::AutofillWebDataService( 38 autofill_data_ = new autofill::AutofillWebDataService(
40 web_database_, base::Bind(&DatabaseErrorCallback)); 39 web_database_, base::Bind(&DatabaseErrorCallback));
41 autofill_data_->Init(); 40 autofill_data_->Init();
42 } 41 }
43 42
44 AwFormDatabaseService::~AwFormDatabaseService() { 43 AwFormDatabaseService::~AwFormDatabaseService() {
45 CancelPendingQuery();
46 Shutdown(); 44 Shutdown();
47 } 45 }
48 46
49 void AwFormDatabaseService::Shutdown() { 47 void AwFormDatabaseService::Shutdown() {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49 DCHECK(result_map_.empty());
50 // TODO(sgurun) we don't run into this logic right now,
51 // but if we do, then we need to implement cancellation
52 // of pending queries.
51 autofill_data_->ShutdownOnUIThread(); 53 autofill_data_->ShutdownOnUIThread();
52 web_database_->ShutdownDatabase(); 54 web_database_->ShutdownDatabase();
53 } 55 }
54 56
55 void AwFormDatabaseService::CancelPendingQuery() {
56 if (pending_query_handle_) {
57 if (autofill_data_.get())
58 autofill_data_->CancelRequest(pending_query_handle_);
59 pending_query_handle_ = 0;
60 }
61 }
62
63 scoped_refptr<autofill::AutofillWebDataService> 57 scoped_refptr<autofill::AutofillWebDataService>
64 AwFormDatabaseService::get_autofill_webdata_service() { 58 AwFormDatabaseService::get_autofill_webdata_service() {
65 return autofill_data_; 59 return autofill_data_;
66 } 60 }
67 61
68 void AwFormDatabaseService::ClearFormData() { 62 void AwFormDatabaseService::ClearFormData() {
63 BrowserThread::PostTask(
64 BrowserThread::DB,
65 FROM_HERE,
66 base::Bind(&AwFormDatabaseService::ClearFormDataImpl,
67 base::Unretained(this)));
68 }
69
70 void AwFormDatabaseService::ClearFormDataImpl() {
69 base::Time begin; 71 base::Time begin;
70 base::Time end = base::Time::Max(); 72 base::Time end = base::Time::Max();
71 autofill_data_->RemoveFormElementsAddedBetween(begin, end); 73 autofill_data_->RemoveFormElementsAddedBetween(begin, end);
72 autofill_data_->RemoveAutofillDataModifiedBetween(begin, end); 74 autofill_data_->RemoveAutofillDataModifiedBetween(begin, end);
73 } 75 }
74 76
75 bool AwFormDatabaseService::HasFormData() { 77 bool AwFormDatabaseService::HasFormData() {
76 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 78 WaitableEvent completion(false, false);
79 bool result = false;
80 BrowserThread::PostTask(
81 BrowserThread::DB,
82 FROM_HERE,
77 base::Bind(&AwFormDatabaseService::HasFormDataImpl, 83 base::Bind(&AwFormDatabaseService::HasFormDataImpl,
78 base::Unretained(this))); 84 base::Unretained(this),
79 completion_.Wait(); 85 &completion,
80 return has_form_data_; 86 &result));
87 completion.Wait();
88 return result;
81 } 89 }
82 90
83 void AwFormDatabaseService::HasFormDataImpl() { 91 void AwFormDatabaseService::HasFormDataImpl(
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 92 WaitableEvent* completion,
85 pending_query_handle_ = autofill_data_->HasFormElements(this); 93 bool* result) {
94 WebDataServiceBase::Handle pending_query_handle =
95 autofill_data_->HasFormElements(this);
96 PendingQuery query;
97 query.result = result;
98 query.completion = completion;
99 result_map_[pending_query_handle] = query;
86 } 100 }
87 101
88
89 void AwFormDatabaseService::OnWebDataServiceRequestDone( 102 void AwFormDatabaseService::OnWebDataServiceRequestDone(
90 WebDataServiceBase::Handle h, 103 WebDataServiceBase::Handle h,
91 const WDTypedResult* result) { 104 const WDTypedResult* result) {
92 105
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
94 DCHECK_EQ(pending_query_handle_, h); 107 bool has_form_data = false;
95 pending_query_handle_ = 0;
96 has_form_data_ = false;
97
98 if (result) { 108 if (result) {
99 DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType()); 109 DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType());
100 const WDResult<bool>* autofill_result = 110 const WDResult<bool>* autofill_result =
101 static_cast<const WDResult<bool>*>(result); 111 static_cast<const WDResult<bool>*>(result);
102 has_form_data_ = autofill_result->GetValue(); 112 has_form_data = autofill_result->GetValue();
103 } 113 }
104 completion_.Signal(); 114 QueryMap::const_iterator it = result_map_.find(h);
115 if (it == result_map_.end()) {
116 LOG(WARNING) << "Received unexpected callback from web data service";
117 return;
118 }
119 *(it->second.result) = has_form_data;
120 it->second.completion->Signal();
121 result_map_.erase(h);
105 } 122 }
106 123
107 } // namespace android_webview 124 } // namespace android_webview
OLDNEW
« no previous file with comments | « android_webview/browser/aw_form_database_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698