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