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