- add sources.
[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 #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