Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / password_manager / password_manager_delegate_impl.cc
1 // Copyright (c) 2012 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/password_manager/password_manager_delegate_impl.h"
6
7 #include "base/memory/singleton.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/timer/elapsed_timer.h"
11 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
12 #include "chrome/browser/infobars/infobar.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/password_manager/password_form_manager.h"
15 #include "chrome/browser/password_manager/password_manager.h"
16 #include "chrome/browser/password_manager/password_manager_metrics_util.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
19 #include "components/autofill/content/browser/autofill_driver_impl.h"
20 #include "components/autofill/content/common/autofill_messages.h"
21 #include "components/autofill/core/browser/autofill_manager.h"
22 #include "components/autofill/core/common/password_form.h"
23 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/page_transition_types.h"
28 #include "content/public/common/ssl_status.h"
29 #include "google_apis/gaia/gaia_urls.h"
30 #include "grit/chromium_strings.h"
31 #include "grit/generated_resources.h"
32 #include "grit/theme_resources.h"
33 #include "net/cert/cert_status_flags.h"
34 #include "ui/base/l10n/l10n_util.h"
35
36
37 // SavePasswordInfoBarDelegate ------------------------------------------------
38
39 // After a successful *new* login attempt, we take the PasswordFormManager in
40 // provisional_save_manager_ and move it to a SavePasswordInfoBarDelegate while
41 // the user makes up their mind with the "save password" infobar. Note if the
42 // login is one we already know about, the end of the line is
43 // provisional_save_manager_ because we just update it on success and so such
44 // forms never end up in an infobar.
45 class SavePasswordInfoBarDelegate : public ConfirmInfoBarDelegate {
46  public:
47   // If we won't be showing the one-click signin infobar, creates a save
48   // password infobar and delegate and adds the infobar to the InfoBarService
49   // for |web_contents|.  |uma_histogram_suffix| is empty, or one of the
50   // "group_X" suffixes used in the histogram names for infobar usage reporting;
51   // if empty, the usage is not reported, otherwise the suffix is used to choose
52   // the right histogram.
53   static void Create(content::WebContents* web_contents,
54                      PasswordFormManager* form_to_save,
55                      const std::string& uma_histogram_suffix);
56
57  private:
58   enum ResponseType {
59     NO_RESPONSE = 0,
60     REMEMBER_PASSWORD,
61     NEVER_REMEMBER_PASSWORD,
62     INFOBAR_DISMISSED,
63     NUM_RESPONSE_TYPES,
64   };
65
66   SavePasswordInfoBarDelegate(PasswordFormManager* form_to_save,
67                               const std::string& uma_histogram_suffix);
68   virtual ~SavePasswordInfoBarDelegate();
69
70   // InfoBarDelegate
71   virtual bool ShouldExpire(const content::LoadCommittedDetails& details)
72       const OVERRIDE;
73
74   // ConfirmInfoBarDelegate
75   virtual int GetIconID() const OVERRIDE;
76   virtual Type GetInfoBarType() const OVERRIDE;
77   virtual base::string16 GetMessageText() const OVERRIDE;
78   virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
79   virtual bool Accept() OVERRIDE;
80   virtual bool Cancel() OVERRIDE;
81   virtual void InfoBarDismissed() OVERRIDE;
82
83   virtual InfoBarAutomationType GetInfoBarAutomationType() const OVERRIDE;
84
85   // The PasswordFormManager managing the form we're asking the user about,
86   // and should update as per her decision.
87   scoped_ptr<PasswordFormManager> form_to_save_;
88
89   // Used to track the results we get from the info bar.
90   ResponseType infobar_response_;
91
92   // Measures the "Save password?" prompt lifetime. Used to report an UMA
93   // signal.
94   base::ElapsedTimer timer_;
95
96   // The group name corresponding to the domain name of |form_to_save_| if the
97   // form is on a monitored domain. Otherwise, an empty string.
98   const std::string uma_histogram_suffix_;
99
100   DISALLOW_COPY_AND_ASSIGN(SavePasswordInfoBarDelegate);
101 };
102
103 // static
104 void SavePasswordInfoBarDelegate::Create(
105     content::WebContents* web_contents,
106     PasswordFormManager* form_to_save,
107     const std::string& uma_histogram_suffix) {
108 #if defined(ENABLE_ONE_CLICK_SIGNIN)
109   // Don't show the password manager infobar if this form is for a google
110   // account and we are going to show the one-click signin infobar.
111   GURL realm(form_to_save->realm());
112   // TODO(mathp): Checking only against associated_username() causes a bug
113   // referenced here: crbug.com/133275
114   if (((realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) ||
115        (realm == GURL("https://www.google.com/"))) &&
116       OneClickSigninHelper::CanOffer(
117           web_contents, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
118           base::UTF16ToUTF8(form_to_save->associated_username()), NULL))
119     return;
120 #endif
121
122   InfoBarService::FromWebContents(web_contents)->AddInfoBar(
123       ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>(
124           new SavePasswordInfoBarDelegate(form_to_save,
125                                           uma_histogram_suffix))));
126 }
127
128 SavePasswordInfoBarDelegate::SavePasswordInfoBarDelegate(
129     PasswordFormManager* form_to_save,
130     const std::string& uma_histogram_suffix)
131     : ConfirmInfoBarDelegate(),
132       form_to_save_(form_to_save),
133       infobar_response_(NO_RESPONSE),
134       uma_histogram_suffix_(uma_histogram_suffix) {
135   if (!uma_histogram_suffix_.empty()) {
136     password_manager_metrics_util::LogUMAHistogramBoolean(
137         "PasswordManager.SavePasswordPromptDisplayed_" + uma_histogram_suffix_,
138         true);
139   }
140 }
141
142 SavePasswordInfoBarDelegate::~SavePasswordInfoBarDelegate() {
143   UMA_HISTOGRAM_ENUMERATION("PasswordManager.InfoBarResponse",
144                             infobar_response_, NUM_RESPONSE_TYPES);
145
146   // The shortest period for which the prompt needs to live, so that we don't
147   // consider it killed prematurely, as might happen, e.g., if a pre-rendered
148   // page gets swapped in (and the current WebContents is destroyed).
149   const base::TimeDelta kMinimumPromptDisplayTime =
150       base::TimeDelta::FromSeconds(1);
151
152   if (!uma_histogram_suffix_.empty()) {
153     password_manager_metrics_util::LogUMAHistogramEnumeration(
154         "PasswordManager.SavePasswordPromptResponse_" + uma_histogram_suffix_,
155         infobar_response_, NUM_RESPONSE_TYPES);
156     password_manager_metrics_util::LogUMAHistogramBoolean(
157         "PasswordManager.SavePasswordPromptDisappearedQuickly_" +
158             uma_histogram_suffix_,
159         timer_.Elapsed() < kMinimumPromptDisplayTime);
160   }
161 }
162
163 bool SavePasswordInfoBarDelegate::ShouldExpire(
164     const content::LoadCommittedDetails& details) const {
165   bool is_not_redirect = !(details.entry->GetTransitionType() &
166                            content::PAGE_TRANSITION_IS_REDIRECT_MASK);
167   return is_not_redirect && InfoBarDelegate::ShouldExpire(details);
168 }
169
170 int SavePasswordInfoBarDelegate::GetIconID() const {
171   return IDR_INFOBAR_SAVE_PASSWORD;
172 }
173
174 InfoBarDelegate::Type SavePasswordInfoBarDelegate::GetInfoBarType() const {
175   return PAGE_ACTION_TYPE;
176 }
177
178 base::string16 SavePasswordInfoBarDelegate::GetMessageText() const {
179   return l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT);
180 }
181
182 base::string16 SavePasswordInfoBarDelegate::GetButtonLabel(
183     InfoBarButton button) const {
184   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
185       IDS_PASSWORD_MANAGER_SAVE_BUTTON : IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON);
186 }
187
188 bool SavePasswordInfoBarDelegate::Accept() {
189   DCHECK(form_to_save_.get());
190   form_to_save_->Save();
191   infobar_response_ = REMEMBER_PASSWORD;
192   return true;
193 }
194
195 bool SavePasswordInfoBarDelegate::Cancel() {
196   DCHECK(form_to_save_.get());
197   form_to_save_->PermanentlyBlacklist();
198   infobar_response_ = NEVER_REMEMBER_PASSWORD;
199   return true;
200 }
201
202 void SavePasswordInfoBarDelegate::InfoBarDismissed() {
203   DCHECK(form_to_save_.get());
204   infobar_response_ = INFOBAR_DISMISSED;
205 }
206
207 InfoBarDelegate::InfoBarAutomationType
208     SavePasswordInfoBarDelegate::GetInfoBarAutomationType() const {
209   return PASSWORD_INFOBAR;
210 }
211
212
213 // PasswordManagerDelegateImpl ------------------------------------------------
214
215 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PasswordManagerDelegateImpl);
216
217 PasswordManagerDelegateImpl::PasswordManagerDelegateImpl(
218     content::WebContents* web_contents)
219     : web_contents_(web_contents) {
220 }
221
222 PasswordManagerDelegateImpl::~PasswordManagerDelegateImpl() {
223 }
224
225 void PasswordManagerDelegateImpl::FillPasswordForm(
226     const autofill::PasswordFormFillData& form_data) {
227   web_contents_->GetRenderViewHost()->Send(
228       new AutofillMsg_FillPasswordForm(
229           web_contents_->GetRenderViewHost()->GetRoutingID(),
230           form_data));
231 }
232
233 void PasswordManagerDelegateImpl::AddSavePasswordInfoBarIfPermitted(
234     PasswordFormManager* form_to_save) {
235   std::string uma_histogram_suffix(
236       password_manager_metrics_util::GroupIdToString(
237           password_manager_metrics_util::MonitoredDomainGroupId(
238               form_to_save->realm(), GetProfile()->GetPrefs())));
239   SavePasswordInfoBarDelegate::Create(
240       web_contents_, form_to_save, uma_histogram_suffix);
241 }
242
243 Profile* PasswordManagerDelegateImpl::GetProfile() {
244   return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
245 }
246
247 bool PasswordManagerDelegateImpl::DidLastPageLoadEncounterSSLErrors() {
248   content::NavigationEntry* entry =
249       web_contents_->GetController().GetActiveEntry();
250   if (!entry) {
251     NOTREACHED();
252     return false;
253   }
254
255   return net::IsCertStatusError(entry->GetSSL().cert_status);
256 }