Home | History | Annotate | Download | only in autofill
      1 // Copyright 2014 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 "chrome/browser/ui/autofill/chrome_autofill_client.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/prefs/pref_service.h"
      9 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
     10 #include "chrome/browser/autofill/personal_data_manager_factory.h"
     11 #include "chrome/browser/infobars/infobar_service.h"
     12 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
     15 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
     16 #include "chrome/browser/ui/browser.h"
     17 #include "chrome/browser/ui/browser_finder.h"
     18 #include "chrome/browser/ui/browser_window.h"
     19 #include "chrome/browser/ui/chrome_pages.h"
     20 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
     21 #include "chrome/browser/ui/zoom/zoom_controller.h"
     22 #include "chrome/browser/webdata/web_data_service_factory.h"
     23 #include "chrome/common/url_constants.h"
     24 #include "components/autofill/content/browser/content_autofill_driver.h"
     25 #include "components/autofill/content/common/autofill_messages.h"
     26 #include "components/autofill/core/common/autofill_pref_names.h"
     27 #include "content/public/browser/render_view_host.h"
     28 #include "ui/gfx/rect.h"
     29 
     30 #if defined(OS_ANDROID)
     31 #include "chrome/browser/android/chromium_application.h"
     32 #include "chrome/browser/ui/android/autofill/autofill_logger_android.h"
     33 #endif
     34 
     35 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::ChromeAutofillClient);
     36 
     37 namespace autofill {
     38 
     39 ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents)
     40     : content::WebContentsObserver(web_contents), web_contents_(web_contents) {
     41   DCHECK(web_contents);
     42   // Since ZoomController is also a WebContentsObserver, we need to be careful
     43   // about disconnecting from it since the relative order of destruction of
     44   // WebContentsObservers is not guaranteed. ZoomController silently clears
     45   // its ZoomObserver list during WebContentsDestroyed() so there's no need
     46   // to explicitly remove ourselves on destruction.
     47   ZoomController* zoom_controller =
     48       ZoomController::FromWebContents(web_contents);
     49   // There may not always be a ZoomController, e.g. on Android.
     50   if (zoom_controller)
     51     zoom_controller->AddObserver(this);
     52 #if defined(OS_MACOSX) && !defined(OS_IOS)
     53   RegisterForKeystoneNotifications();
     54 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
     55 }
     56 
     57 ChromeAutofillClient::~ChromeAutofillClient() {
     58   // NOTE: It is too late to clean up the autofill popup; that cleanup process
     59   // requires that the WebContents instance still be valid and it is not at
     60   // this point (in particular, the WebContentsImpl destructor has already
     61   // finished running and we are now in the base class destructor).
     62   DCHECK(!popup_controller_);
     63 #if defined(OS_MACOSX) && !defined(OS_IOS)
     64   UnregisterFromKeystoneNotifications();
     65 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
     66 }
     67 
     68 void ChromeAutofillClient::TabActivated() {
     69   if (dialog_controller_.get())
     70     dialog_controller_->TabActivated();
     71 }
     72 
     73 PersonalDataManager* ChromeAutofillClient::GetPersonalDataManager() {
     74   Profile* profile =
     75       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
     76   return PersonalDataManagerFactory::GetForProfile(
     77       profile->GetOriginalProfile());
     78 }
     79 
     80 scoped_refptr<AutofillWebDataService> ChromeAutofillClient::GetDatabase() {
     81   Profile* profile =
     82       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
     83   return WebDataServiceFactory::GetAutofillWebDataForProfile(
     84       profile, Profile::EXPLICIT_ACCESS);
     85 }
     86 
     87 PrefService* ChromeAutofillClient::GetPrefs() {
     88   return Profile::FromBrowserContext(web_contents_->GetBrowserContext())
     89       ->GetPrefs();
     90 }
     91 
     92 void ChromeAutofillClient::ShowAutofillSettings() {
     93 #if defined(OS_ANDROID)
     94   chrome::android::ChromiumApplication::ShowAutofillSettings();
     95 #else
     96   Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
     97   if (browser)
     98     chrome::ShowSettingsSubPage(browser, chrome::kAutofillSubPage);
     99 #endif  // #if defined(OS_ANDROID)
    100 }
    101 
    102 void ChromeAutofillClient::ConfirmSaveCreditCard(
    103     const AutofillMetrics& metric_logger,
    104     const base::Closure& save_card_callback) {
    105   InfoBarService* infobar_service =
    106       InfoBarService::FromWebContents(web_contents_);
    107   AutofillCCInfoBarDelegate::Create(
    108       infobar_service, &metric_logger, save_card_callback);
    109 }
    110 
    111 void ChromeAutofillClient::ShowRequestAutocompleteDialog(
    112     const FormData& form,
    113     const GURL& source_url,
    114     const ResultCallback& callback) {
    115   HideRequestAutocompleteDialog();
    116 
    117   dialog_controller_ = AutofillDialogController::Create(
    118       web_contents_, form, source_url, callback);
    119   if (dialog_controller_) {
    120     dialog_controller_->Show();
    121   } else {
    122     callback.Run(AutofillClient::AutocompleteResultErrorDisabled,
    123                  base::string16(),
    124                  NULL);
    125     NOTIMPLEMENTED();
    126   }
    127 }
    128 
    129 void ChromeAutofillClient::ShowAutofillPopup(
    130     const gfx::RectF& element_bounds,
    131     base::i18n::TextDirection text_direction,
    132     const std::vector<base::string16>& values,
    133     const std::vector<base::string16>& labels,
    134     const std::vector<base::string16>& icons,
    135     const std::vector<int>& identifiers,
    136     base::WeakPtr<AutofillPopupDelegate> delegate) {
    137   // Convert element_bounds to be in screen space.
    138   gfx::Rect client_area = web_contents_->GetContainerBounds();
    139   gfx::RectF element_bounds_in_screen_space =
    140       element_bounds + client_area.OffsetFromOrigin();
    141 
    142   // Will delete or reuse the old |popup_controller_|.
    143   popup_controller_ =
    144       AutofillPopupControllerImpl::GetOrCreate(popup_controller_,
    145                                                delegate,
    146                                                web_contents(),
    147                                                web_contents()->GetNativeView(),
    148                                                element_bounds_in_screen_space,
    149                                                text_direction);
    150 
    151   popup_controller_->Show(values, labels, icons, identifiers);
    152 }
    153 
    154 void ChromeAutofillClient::UpdateAutofillPopupDataListValues(
    155     const std::vector<base::string16>& values,
    156     const std::vector<base::string16>& labels) {
    157   if (popup_controller_.get())
    158     popup_controller_->UpdateDataListValues(values, labels);
    159 }
    160 
    161 void ChromeAutofillClient::HideAutofillPopup() {
    162   if (popup_controller_.get())
    163     popup_controller_->Hide();
    164 
    165   // Password generation popups behave in the same fashion and should also
    166   // be hidden.
    167   ChromePasswordManagerClient* password_client =
    168       ChromePasswordManagerClient::FromWebContents(web_contents_);
    169   if (password_client)
    170     password_client->HidePasswordGenerationPopup();
    171 }
    172 
    173 bool ChromeAutofillClient::IsAutocompleteEnabled() {
    174   // For browser, Autocomplete is always enabled as part of Autofill.
    175   return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
    176 }
    177 
    178 void ChromeAutofillClient::HideRequestAutocompleteDialog() {
    179   if (dialog_controller_.get())
    180     dialog_controller_->Hide();
    181 }
    182 
    183 void ChromeAutofillClient::WebContentsDestroyed() {
    184   HideAutofillPopup();
    185 }
    186 
    187 void ChromeAutofillClient::OnZoomChanged(
    188     const ZoomController::ZoomChangedEventData& data) {
    189   HideAutofillPopup();
    190 }
    191 
    192 void ChromeAutofillClient::DetectAccountCreationForms(
    193     const std::vector<autofill::FormStructure*>& forms) {
    194   password_manager::PasswordGenerationManager* manager =
    195       ChromePasswordManagerClient::GetGenerationManagerFromWebContents(
    196           web_contents_);
    197   if (manager)
    198     manager->DetectAccountCreationForms(forms);
    199 }
    200 
    201 void ChromeAutofillClient::DidFillOrPreviewField(
    202     const base::string16& autofilled_value,
    203     const base::string16& profile_full_name) {
    204 #if defined(OS_ANDROID)
    205   AutofillLoggerAndroid::DidFillOrPreviewField(autofilled_value,
    206                                                profile_full_name);
    207 #endif  // defined(OS_ANDROID)
    208 }
    209 
    210 }  // namespace autofill
    211