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
ChromeAutofillClient(content::WebContents * web_contents)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
~ChromeAutofillClient()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
TabActivated()68 void ChromeAutofillClient::TabActivated() {
69 if (dialog_controller_.get())
70 dialog_controller_->TabActivated();
71 }
72
GetPersonalDataManager()73 PersonalDataManager* ChromeAutofillClient::GetPersonalDataManager() {
74 Profile* profile =
75 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
76 return PersonalDataManagerFactory::GetForProfile(
77 profile->GetOriginalProfile());
78 }
79
GetDatabase()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
GetPrefs()87 PrefService* ChromeAutofillClient::GetPrefs() {
88 return Profile::FromBrowserContext(web_contents_->GetBrowserContext())
89 ->GetPrefs();
90 }
91
ShowAutofillSettings()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
ConfirmSaveCreditCard(const AutofillMetrics & metric_logger,const base::Closure & save_card_callback)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
ShowRequestAutocompleteDialog(const FormData & form,const GURL & source_url,const ResultCallback & callback)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
ShowAutofillPopup(const gfx::RectF & element_bounds,base::i18n::TextDirection text_direction,const std::vector<base::string16> & values,const std::vector<base::string16> & labels,const std::vector<base::string16> & icons,const std::vector<int> & identifiers,base::WeakPtr<AutofillPopupDelegate> delegate)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
UpdateAutofillPopupDataListValues(const std::vector<base::string16> & values,const std::vector<base::string16> & labels)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
HideAutofillPopup()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
IsAutocompleteEnabled()173 bool ChromeAutofillClient::IsAutocompleteEnabled() {
174 // For browser, Autocomplete is always enabled as part of Autofill.
175 return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
176 }
177
HideRequestAutocompleteDialog()178 void ChromeAutofillClient::HideRequestAutocompleteDialog() {
179 if (dialog_controller_.get())
180 dialog_controller_->Hide();
181 }
182
WebContentsDestroyed()183 void ChromeAutofillClient::WebContentsDestroyed() {
184 HideAutofillPopup();
185 }
186
OnZoomChanged(const ZoomController::ZoomChangedEventData & data)187 void ChromeAutofillClient::OnZoomChanged(
188 const ZoomController::ZoomChangedEventData& data) {
189 HideAutofillPopup();
190 }
191
DetectAccountCreationForms(const std::vector<autofill::FormStructure * > & forms)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
DidFillOrPreviewField(const base::string16 & autofilled_value,const base::string16 & profile_full_name)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