1// Copyright 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/native/aw_autofill_manager_delegate.h"
6
7#include "android_webview/browser/aw_browser_context.h"
8#include "android_webview/browser/aw_content_browser_client.h"
9#include "android_webview/browser/aw_pref_store.h"
10#include "android_webview/native/aw_contents.h"
11#include "base/android/jni_android.h"
12#include "base/android/jni_string.h"
13#include "base/android/scoped_java_ref.h"
14#include "base/logging.h"
15#include "base/prefs/pref_registry_simple.h"
16#include "base/prefs/pref_service.h"
17#include "base/prefs/pref_service_builder.h"
18#include "components/autofill/content/browser/autocheckout/whitelist_manager.h"
19#include "components/autofill/core/browser/autofill_popup_delegate.h"
20#include "components/autofill/core/common/autofill_pref_names.h"
21#include "components/user_prefs/user_prefs.h"
22#include "content/public/browser/web_contents.h"
23#include "content/public/browser/web_contents_view.h"
24#include "jni/AwAutofillManagerDelegate_jni.h"
25
26using base::android::AttachCurrentThread;
27using base::android::ConvertUTF16ToJavaString;
28using base::android::ScopedJavaLocalRef;
29using content::WebContents;
30
31DEFINE_WEB_CONTENTS_USER_DATA_KEY(android_webview::AwAutofillManagerDelegate);
32
33namespace android_webview {
34
35// Ownership: The native object is created (if autofill enabled) and owned by
36// AwContents. The native object creates the java peer which handles most
37// autofill functionality at the java side. The java peer is owned by Java
38// AwContents. The native object only maintains a weak ref to it.
39AwAutofillManagerDelegate::AwAutofillManagerDelegate(WebContents* contents)
40    : web_contents_(contents),
41      save_form_data_(false) {
42  JNIEnv* env = AttachCurrentThread();
43  ScopedJavaLocalRef<jobject> delegate;
44  delegate.Reset(
45      Java_AwAutofillManagerDelegate_create(env, reinterpret_cast<jint>(this)));
46
47  AwContents* aw_contents = AwContents::FromWebContents(web_contents_);
48  aw_contents->SetAwAutofillManagerDelegate(delegate.obj());
49  java_ref_ = JavaObjectWeakGlobalRef(env, delegate.obj());
50}
51
52AwAutofillManagerDelegate::~AwAutofillManagerDelegate() {
53  HideAutofillPopup();
54}
55
56void AwAutofillManagerDelegate::SetSaveFormData(bool enabled) {
57  save_form_data_ = enabled;
58}
59
60bool AwAutofillManagerDelegate::GetSaveFormData() {
61  return save_form_data_;
62}
63
64PrefService* AwAutofillManagerDelegate::GetPrefs() {
65  return user_prefs::UserPrefs::Get(
66      AwContentBrowserClient::GetAwBrowserContext());
67}
68
69autofill::PersonalDataManager*
70AwAutofillManagerDelegate::GetPersonalDataManager() {
71  return NULL;
72}
73
74autofill::autocheckout::WhitelistManager*
75AwAutofillManagerDelegate::GetAutocheckoutWhitelistManager() const {
76  return NULL;
77}
78
79void AwAutofillManagerDelegate::ShowAutofillPopup(
80    const gfx::RectF& element_bounds,
81    base::i18n::TextDirection text_direction,
82    const std::vector<string16>& values,
83    const std::vector<string16>& labels,
84    const std::vector<string16>& icons,
85    const std::vector<int>& identifiers,
86    base::WeakPtr<autofill::AutofillPopupDelegate> delegate) {
87
88  values_ = values;
89  identifiers_ = identifiers;
90  delegate_ = delegate;
91
92  // Convert element_bounds to be in screen space.
93  gfx::Rect client_area;
94  web_contents_->GetView()->GetContainerBounds(&client_area);
95  gfx::RectF element_bounds_in_screen_space =
96      element_bounds + client_area.OffsetFromOrigin();
97
98  ShowAutofillPopupImpl(element_bounds_in_screen_space,
99                        values,
100                        labels,
101                        identifiers);
102}
103
104void AwAutofillManagerDelegate::ShowAutofillPopupImpl(
105    const gfx::RectF& element_bounds,
106    const std::vector<string16>& values,
107    const std::vector<string16>& labels,
108    const std::vector<int>& identifiers) {
109  JNIEnv* env = AttachCurrentThread();
110  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
111  if (obj.is_null())
112    return;
113
114  // We need an array of AutofillSuggestion.
115  size_t count = values.size();
116
117  ScopedJavaLocalRef<jobjectArray> data_array =
118      Java_AwAutofillManagerDelegate_createAutofillSuggestionArray(env, count);
119
120  for (size_t i = 0; i < count; ++i) {
121    ScopedJavaLocalRef<jstring> name = ConvertUTF16ToJavaString(env, values[i]);
122    ScopedJavaLocalRef<jstring> label =
123        ConvertUTF16ToJavaString(env, labels[i]);
124    Java_AwAutofillManagerDelegate_addToAutofillSuggestionArray(
125        env,
126        data_array.obj(),
127        i,
128        name.obj(),
129        label.obj(),
130        identifiers[i]);
131  }
132
133  Java_AwAutofillManagerDelegate_showAutofillPopup(
134      env,
135      obj.obj(),
136      element_bounds.x(),
137      element_bounds.y(), element_bounds.width(),
138      element_bounds.height(), data_array.obj());
139}
140
141void AwAutofillManagerDelegate::UpdateAutofillPopupDataListValues(
142    const std::vector<base::string16>& values,
143    const std::vector<base::string16>& labels) {
144  NOTIMPLEMENTED();
145}
146
147void AwAutofillManagerDelegate::HideAutofillPopup() {
148  JNIEnv* env = AttachCurrentThread();
149  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
150  if (obj.is_null())
151    return;
152  delegate_.reset();
153  Java_AwAutofillManagerDelegate_hideAutofillPopup(env, obj.obj());
154}
155
156bool AwAutofillManagerDelegate::IsAutocompleteEnabled() {
157  return GetSaveFormData();
158}
159
160void AwAutofillManagerDelegate::SuggestionSelected(JNIEnv* env,
161                                                   jobject object,
162                                                   jint position) {
163  if (delegate_)
164    delegate_->DidAcceptSuggestion(values_[position], identifiers_[position]);
165}
166
167void AwAutofillManagerDelegate::HideRequestAutocompleteDialog() {
168  NOTIMPLEMENTED();
169}
170
171void AwAutofillManagerDelegate::OnAutocheckoutError() {
172  NOTIMPLEMENTED();
173}
174
175void AwAutofillManagerDelegate::OnAutocheckoutSuccess() {
176  NOTIMPLEMENTED();
177}
178
179void AwAutofillManagerDelegate::ShowAutofillSettings() {
180  NOTIMPLEMENTED();
181}
182
183void AwAutofillManagerDelegate::ConfirmSaveCreditCard(
184    const autofill::AutofillMetrics& metric_logger,
185    const autofill::CreditCard& credit_card,
186    const base::Closure& save_card_callback) {
187  NOTIMPLEMENTED();
188}
189
190bool AwAutofillManagerDelegate::ShowAutocheckoutBubble(
191    const gfx::RectF& bounding_box,
192    bool is_google_user,
193    const base::Callback<void(autofill::AutocheckoutBubbleState)>& callback) {
194  NOTIMPLEMENTED();
195  return false;
196}
197
198void AwAutofillManagerDelegate::HideAutocheckoutBubble() {
199  NOTIMPLEMENTED();
200}
201
202void AwAutofillManagerDelegate::ShowRequestAutocompleteDialog(
203    const autofill::FormData& form,
204    const GURL& source_url,
205    autofill::DialogType dialog_type,
206    const base::Callback<void(const autofill::FormStructure*,
207                              const std::string&)>& callback) {
208  NOTIMPLEMENTED();
209}
210
211void AwAutofillManagerDelegate::AddAutocheckoutStep(
212    autofill::AutocheckoutStepType step_type) {
213  NOTIMPLEMENTED();
214}
215
216void AwAutofillManagerDelegate::UpdateAutocheckoutStep(
217    autofill::AutocheckoutStepType step_type,
218    autofill::AutocheckoutStepStatus step_status) {
219  NOTIMPLEMENTED();
220}
221
222bool RegisterAwAutofillManagerDelegate(JNIEnv* env) {
223  return RegisterNativesImpl(env) >= 0;
224}
225
226} // namespace android_webview
227