| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/password_manager/save_password_infobar_delegate.h" |
| |
| #include "base/metrics/histogram.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/infobars/infobar_service.h" |
| #include "chrome/browser/ui/sync/one_click_signin_helper.h" |
| #include "components/infobars/core/infobar.h" |
| #include "components/password_manager/core/browser/password_form_manager.h" |
| #include "components/signin/core/common/profile_management_switches.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/web_contents.h" |
| #include "google_apis/gaia/gaia_urls.h" |
| #include "grit/chromium_strings.h" |
| #include "grit/generated_resources.h" |
| #include "grit/theme_resources.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| // static |
| void SavePasswordInfoBarDelegate::Create( |
| content::WebContents* web_contents, |
| password_manager::PasswordFormManager* form_to_save, |
| const std::string& uma_histogram_suffix) { |
| #if defined(ENABLE_ONE_CLICK_SIGNIN) |
| // Don't show the password manager infobar if this form is for a google |
| // account and we are going to show the one-click signin infobar. |
| GURL realm(form_to_save->realm()); |
| // TODO(mathp): Checking only against associated_username() causes a bug |
| // referenced here: crbug.com/133275 |
| // TODO(vabr): The check IsEnableWebBasedSignin is a hack for the time when |
| // OneClickSignin is disabled. http://crbug.com/339804 |
| if (((realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) || |
| (realm == GURL("https://www.google.com/"))) && |
| switches::IsEnableWebBasedSignin() && |
| OneClickSigninHelper::CanOffer( |
| web_contents, |
| OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, |
| base::UTF16ToUTF8(form_to_save->associated_username()), |
| NULL)) |
| return; |
| #endif |
| |
| InfoBarService::FromWebContents(web_contents)->AddInfoBar( |
| SavePasswordInfoBarDelegate::CreateInfoBar( |
| scoped_ptr<SavePasswordInfoBarDelegate>( |
| new SavePasswordInfoBarDelegate(form_to_save, |
| uma_histogram_suffix)))); |
| } |
| |
| SavePasswordInfoBarDelegate::~SavePasswordInfoBarDelegate() { |
| UMA_HISTOGRAM_ENUMERATION("PasswordManager.InfoBarResponse", |
| infobar_response_, |
| password_manager::metrics_util::NUM_RESPONSE_TYPES); |
| |
| password_manager::metrics_util::LogUIDismissalReason(infobar_response_); |
| |
| // The shortest period for which the prompt needs to live, so that we don't |
| // consider it killed prematurely, as might happen, e.g., if a pre-rendered |
| // page gets swapped in (and the current WebContents is destroyed). |
| const base::TimeDelta kMinimumPromptDisplayTime = |
| base::TimeDelta::FromSeconds(1); |
| |
| if (!uma_histogram_suffix_.empty()) { |
| password_manager::metrics_util::LogUMAHistogramEnumeration( |
| "PasswordManager.SavePasswordPromptResponse_" + uma_histogram_suffix_, |
| infobar_response_, |
| password_manager::metrics_util::NUM_RESPONSE_TYPES); |
| password_manager::metrics_util::LogUMAHistogramBoolean( |
| "PasswordManager.SavePasswordPromptDisappearedQuickly_" + |
| uma_histogram_suffix_, |
| timer_.Elapsed() < kMinimumPromptDisplayTime); |
| } |
| } |
| |
| void SavePasswordInfoBarDelegate::SetUseAdditionalPasswordAuthentication( |
| bool use_additional_authentication) { |
| form_to_save_->SetUseAdditionalPasswordAuthentication( |
| use_additional_authentication); |
| } |
| |
| SavePasswordInfoBarDelegate::SavePasswordInfoBarDelegate( |
| password_manager::PasswordFormManager* form_to_save, |
| const std::string& uma_histogram_suffix) |
| : ConfirmInfoBarDelegate(), |
| form_to_save_(form_to_save), |
| infobar_response_(password_manager::metrics_util::NO_RESPONSE), |
| uma_histogram_suffix_(uma_histogram_suffix) { |
| if (!uma_histogram_suffix_.empty()) { |
| password_manager::metrics_util::LogUMAHistogramBoolean( |
| "PasswordManager.SavePasswordPromptDisplayed_" + uma_histogram_suffix_, |
| true); |
| } |
| } |
| |
| #if !defined(OS_ANDROID) |
| // On Android, the save password infobar supports an additional checkbox to |
| // require additional authentication before autofilling a saved password. |
| // Because of this non-standard UI, the Android version is special cased and |
| // constructed in: |
| // chrome/browser/ui/android/infobars/save_password_infobar.cc |
| |
| // static |
| scoped_ptr<infobars::InfoBar> SavePasswordInfoBarDelegate::CreateInfoBar( |
| scoped_ptr<SavePasswordInfoBarDelegate> delegate) { |
| return ConfirmInfoBarDelegate::CreateInfoBar( |
| delegate.PassAs<ConfirmInfoBarDelegate>()); |
| } |
| #endif |
| |
| bool SavePasswordInfoBarDelegate::ShouldExpire( |
| const NavigationDetails& details) const { |
| return !details.is_redirect && |
| infobars::InfoBarDelegate::ShouldExpire(details); |
| } |
| |
| int SavePasswordInfoBarDelegate::GetIconID() const { |
| return IDR_INFOBAR_SAVE_PASSWORD; |
| } |
| |
| infobars::InfoBarDelegate::Type SavePasswordInfoBarDelegate::GetInfoBarType() |
| const { |
| return PAGE_ACTION_TYPE; |
| } |
| |
| base::string16 SavePasswordInfoBarDelegate::GetMessageText() const { |
| return l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT); |
| } |
| |
| base::string16 SavePasswordInfoBarDelegate::GetButtonLabel( |
| InfoBarButton button) const { |
| return l10n_util::GetStringUTF16((button == BUTTON_OK) ? |
| IDS_PASSWORD_MANAGER_SAVE_BUTTON : IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON); |
| } |
| |
| bool SavePasswordInfoBarDelegate::Accept() { |
| DCHECK(form_to_save_.get()); |
| form_to_save_->Save(); |
| infobar_response_ = password_manager::metrics_util::REMEMBER_PASSWORD; |
| return true; |
| } |
| |
| bool SavePasswordInfoBarDelegate::Cancel() { |
| DCHECK(form_to_save_.get()); |
| form_to_save_->PermanentlyBlacklist(); |
| infobar_response_ = password_manager::metrics_util::NEVER_REMEMBER_PASSWORD; |
| return true; |
| } |
| |
| void SavePasswordInfoBarDelegate::InfoBarDismissed() { |
| DCHECK(form_to_save_.get()); |
| infobar_response_ = password_manager::metrics_util::INFOBAR_DISMISSED; |
| } |
| |
| infobars::InfoBarDelegate::InfoBarAutomationType |
| SavePasswordInfoBarDelegate::GetInfoBarAutomationType() const { |
| return PASSWORD_INFOBAR; |
| } |