blob: c13fa9789d49f6968722c15ddc6fa6b212351c14 [file] [log] [blame]
[email protected]b4db6d42014-06-07 04:36:581// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]8d4cc15e2012-08-30 00:33:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]b4db6d42014-06-07 04:36:585#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
[email protected]8d4cc15e2012-08-30 00:33:106
7#include "base/logging.h"
[email protected]3853a4c2013-02-11 17:15:578#include "base/prefs/pref_service.h"
[email protected]6f3ccf52013-02-21 03:55:239#include "chrome/browser/autofill/personal_data_manager_factory.h"
mathp94e3f0b2015-03-18 00:16:1610#include "chrome/browser/browser_process.h"
[email protected]4a8adfa02013-03-19 22:37:4611#include "chrome/browser/infobars/infobar_service.h"
[email protected]7d7e0b72014-02-10 18:36:0512#include "chrome/browser/password_manager/chrome_password_manager_client.h"
[email protected]8d4cc15e2012-08-30 00:33:1013#include "chrome/browser/profiles/profile.h"
estade494f8e62015-01-26 23:28:1314#include "chrome/browser/signin/profile_identity_provider.h"
15#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16#include "chrome/browser/signin/signin_manager_factory.h"
[email protected]a55c6742013-08-10 07:28:4817#include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
[email protected]bfd4b812013-04-11 02:02:1118#include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
estadeecb659d2014-12-11 03:53:1619#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
rouslan497109da2014-11-26 20:30:3420#include "chrome/browser/ui/autofill/credit_card_scanner_controller.h"
[email protected]cc5419d2012-08-30 02:29:4621#include "chrome/browser/ui/browser.h"
22#include "chrome/browser/ui/browser_finder.h"
23#include "chrome/browser/ui/browser_window.h"
24#include "chrome/browser/ui/chrome_pages.h"
[email protected]10090d52013-07-25 20:41:3725#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
[email protected]34b59462013-12-03 14:08:3226#include "chrome/browser/webdata/web_data_service_factory.h"
[email protected]cc5419d2012-08-30 02:29:4627#include "chrome/common/url_constants.h"
[email protected]e13549e2014-03-12 20:34:3628#include "components/autofill/content/browser/content_autofill_driver.h"
[email protected]45b53fb2013-12-12 19:28:0629#include "components/autofill/content/common/autofill_messages.h"
pritam.nikam2cd65ab92015-01-13 08:13:0230#include "components/autofill/core/browser/autofill_cc_infobar_delegate.h"
[email protected]6c7dcb2f22013-06-22 00:57:4831#include "components/autofill/core/common/autofill_pref_names.h"
estadeb1bc9bd2014-12-02 22:44:1132#include "components/password_manager/content/browser/content_password_manager_driver.h"
estade1dbe1232015-01-06 22:45:0433#include "content/public/browser/render_frame_host.h"
tfarina3b0452d2014-12-31 15:20:0934#include "ui/gfx/geometry/rect.h"
[email protected]8d4cc15e2012-08-30 00:33:1035
[email protected]5b466c42014-02-25 17:56:3636#if defined(OS_ANDROID)
estade57722ec2014-08-27 23:52:3337#include "chrome/browser/android/chromium_application.h"
[email protected]5b466c42014-02-25 17:56:3638#include "chrome/browser/ui/android/autofill/autofill_logger_android.h"
thestig2c8c41e2014-10-23 02:56:5039#else
estade494f8e62015-01-26 23:28:1340#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
wjmaclean7f63c6b2014-12-09 14:59:5541#include "components/ui/zoom/zoom_controller.h"
[email protected]5b466c42014-02-25 17:56:3642#endif
43
[email protected]b4db6d42014-06-07 04:36:5844DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::ChromeAutofillClient);
[email protected]bfb4d67212013-02-14 20:32:2945
46namespace autofill {
[email protected]698bdf742012-10-01 21:13:5047
[email protected]b4db6d42014-06-07 04:36:5848ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents)
estade7c369d42014-12-18 01:46:2349 : content::WebContentsObserver(web_contents),
estade1dbe1232015-01-06 22:45:0450 unmask_controller_(web_contents),
51 last_rfh_to_rac_(nullptr) {
[email protected]698bdf742012-10-01 21:13:5052 DCHECK(web_contents);
thestig2c8c41e2014-10-23 02:56:5053
54#if !defined(OS_ANDROID)
[email protected]76a54502014-07-10 22:59:3455 // Since ZoomController is also a WebContentsObserver, we need to be careful
56 // about disconnecting from it since the relative order of destruction of
57 // WebContentsObservers is not guaranteed. ZoomController silently clears
58 // its ZoomObserver list during WebContentsDestroyed() so there's no need
59 // to explicitly remove ourselves on destruction.
wjmaclean7f63c6b2014-12-09 14:59:5560 ui_zoom::ZoomController* zoom_controller =
61 ui_zoom::ZoomController::FromWebContents(web_contents);
thestig2c8c41e2014-10-23 02:56:5062 // There may not always be a ZoomController, e.g. in tests.
[email protected]76a54502014-07-10 22:59:3463 if (zoom_controller)
64 zoom_controller->AddObserver(this);
thestig2c8c41e2014-10-23 02:56:5065#endif
66
[email protected]34cd6712014-06-19 03:19:2667#if defined(OS_MACOSX) && !defined(OS_IOS)
68 RegisterForKeystoneNotifications();
69#endif // defined(OS_MACOSX) && !defined(OS_IOS)
[email protected]8d4cc15e2012-08-30 00:33:1070}
71
[email protected]b4db6d42014-06-07 04:36:5872ChromeAutofillClient::~ChromeAutofillClient() {
[email protected]9256a9362013-07-04 22:11:4873 // NOTE: It is too late to clean up the autofill popup; that cleanup process
74 // requires that the WebContents instance still be valid and it is not at
75 // this point (in particular, the WebContentsImpl destructor has already
76 // finished running and we are now in the base class destructor).
77 DCHECK(!popup_controller_);
[email protected]34cd6712014-06-19 03:19:2678#if defined(OS_MACOSX) && !defined(OS_IOS)
79 UnregisterFromKeystoneNotifications();
80#endif // defined(OS_MACOSX) && !defined(OS_IOS)
[email protected]8ac8bfd2013-02-27 05:18:0881}
82
[email protected]b4db6d42014-06-07 04:36:5883void ChromeAutofillClient::TabActivated() {
[email protected]10090d52013-07-25 20:41:3784 if (dialog_controller_.get())
85 dialog_controller_->TabActivated();
86}
87
[email protected]b4db6d42014-06-07 04:36:5888PersonalDataManager* ChromeAutofillClient::GetPersonalDataManager() {
[email protected]6f3ccf52013-02-21 03:55:2389 Profile* profile =
estadeecb659d2014-12-11 03:53:1690 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]6f3ccf52013-02-21 03:55:2391 return PersonalDataManagerFactory::GetForProfile(
92 profile->GetOriginalProfile());
93}
94
[email protected]b4db6d42014-06-07 04:36:5895scoped_refptr<AutofillWebDataService> ChromeAutofillClient::GetDatabase() {
[email protected]34b59462013-12-03 14:08:3296 Profile* profile =
estadeecb659d2014-12-11 03:53:1697 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]34b59462013-12-03 14:08:3298 return WebDataServiceFactory::GetAutofillWebDataForProfile(
sdefresnee9ea3c22015-01-10 10:10:0499 profile, ServiceAccessType::EXPLICIT_ACCESS);
[email protected]29079a272013-11-19 14:51:24100}
101
[email protected]b4db6d42014-06-07 04:36:58102PrefService* ChromeAutofillClient::GetPrefs() {
estadeecb659d2014-12-11 03:53:16103 return Profile::FromBrowserContext(web_contents()->GetBrowserContext())
[email protected]b4db6d42014-06-07 04:36:58104 ->GetPrefs();
[email protected]8d4cc15e2012-08-30 00:33:10105}
106
estade494f8e62015-01-26 23:28:13107IdentityProvider* ChromeAutofillClient::GetIdentityProvider() {
108 if (!identity_provider_) {
109 Profile* profile =
estade1baedb12015-03-23 22:59:29110 Profile::FromBrowserContext(web_contents()->GetBrowserContext())
111 ->GetOriginalProfile();
estade494f8e62015-01-26 23:28:13112 LoginUIService* login_service = nullptr;
113#if !defined(OS_ANDROID)
114 login_service = LoginUIServiceFactory::GetForProfile(profile);
115#endif
116 identity_provider_.reset(new ProfileIdentityProvider(
117 SigninManagerFactory::GetForProfile(profile),
118 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
119 login_service));
120 }
121
122 return identity_provider_.get();
123}
124
mathp94e3f0b2015-03-18 00:16:16125rappor::RapporService* ChromeAutofillClient::GetRapporService() {
126 return g_browser_process->rappor_service();
127}
128
[email protected]b4db6d42014-06-07 04:36:58129void ChromeAutofillClient::ShowAutofillSettings() {
[email protected]cc5419d2012-08-30 02:29:46130#if defined(OS_ANDROID)
estade57722ec2014-08-27 23:52:33131 chrome::android::ChromiumApplication::ShowAutofillSettings();
[email protected]cc5419d2012-08-30 02:29:46132#else
estadeecb659d2014-12-11 03:53:16133 Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
[email protected]cc5419d2012-08-30 02:29:46134 if (browser)
135 chrome::ShowSettingsSubPage(browser, chrome::kAutofillSubPage);
136#endif // #if defined(OS_ANDROID)
137}
138
estade39f60492014-12-30 23:35:19139void ChromeAutofillClient::ShowUnmaskPrompt(
140 const CreditCard& card,
141 base::WeakPtr<CardUnmaskDelegate> delegate) {
142 unmask_controller_.ShowPrompt(card, delegate);
estadeecb659d2014-12-11 03:53:16143}
144
estadefb1d7742015-03-03 02:57:07145void ChromeAutofillClient::OnUnmaskVerificationResult(GetRealPanResult result) {
146 unmask_controller_.OnVerificationResult(result);
estadeecb659d2014-12-11 03:53:16147}
148
[email protected]b4db6d42014-06-07 04:36:58149void ChromeAutofillClient::ConfirmSaveCreditCard(
[email protected]90804a502013-03-06 22:07:18150 const base::Closure& save_card_callback) {
pritam.nikam2cd65ab92015-01-13 08:13:02151 AutofillCCInfoBarDelegate::Create(
152 InfoBarService::FromWebContents(web_contents()), this,
153 save_card_callback);
[email protected]90804a502013-03-06 22:07:18154}
155
rouslan497109da2014-11-26 20:30:34156bool ChromeAutofillClient::HasCreditCardScanFeature() {
157 return CreditCardScannerController::HasCreditCardScanFeature();
158}
159
160void ChromeAutofillClient::ScanCreditCard(
161 const CreditCardScanCallback& callback) {
162 CreditCardScannerController::ScanCreditCard(web_contents(), callback);
163}
164
[email protected]b4db6d42014-06-07 04:36:58165void ChromeAutofillClient::ShowRequestAutocompleteDialog(
[email protected]4ff32522013-01-26 00:37:58166 const FormData& form,
estade1dbe1232015-01-06 22:45:04167 content::RenderFrameHost* render_frame_host,
[email protected]ce24d872014-04-11 20:45:28168 const ResultCallback& callback) {
[email protected]364481b2013-01-29 01:52:28169 HideRequestAutocompleteDialog();
estade1dbe1232015-01-06 22:45:04170 last_rfh_to_rac_ = render_frame_host;
171 GURL frame_url = render_frame_host->GetLastCommittedURL();
estadeecb659d2014-12-11 03:53:16172 dialog_controller_ = AutofillDialogController::Create(web_contents(), form,
estade1dbe1232015-01-06 22:45:04173 frame_url, callback);
[email protected]a55c6742013-08-10 07:28:48174 if (dialog_controller_) {
175 dialog_controller_->Show();
176 } else {
[email protected]b4db6d42014-06-07 04:36:58177 callback.Run(AutofillClient::AutocompleteResultErrorDisabled,
[email protected]dbdd60272014-04-14 22:48:40178 base::string16(),
[email protected]ce24d872014-04-11 20:45:28179 NULL);
[email protected]a55c6742013-08-10 07:28:48180 NOTIMPLEMENTED();
181 }
[email protected]364481b2013-01-29 01:52:28182}
183
[email protected]b4db6d42014-06-07 04:36:58184void ChromeAutofillClient::ShowAutofillPopup(
[email protected]8ac8bfd2013-02-27 05:18:08185 const gfx::RectF& element_bounds,
[email protected]46cb7e92013-06-12 15:32:31186 base::i18n::TextDirection text_direction,
brettw5f888152014-12-15 23:31:26187 const std::vector<autofill::Suggestion>& suggestions,
[email protected]1f66a3892013-04-22 18:57:14188 base::WeakPtr<AutofillPopupDelegate> delegate) {
[email protected]8ac8bfd2013-02-27 05:18:08189 // Convert element_bounds to be in screen space.
estadeecb659d2014-12-11 03:53:16190 gfx::Rect client_area = web_contents()->GetContainerBounds();
[email protected]8ac8bfd2013-02-27 05:18:08191 gfx::RectF element_bounds_in_screen_space =
192 element_bounds + client_area.OffsetFromOrigin();
193
194 // Will delete or reuse the old |popup_controller_|.
noms9139a6a2015-02-19 19:42:29195 popup_controller_ =
196 AutofillPopupControllerImpl::GetOrCreate(popup_controller_,
197 delegate,
198 web_contents(),
199 web_contents()->GetNativeView(),
200 element_bounds_in_screen_space,
201 text_direction);
[email protected]8ac8bfd2013-02-27 05:18:08202
brettw5f888152014-12-15 23:31:26203 popup_controller_->Show(suggestions);
[email protected]8ac8bfd2013-02-27 05:18:08204}
205
[email protected]b4db6d42014-06-07 04:36:58206void ChromeAutofillClient::UpdateAutofillPopupDataListValues(
[email protected]ead7fb02013-07-18 18:50:12207 const std::vector<base::string16>& values,
208 const std::vector<base::string16>& labels) {
209 if (popup_controller_.get())
210 popup_controller_->UpdateDataListValues(values, labels);
211}
212
[email protected]b4db6d42014-06-07 04:36:58213void ChromeAutofillClient::HideAutofillPopup() {
[email protected]e8dad9b2013-06-04 04:43:45214 if (popup_controller_.get())
[email protected]8ac8bfd2013-02-27 05:18:08215 popup_controller_->Hide();
[email protected]3cbdf9362014-01-31 23:12:23216
217 // Password generation popups behave in the same fashion and should also
218 // be hidden.
[email protected]53e4e6d2014-02-25 14:09:43219 ChromePasswordManagerClient* password_client =
estadeecb659d2014-12-11 03:53:16220 ChromePasswordManagerClient::FromWebContents(web_contents());
[email protected]53e4e6d2014-02-25 14:09:43221 if (password_client)
222 password_client->HidePasswordGenerationPopup();
[email protected]364481b2013-01-29 01:52:28223}
224
[email protected]b4db6d42014-06-07 04:36:58225bool ChromeAutofillClient::IsAutocompleteEnabled() {
[email protected]6c7dcb2f22013-06-22 00:57:48226 // For browser, Autocomplete is always enabled as part of Autofill.
227 return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
228}
229
[email protected]b4db6d42014-06-07 04:36:58230void ChromeAutofillClient::HideRequestAutocompleteDialog() {
estade1dbe1232015-01-06 22:45:04231 if (dialog_controller_)
[email protected]8ac8bfd2013-02-27 05:18:08232 dialog_controller_->Hide();
[email protected]364481b2013-01-29 01:52:28233}
234
estade1dbe1232015-01-06 22:45:04235void ChromeAutofillClient::RenderFrameDeleted(
236 content::RenderFrameHost* render_frame_host) {
237 if (dialog_controller_ && render_frame_host == last_rfh_to_rac_)
238 HideRequestAutocompleteDialog();
239}
240
241void ChromeAutofillClient::DidNavigateAnyFrame(
242 content::RenderFrameHost* render_frame_host,
243 const content::LoadCommittedDetails& details,
244 const content::FrameNavigateParams& params) {
245 if (dialog_controller_ && render_frame_host == last_rfh_to_rac_)
246 HideRequestAutocompleteDialog();
247}
248
rouslan2f5993f2015-01-29 00:18:31249void ChromeAutofillClient::MainFrameWasResized(bool width_changed) {
250#if defined(OS_ANDROID)
251 // Ignore virtual keyboard showing and hiding a strip of suggestions.
252 if (!width_changed)
253 return;
254#endif
255
estaded0a0c992015-01-21 14:12:06256 HideAutofillPopup();
257}
258
[email protected]b4db6d42014-06-07 04:36:58259void ChromeAutofillClient::WebContentsDestroyed() {
[email protected]9256a9362013-07-04 22:11:48260 HideAutofillPopup();
261}
262
[email protected]76a54502014-07-10 22:59:34263void ChromeAutofillClient::OnZoomChanged(
wjmaclean7f63c6b2014-12-09 14:59:55264 const ui_zoom::ZoomController::ZoomChangedEventData& data) {
[email protected]76a54502014-07-10 22:59:34265 HideAutofillPopup();
266}
267
[email protected]b4db6d42014-06-07 04:36:58268void ChromeAutofillClient::DetectAccountCreationForms(
estadeb1bc9bd2014-12-02 22:44:11269 content::RenderFrameHost* rfh,
[email protected]375564a2013-09-06 20:36:40270 const std::vector<autofill::FormStructure*>& forms) {
estadecde163512014-12-04 22:14:05271 password_manager::ContentPasswordManagerDriver* driver =
272 password_manager::ContentPasswordManagerDriver::GetForRenderFrameHost(
273 rfh);
274 if (driver)
275 driver->GetPasswordGenerationManager()->DetectAccountCreationForms(forms);
[email protected]375564a2013-09-06 20:36:40276}
277
[email protected]b4db6d42014-06-07 04:36:58278void ChromeAutofillClient::DidFillOrPreviewField(
[email protected]5b466c42014-02-25 17:56:36279 const base::string16& autofilled_value,
280 const base::string16& profile_full_name) {
281#if defined(OS_ANDROID)
[email protected]b4db6d42014-06-07 04:36:58282 AutofillLoggerAndroid::DidFillOrPreviewField(autofilled_value,
283 profile_full_name);
[email protected]5b466c42014-02-25 17:56:36284#endif // defined(OS_ANDROID)
285}
286
estadeb1bc9bd2014-12-02 22:44:11287void ChromeAutofillClient::OnFirstUserGestureObserved() {
288 web_contents()->SendToAllFrames(
289 new AutofillMsg_FirstUserGestureObservedInTab(routing_id()));
290}
291
pritam.nikam2cd65ab92015-01-13 08:13:02292void ChromeAutofillClient::LinkClicked(const GURL& url,
293 WindowOpenDisposition disposition) {
294 web_contents()->OpenURL(content::OpenURLParams(
295 url, content::Referrer(), disposition, ui::PAGE_TRANSITION_LINK, false));
296}
297
[email protected]bfb4d67212013-02-14 20:32:29298} // namespace autofill