ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / password_manager / chrome_password_manager_client.cc
blobbc8c710db1f11c742537d876db1446e74199a28c
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.
5 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
7 #include "base/bind_helpers.h"
8 #include "base/command_line.h"
9 #include "base/memory/singleton.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browsing_data/browsing_data_helper.h"
14 #include "chrome/browser/password_manager/password_manager_util.h"
15 #include "chrome/browser/password_manager/password_store_factory.h"
16 #include "chrome/browser/password_manager/save_password_infobar_delegate.h"
17 #include "chrome/browser/password_manager/sync_metrics.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/sync/profile_sync_service.h"
20 #include "chrome/browser/sync/profile_sync_service_factory.h"
21 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h"
22 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/common/chrome_version_info.h"
25 #include "chrome/common/url_constants.h"
26 #include "components/autofill/content/browser/content_autofill_driver.h"
27 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
28 #include "components/autofill/content/common/autofill_messages.h"
29 #include "components/autofill/core/browser/password_generator.h"
30 #include "components/autofill/core/common/password_form.h"
31 #include "components/password_manager/content/browser/content_password_manager_driver.h"
32 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
33 #include "components/password_manager/content/common/credential_manager_messages.h"
34 #include "components/password_manager/content/common/credential_manager_types.h"
35 #include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
36 #include "components/password_manager/core/browser/log_receiver.h"
37 #include "components/password_manager/core/browser/password_form_manager.h"
38 #include "components/password_manager/core/browser/password_manager_internals_service.h"
39 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
40 #include "components/password_manager/core/common/password_manager_switches.h"
41 #include "content/public/browser/navigation_entry.h"
42 #include "content/public/browser/render_view_host.h"
43 #include "content/public/browser/web_contents.h"
44 #include "google_apis/gaia/gaia_urls.h"
45 #include "net/base/url_util.h"
46 #include "third_party/re2/re2/re2.h"
48 #if defined(OS_ANDROID)
49 #include "chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h"
50 #endif
52 using password_manager::ContentPasswordManagerDriverFactory;
53 using password_manager::PasswordManagerInternalsService;
54 using password_manager::PasswordManagerInternalsServiceFactory;
56 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromePasswordManagerClient);
58 // Shorten the name to spare line breaks. The code provides enough context
59 // already.
60 typedef autofill::SavePasswordProgressLogger Logger;
62 // static
63 void ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
64 content::WebContents* contents,
65 autofill::AutofillClient* autofill_client) {
66 if (FromWebContents(contents))
67 return;
69 contents->SetUserData(
70 UserDataKey(),
71 new ChromePasswordManagerClient(contents, autofill_client));
74 ChromePasswordManagerClient::ChromePasswordManagerClient(
75 content::WebContents* web_contents,
76 autofill::AutofillClient* autofill_client)
77 : content::WebContentsObserver(web_contents),
78 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
79 password_manager_(this),
80 driver_factory_(nullptr),
81 credential_manager_dispatcher_(web_contents, this),
82 observer_(nullptr),
83 can_use_log_router_(false),
84 autofill_sync_state_(ALLOW_SYNC_CREDENTIALS),
85 sync_credential_was_filtered_(false) {
86 ContentPasswordManagerDriverFactory::CreateForWebContents(web_contents, this,
87 autofill_client);
88 driver_factory_ =
89 ContentPasswordManagerDriverFactory::FromWebContents(web_contents);
91 PasswordManagerInternalsService* service =
92 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
93 if (service)
94 can_use_log_router_ = service->RegisterClient(this);
95 SetUpAutofillSyncState();
98 ChromePasswordManagerClient::~ChromePasswordManagerClient() {
99 PasswordManagerInternalsService* service =
100 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
101 if (service)
102 service->UnregisterClient(this);
105 bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
106 return base::CommandLine::ForCurrentProcess()->HasSwitch(
107 password_manager::switches::kEnableAutomaticPasswordSaving) &&
108 chrome::VersionInfo::GetChannel() ==
109 chrome::VersionInfo::CHANNEL_UNKNOWN;
112 bool ChromePasswordManagerClient::IsPasswordManagerEnabledForCurrentPage()
113 const {
114 DCHECK(web_contents());
115 content::NavigationEntry* entry =
116 web_contents()->GetController().GetLastCommittedEntry();
117 if (!entry) {
118 // TODO(gcasto): Determine if fix for crbug.com/388246 is relevant here.
119 return true;
122 // Disable the password manager for online password management.
123 if (IsURLPasswordWebsiteReauth(entry->GetURL()))
124 return false;
126 if (EnabledForSyncSignin())
127 return true;
129 // Do not fill nor save password when a user is signing in for sync. This
130 // is because users need to remember their password if they are syncing as
131 // this is effectively their master password.
132 return entry->GetURL().host() != chrome::kChromeUIChromeSigninHost;
135 bool ChromePasswordManagerClient::ShouldFilterAutofillResult(
136 const autofill::PasswordForm& form) {
137 if (!IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
138 form.signon_realm))
139 return false;
141 if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
142 sync_credential_was_filtered_ = true;
143 return true;
146 if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
147 LastLoadWasTransactionalReauthPage()) {
148 sync_credential_was_filtered_ = true;
149 return true;
152 return false;
155 std::string ChromePasswordManagerClient::GetSyncUsername() const {
156 return password_manager_sync_metrics::GetSyncUsername(profile_);
159 bool ChromePasswordManagerClient::IsSyncAccountCredential(
160 const std::string& username, const std::string& origin) const {
161 return password_manager_sync_metrics::IsSyncAccountCredential(
162 profile_, username, origin);
165 void ChromePasswordManagerClient::AutofillResultsComputed() {
166 UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
167 sync_credential_was_filtered_);
168 sync_credential_was_filtered_ = false;
171 bool ChromePasswordManagerClient::PromptUserToSavePassword(
172 scoped_ptr<password_manager::PasswordFormManager> form_to_save,
173 password_manager::CredentialSourceType type) {
174 // Save password infobar and the password bubble prompts in case of
175 // "webby" URLs and do not prompt in case of "non-webby" URLS (e.g. file://).
176 if (!BrowsingDataHelper::IsWebScheme(
177 web_contents()->GetLastCommittedURL().scheme())) {
178 return false;
181 if (IsTheHotNewBubbleUIEnabled()) {
182 ManagePasswordsUIController* manage_passwords_ui_controller =
183 ManagePasswordsUIController::FromWebContents(web_contents());
184 manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save.Pass());
185 } else {
186 // TODO(melandory): If type is CREDENTIAL_SOURCE_API then new bubble should
187 // be shown.
188 std::string uma_histogram_suffix(
189 password_manager::metrics_util::GroupIdToString(
190 password_manager::metrics_util::MonitoredDomainGroupId(
191 form_to_save->realm(), GetPrefs())));
192 SavePasswordInfoBarDelegate::Create(
193 web_contents(), form_to_save.Pass(), uma_histogram_suffix);
195 return true;
198 bool ChromePasswordManagerClient::PromptUserToChooseCredentials(
199 ScopedVector<autofill::PasswordForm> local_forms,
200 ScopedVector<autofill::PasswordForm> federated_forms,
201 const GURL& origin,
202 base::Callback<void(const password_manager::CredentialInfo&)> callback) {
203 return ManagePasswordsUIController::FromWebContents(web_contents())->
204 OnChooseCredentials(local_forms.Pass(), federated_forms.Pass(), origin,
205 callback);
208 void ChromePasswordManagerClient::NotifyUserAutoSignin(
209 ScopedVector<autofill::PasswordForm> local_forms) {
210 DCHECK(!local_forms.empty());
211 ManagePasswordsUIController::FromWebContents(web_contents())->
212 OnAutoSignin(local_forms.Pass());
215 void ChromePasswordManagerClient::AutomaticPasswordSave(
216 scoped_ptr<password_manager::PasswordFormManager> saved_form) {
217 #if defined(OS_ANDROID)
218 GeneratedPasswordSavedInfoBarDelegateAndroid::Create(web_contents());
219 #else
220 if (IsTheHotNewBubbleUIEnabled()) {
221 ManagePasswordsUIController* manage_passwords_ui_controller =
222 ManagePasswordsUIController::FromWebContents(web_contents());
223 manage_passwords_ui_controller->OnAutomaticPasswordSave(
224 saved_form.Pass());
226 #endif
229 void ChromePasswordManagerClient::PasswordWasAutofilled(
230 const autofill::PasswordFormMap& best_matches) const {
231 ManagePasswordsUIController* manage_passwords_ui_controller =
232 ManagePasswordsUIController::FromWebContents(web_contents());
233 if (manage_passwords_ui_controller && IsTheHotNewBubbleUIEnabled())
234 manage_passwords_ui_controller->OnPasswordAutofilled(best_matches);
237 void ChromePasswordManagerClient::PasswordAutofillWasBlocked(
238 const autofill::PasswordFormMap& best_matches) const {
239 ManagePasswordsUIController* controller =
240 ManagePasswordsUIController::FromWebContents(web_contents());
241 if (controller && IsTheHotNewBubbleUIEnabled())
242 controller->OnBlacklistBlockedAutofill(best_matches);
245 void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
246 if (popup_controller_)
247 popup_controller_->HideAndDestroy();
250 PrefService* ChromePasswordManagerClient::GetPrefs() {
251 return profile_->GetPrefs();
254 password_manager::PasswordStore*
255 ChromePasswordManagerClient::GetPasswordStore() const {
256 // Always use EXPLICIT_ACCESS as the password manager checks IsOffTheRecord
257 // itself when it shouldn't access the PasswordStore.
258 // TODO(gcasto): Is is safe to change this to
259 // ServiceAccessType::IMPLICIT_ACCESS?
260 return PasswordStoreFactory::GetForProfile(
261 profile_, ServiceAccessType::EXPLICIT_ACCESS).get();
264 base::FieldTrial::Probability
265 ChromePasswordManagerClient::GetProbabilityForExperiment(
266 const std::string& experiment_name) const {
267 base::FieldTrial::Probability enabled_probability = 0;
268 if (experiment_name ==
269 password_manager::PasswordManager::kOtherPossibleUsernamesExperiment) {
270 switch (chrome::VersionInfo::GetChannel()) {
271 case chrome::VersionInfo::CHANNEL_DEV:
272 case chrome::VersionInfo::CHANNEL_BETA:
273 enabled_probability = 50;
274 break;
275 default:
276 break;
279 return enabled_probability;
282 bool ChromePasswordManagerClient::IsPasswordSyncEnabled(
283 password_manager::CustomPassphraseState state) const {
284 ProfileSyncService* sync_service =
285 ProfileSyncServiceFactory::GetForProfile(profile_);
286 if (sync_service && sync_service->HasSyncSetupCompleted() &&
287 sync_service->SyncActive() &&
288 sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS)) {
289 if (sync_service->IsUsingSecondaryPassphrase()) {
290 return state == password_manager::ONLY_CUSTOM_PASSPHRASE;
291 } else {
292 return state == password_manager::WITHOUT_CUSTOM_PASSPHRASE;
295 return false;
298 void ChromePasswordManagerClient::OnLogRouterAvailabilityChanged(
299 bool router_can_be_used) {
300 if (can_use_log_router_ == router_can_be_used)
301 return;
302 can_use_log_router_ = router_can_be_used;
304 NotifyRendererOfLoggingAvailability();
307 void ChromePasswordManagerClient::LogSavePasswordProgress(
308 const std::string& text) const {
309 if (!IsLoggingActive())
310 return;
311 PasswordManagerInternalsService* service =
312 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
313 if (service)
314 service->ProcessLog(text);
317 bool ChromePasswordManagerClient::IsLoggingActive() const {
318 // WebUI tabs do not need to log password saving progress. In particular, the
319 // internals page itself should not send any logs.
320 return can_use_log_router_ && !web_contents()->GetWebUI();
323 bool ChromePasswordManagerClient::WasLastNavigationHTTPError() const {
324 DCHECK(web_contents());
326 scoped_ptr<password_manager::BrowserSavePasswordProgressLogger> logger;
327 if (IsLoggingActive()) {
328 logger.reset(new password_manager::BrowserSavePasswordProgressLogger(this));
329 logger->LogMessage(
330 Logger::STRING_WAS_LAST_NAVIGATION_HTTP_ERROR_METHOD);
333 content::NavigationEntry* entry =
334 web_contents()->GetController().GetVisibleEntry();
335 if (!entry)
336 return false;
337 int http_status_code = entry->GetHttpStatusCode();
339 if (logger)
340 logger->LogNumber(Logger::STRING_HTTP_STATUS_CODE, http_status_code);
342 if (http_status_code >= 400 && http_status_code < 600)
343 return true;
344 return false;
347 bool ChromePasswordManagerClient::DidLastPageLoadEncounterSSLErrors() const {
348 content::NavigationEntry* entry =
349 web_contents()->GetController().GetLastCommittedEntry();
350 if (!entry)
351 return false;
353 return net::IsCertStatusError(entry->GetSSL().cert_status);
356 bool ChromePasswordManagerClient::IsOffTheRecord() const {
357 return web_contents()->GetBrowserContext()->IsOffTheRecord();
360 password_manager::PasswordManager*
361 ChromePasswordManagerClient::GetPasswordManager() {
362 return &password_manager_;
365 autofill::AutofillManager*
366 ChromePasswordManagerClient::GetAutofillManagerForMainFrame() {
367 autofill::ContentAutofillDriverFactory* factory =
368 autofill::ContentAutofillDriverFactory::FromWebContents(web_contents());
369 return factory
370 ? factory->DriverForFrame(web_contents()->GetMainFrame())
371 ->autofill_manager()
372 : nullptr;
375 void ChromePasswordManagerClient::SetTestObserver(
376 autofill::PasswordGenerationPopupObserver* observer) {
377 observer_ = observer;
380 bool ChromePasswordManagerClient::OnMessageReceived(
381 const IPC::Message& message,
382 content::RenderFrameHost* render_frame_host) {
383 bool handled = true;
384 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ChromePasswordManagerClient, message,
385 render_frame_host)
386 // Autofill messages:
387 IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordGenerationPopup,
388 ShowPasswordGenerationPopup)
389 IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordEditingPopup,
390 ShowPasswordEditingPopup)
391 IPC_END_MESSAGE_MAP()
393 IPC_BEGIN_MESSAGE_MAP(ChromePasswordManagerClient, message)
394 IPC_MESSAGE_HANDLER(AutofillHostMsg_HidePasswordGenerationPopup,
395 HidePasswordGenerationPopup)
396 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordAutofillAgentConstructed,
397 NotifyRendererOfLoggingAvailability)
398 // Default:
399 IPC_MESSAGE_UNHANDLED(handled = false)
400 IPC_END_MESSAGE_MAP()
402 return handled;
405 gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
406 const gfx::RectF& bounds) {
407 gfx::Rect client_area = web_contents()->GetContainerBounds();
408 return bounds + client_area.OffsetFromOrigin();
411 void ChromePasswordManagerClient::ShowPasswordGenerationPopup(
412 content::RenderFrameHost* render_frame_host,
413 const gfx::RectF& bounds,
414 int max_length,
415 const autofill::PasswordForm& form) {
416 // TODO(gcasto): Validate data in PasswordForm.
418 gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
420 popup_controller_ =
421 autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
422 popup_controller_, element_bounds_in_screen_space, form, max_length,
423 &password_manager_,
424 driver_factory_->GetDriverForFrame(render_frame_host), observer_,
425 web_contents(), web_contents()->GetNativeView());
426 popup_controller_->Show(true /* display_password */);
429 void ChromePasswordManagerClient::ShowPasswordEditingPopup(
430 content::RenderFrameHost* render_frame_host,
431 const gfx::RectF& bounds,
432 const autofill::PasswordForm& form) {
433 gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
434 popup_controller_ =
435 autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
436 popup_controller_, element_bounds_in_screen_space, form,
437 0, // Unspecified max length.
438 &password_manager_,
439 driver_factory_->GetDriverForFrame(render_frame_host), observer_,
440 web_contents(), web_contents()->GetNativeView());
441 popup_controller_->Show(false /* display_password */);
444 void ChromePasswordManagerClient::NotifyRendererOfLoggingAvailability() {
445 if (!web_contents())
446 return;
448 web_contents()->GetRenderViewHost()->Send(new AutofillMsg_SetLoggingState(
449 web_contents()->GetRenderViewHost()->GetRoutingID(),
450 can_use_log_router_));
453 bool ChromePasswordManagerClient::LastLoadWasTransactionalReauthPage() const {
454 DCHECK(web_contents());
455 content::NavigationEntry* entry =
456 web_contents()->GetController().GetLastCommittedEntry();
457 if (!entry)
458 return false;
460 if (entry->GetURL().GetOrigin() !=
461 GaiaUrls::GetInstance()->gaia_url().GetOrigin())
462 return false;
464 // "rart" is the transactional reauth paramter.
465 std::string ignored_value;
466 return net::GetValueForKeyInQuery(entry->GetURL(),
467 "rart",
468 &ignored_value);
471 bool ChromePasswordManagerClient::IsURLPasswordWebsiteReauth(
472 const GURL& url) const {
473 if (url.GetOrigin() != GaiaUrls::GetInstance()->gaia_url().GetOrigin())
474 return false;
476 // "rart" param signals this page is for transactional reauth.
477 std::string param_value;
478 if (!net::GetValueForKeyInQuery(url, "rart", &param_value))
479 return false;
481 // Check the "continue" param to see if this reauth page is for the passwords
482 // website.
483 param_value.clear();
484 if (!net::GetValueForKeyInQuery(url, "continue", &param_value))
485 return false;
487 // All password sites, including test sites, have autofilling disabled.
488 CR_DEFINE_STATIC_LOCAL(RE2, account_dashboard_pattern,
489 ("passwords(-([a-z-]+\\.corp))?\\.google\\.com"));
491 return RE2::FullMatch(GURL(param_value).host(), account_dashboard_pattern);
494 bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() {
495 #if !defined(USE_AURA) && !defined(OS_MACOSX)
496 return false;
497 #endif
498 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
499 if (command_line->HasSwitch(switches::kDisableSavePasswordBubble))
500 return false;
502 if (command_line->HasSwitch(switches::kEnableSavePasswordBubble))
503 return true;
505 std::string group_name =
506 base::FieldTrialList::FindFullName("PasswordManagerUI");
508 // The bubble should be the default case that runs on the bots.
509 return group_name != "Infobar";
512 bool ChromePasswordManagerClient::EnabledForSyncSignin() {
513 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
514 if (command_line->HasSwitch(
515 password_manager::switches::kDisableManagerForSyncSignin))
516 return false;
518 if (command_line->HasSwitch(
519 password_manager::switches::kEnableManagerForSyncSignin))
520 return true;
522 // Default is enabled.
523 std::string group_name =
524 base::FieldTrialList::FindFullName("PasswordManagerStateForSyncSignin");
525 return group_name != "Disabled";
528 void ChromePasswordManagerClient::SetUpAutofillSyncState() {
529 std::string group_name =
530 base::FieldTrialList::FindFullName("AutofillSyncCredential");
532 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
533 if (command_line->HasSwitch(
534 password_manager::switches::kAllowAutofillSyncCredential)) {
535 autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
536 return;
538 if (command_line->HasSwitch(
539 password_manager::switches::
540 kDisallowAutofillSyncCredentialForReauth)) {
541 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
542 return;
544 if (command_line->HasSwitch(
545 password_manager::switches::kDisallowAutofillSyncCredential)) {
546 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
547 return;
550 if (group_name == "DisallowSyncCredentialsForReauth") {
551 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
552 } else if (group_name == "DisallowSyncCredentials") {
553 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
554 } else {
555 // Allow by default.
556 autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
560 const GURL& ChromePasswordManagerClient::GetMainFrameURL() const {
561 return web_contents()->GetVisibleURL();