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 35DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::ChromeAutofillClient); 36 37namespace autofill { 38 39ChromeAutofillClient::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 57ChromeAutofillClient::~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 68void ChromeAutofillClient::TabActivated() { 69 if (dialog_controller_.get()) 70 dialog_controller_->TabActivated(); 71} 72 73PersonalDataManager* ChromeAutofillClient::GetPersonalDataManager() { 74 Profile* profile = 75 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); 76 return PersonalDataManagerFactory::GetForProfile( 77 profile->GetOriginalProfile()); 78} 79 80scoped_refptr<AutofillWebDataService> ChromeAutofillClient::GetDatabase() { 81 Profile* profile = 82 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); 83 return WebDataServiceFactory::GetAutofillWebDataForProfile( 84 profile, Profile::EXPLICIT_ACCESS); 85} 86 87PrefService* ChromeAutofillClient::GetPrefs() { 88 return Profile::FromBrowserContext(web_contents_->GetBrowserContext()) 89 ->GetPrefs(); 90} 91 92void 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 102void 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 111void 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 129void 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 154void 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 161void 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 173bool ChromeAutofillClient::IsAutocompleteEnabled() { 174 // For browser, Autocomplete is always enabled as part of Autofill. 175 return GetPrefs()->GetBoolean(prefs::kAutofillEnabled); 176} 177 178void ChromeAutofillClient::HideRequestAutocompleteDialog() { 179 if (dialog_controller_.get()) 180 dialog_controller_->Hide(); 181} 182 183void ChromeAutofillClient::WebContentsDestroyed() { 184 HideAutofillPopup(); 185} 186 187void ChromeAutofillClient::OnZoomChanged( 188 const ZoomController::ZoomChangedEventData& data) { 189 HideAutofillPopup(); 190} 191 192void 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 201void 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