OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/password_manager/password_manager.h" | 5 #include "chrome/browser/password_manager/password_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/threading/platform_thread.h" | 13 #include "base/threading/platform_thread.h" |
14 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 14 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
15 #include "chrome/browser/password_manager/password_form_manager.h" | 15 #include "chrome/browser/password_manager/password_form_manager.h" |
16 #include "chrome/browser/password_manager/password_manager_delegate.h" | 16 #include "chrome/browser/password_manager/password_manager_delegate.h" |
17 #include "chrome/browser/password_manager/password_manager_util.h" | |
17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
19 #include "chrome/common/chrome_version_info.h" | 20 #include "chrome/common/chrome_version_info.h" |
20 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
21 #include "components/autofill/core/common/autofill_messages.h" | 22 #include "components/autofill/core/common/autofill_messages.h" |
22 #include "components/user_prefs/pref_registry_syncable.h" | 23 #include "components/user_prefs/pref_registry_syncable.h" |
23 #include "content/public/browser/navigation_details.h" | 24 #include "content/public/browser/navigation_details.h" |
24 #include "content/public/browser/user_metrics.h" | 25 #include "content/public/browser/user_metrics.h" |
25 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
26 #include "content/public/common/frame_navigate_params.h" | 27 #include "content/public/common/frame_navigate_params.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
48 void ReportMetrics(bool password_manager_enabled) { | 49 void ReportMetrics(bool password_manager_enabled) { |
49 static base::PlatformThreadId initial_thread_id = | 50 static base::PlatformThreadId initial_thread_id = |
50 base::PlatformThread::CurrentId(); | 51 base::PlatformThread::CurrentId(); |
51 DCHECK(initial_thread_id == base::PlatformThread::CurrentId()); | 52 DCHECK(initial_thread_id == base::PlatformThread::CurrentId()); |
52 | 53 |
53 static bool ran_once = false; | 54 static bool ran_once = false; |
54 if (ran_once) | 55 if (ran_once) |
55 return; | 56 return; |
56 ran_once = true; | 57 ran_once = true; |
57 | 58 |
58 // TODO(isherman): This does not actually measure a user action. It should be | 59 UMA_HISTOGRAM_BOOLEAN("PasswordManager.Enabled", password_manager_enabled); |
59 // a boolean histogram. | |
60 if (password_manager_enabled) | |
61 content::RecordAction(UserMetricsAction("PasswordManager_Enabled")); | |
62 else | |
63 content::RecordAction(UserMetricsAction("PasswordManager_Disabled")); | |
64 } | 60 } |
65 | 61 |
66 } // namespace | 62 } // namespace |
67 | 63 |
68 // static | 64 // static |
69 void PasswordManager::RegisterProfilePrefs( | 65 void PasswordManager::RegisterProfilePrefs( |
70 user_prefs::PrefRegistrySyncable* registry) { | 66 user_prefs::PrefRegistrySyncable* registry) { |
71 registry->RegisterBooleanPref( | 67 registry->RegisterBooleanPref( |
72 prefs::kPasswordManagerEnabled, | 68 prefs::kPasswordManagerEnabled, |
73 true, | 69 true, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 // TODO(gcasto): Add UMA stats to track this. | 128 // TODO(gcasto): Add UMA stats to track this. |
133 } | 129 } |
134 | 130 |
135 bool PasswordManager::IsSavingEnabled() const { | 131 bool PasswordManager::IsSavingEnabled() const { |
136 return *password_manager_enabled_ && | 132 return *password_manager_enabled_ && |
137 !delegate_->GetProfile()->IsOffTheRecord(); | 133 !delegate_->GetProfile()->IsOffTheRecord(); |
138 } | 134 } |
139 | 135 |
140 void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { | 136 void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
141 if (!IsSavingEnabled()) { | 137 if (!IsSavingEnabled()) { |
142 RecordFailure(SAVING_DISABLED); | 138 RecordFailure(SAVING_DISABLED, form.origin.host()); |
143 return; | 139 return; |
144 } | 140 } |
145 | 141 |
146 // No password to save? Then don't. | 142 // No password to save? Then don't. |
147 if (form.password_value.empty()) { | 143 if (form.password_value.empty()) { |
148 RecordFailure(EMPTY_PASSWORD); | 144 RecordFailure(EMPTY_PASSWORD, form.origin.host()); |
149 return; | 145 return; |
150 } | 146 } |
151 | 147 |
152 scoped_ptr<PasswordFormManager> manager; | 148 scoped_ptr<PasswordFormManager> manager; |
153 ScopedVector<PasswordFormManager>::iterator matched_manager_it = | 149 ScopedVector<PasswordFormManager>::iterator matched_manager_it = |
154 pending_login_managers_.end(); | 150 pending_login_managers_.end(); |
155 for (ScopedVector<PasswordFormManager>::iterator iter = | 151 for (ScopedVector<PasswordFormManager>::iterator iter = |
156 pending_login_managers_.begin(); | 152 pending_login_managers_.begin(); |
157 iter != pending_login_managers_.end(); ++iter) { | 153 iter != pending_login_managers_.end(); ++iter) { |
158 // If we find a manager that exactly matches the submitted form including | 154 // If we find a manager that exactly matches the submitted form including |
(...skipping 12 matching lines...) Expand all Loading... | |
171 } | 167 } |
172 // If we didn't find a manager, this means a form was submitted without | 168 // If we didn't find a manager, this means a form was submitted without |
173 // first loading the page containing the form. Don't offer to save | 169 // first loading the page containing the form. Don't offer to save |
174 // passwords in this case. | 170 // passwords in this case. |
175 if (matched_manager_it != pending_login_managers_.end()) { | 171 if (matched_manager_it != pending_login_managers_.end()) { |
176 // Transfer ownership of the manager from |pending_login_managers_| to | 172 // Transfer ownership of the manager from |pending_login_managers_| to |
177 // |manager|. | 173 // |manager|. |
178 manager.reset(*matched_manager_it); | 174 manager.reset(*matched_manager_it); |
179 pending_login_managers_.weak_erase(matched_manager_it); | 175 pending_login_managers_.weak_erase(matched_manager_it); |
180 } else { | 176 } else { |
181 RecordFailure(NO_MATCHING_FORM); | 177 RecordFailure(NO_MATCHING_FORM, form.origin.host()); |
182 return; | 178 return; |
183 } | 179 } |
184 | 180 |
185 // If we found a manager but it didn't finish matching yet, the user has | 181 // If we found a manager but it didn't finish matching yet, the user has |
186 // tried to submit credentials before we had time to even find matching | 182 // tried to submit credentials before we had time to even find matching |
187 // results for the given form and autofill. If this is the case, we just | 183 // results for the given form and autofill. If this is the case, we just |
188 // give up. | 184 // give up. |
189 if (!manager->HasCompletedMatching()) { | 185 if (!manager->HasCompletedMatching()) { |
190 RecordFailure(MATCHING_NOT_COMPLETE); | 186 RecordFailure(MATCHING_NOT_COMPLETE, form.origin.host()); |
191 return; | 187 return; |
192 } | 188 } |
193 | 189 |
194 // Also get out of here if the user told us to 'never remember' passwords for | 190 // Also get out of here if the user told us to 'never remember' passwords for |
195 // this form. | 191 // this form. |
196 if (manager->IsBlacklisted()) { | 192 if (manager->IsBlacklisted()) { |
197 RecordFailure(FORM_BLACKLISTED); | 193 RecordFailure(FORM_BLACKLISTED, form.origin.host()); |
198 return; | 194 return; |
199 } | 195 } |
200 | 196 |
201 // Bail if we're missing any of the necessary form components. | 197 // Bail if we're missing any of the necessary form components. |
202 if (!manager->HasValidPasswordForm()) { | 198 if (!manager->HasValidPasswordForm()) { |
203 RecordFailure(INVALID_FORM); | 199 RecordFailure(INVALID_FORM, form.origin.host()); |
204 return; | 200 return; |
205 } | 201 } |
206 | 202 |
207 // Always save generated passwords, as the user expresses explicit intent for | 203 // Always save generated passwords, as the user expresses explicit intent for |
208 // Chrome to manage such passwords. For other passwords, respect the | 204 // Chrome to manage such passwords. For other passwords, respect the |
209 // autocomplete attribute. | 205 // autocomplete attribute. |
210 if (!manager->HasGeneratedPassword() && !form.password_autocomplete_set) { | 206 if (!manager->HasGeneratedPassword() && !form.password_autocomplete_set) { |
211 RecordFailure(AUTOCOMPLETE_OFF); | 207 RecordFailure(AUTOCOMPLETE_OFF, form.origin.host()); |
212 return; | 208 return; |
213 } | 209 } |
214 | 210 |
215 PasswordForm provisionally_saved_form(form); | 211 PasswordForm provisionally_saved_form(form); |
216 provisionally_saved_form.ssl_valid = form.origin.SchemeIsSecure() && | 212 provisionally_saved_form.ssl_valid = form.origin.SchemeIsSecure() && |
217 !delegate_->DidLastPageLoadEncounterSSLErrors(); | 213 !delegate_->DidLastPageLoadEncounterSSLErrors(); |
218 provisionally_saved_form.preferred = true; | 214 provisionally_saved_form.preferred = true; |
219 PasswordFormManager::OtherPossibleUsernamesAction action = | 215 PasswordFormManager::OtherPossibleUsernamesAction action = |
220 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES; | 216 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES; |
221 if (OtherPossibleUsernamesEnabled()) | 217 if (OtherPossibleUsernamesEnabled()) |
222 action = PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES; | 218 action = PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES; |
223 manager->ProvisionallySave(provisionally_saved_form, action); | 219 manager->ProvisionallySave(provisionally_saved_form, action); |
224 provisional_save_manager_.swap(manager); | 220 provisional_save_manager_.swap(manager); |
225 } | 221 } |
226 | 222 |
227 void PasswordManager::RecordFailure(ProvisionalSaveFailure failure) { | 223 void PasswordManager::RecordFailure(ProvisionalSaveFailure failure, |
224 const std::string& url_host) { | |
228 UMA_HISTOGRAM_ENUMERATION("PasswordManager.ProvisionalSaveFailure", | 225 UMA_HISTOGRAM_ENUMERATION("PasswordManager.ProvisionalSaveFailure", |
229 failure, MAX_FAILURE_VALUE); | 226 failure, MAX_FAILURE_VALUE); |
227 | |
228 std::string domain_name; | |
229 if (password_manager_util::IsDomainNameMonitored(url_host, &domain_name)) { | |
230 domain_name.insert(0, "_"); | |
Ilya Sherman
2013/08/29 06:42:21
nit: Why not just include the underscore in the st
jdomingos
2013/08/30 21:09:20
Done.
| |
231 UMA_HISTOGRAM_ENUMERATION( | |
232 "PasswordManager.ProvisionalSaveFailure" + domain_name, failure, | |
233 MAX_FAILURE_VALUE); | |
Ilya Sherman
2013/08/29 06:42:21
As in password_manager_delegate_impl.cc, you'll ne
jdomingos
2013/08/30 21:09:20
Done.
| |
234 } | |
230 } | 235 } |
231 | 236 |
232 void PasswordManager::AddSubmissionCallback( | 237 void PasswordManager::AddSubmissionCallback( |
233 const PasswordSubmittedCallback& callback) { | 238 const PasswordSubmittedCallback& callback) { |
234 submission_callbacks_.push_back(callback); | 239 submission_callbacks_.push_back(callback); |
235 } | 240 } |
236 | 241 |
237 void PasswordManager::AddObserver(LoginModelObserver* observer) { | 242 void PasswordManager::AddObserver(LoginModelObserver* observer) { |
238 observers_.AddObserver(observer); | 243 observers_.AddObserver(observer); |
239 } | 244 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 web_contents(), | 299 web_contents(), |
295 *iter, | 300 *iter, |
296 ssl_valid); | 301 ssl_valid); |
297 pending_login_managers_.push_back(manager); | 302 pending_login_managers_.push_back(manager); |
298 manager->FetchMatchingLoginsFromPasswordStore(); | 303 manager->FetchMatchingLoginsFromPasswordStore(); |
299 } | 304 } |
300 } | 305 } |
301 | 306 |
302 bool PasswordManager::ShouldShowSavePasswordInfoBar() const { | 307 bool PasswordManager::ShouldShowSavePasswordInfoBar() const { |
303 return provisional_save_manager_->IsNewLogin() && | 308 return provisional_save_manager_->IsNewLogin() && |
304 !provisional_save_manager_->HasGeneratedPassword() && | 309 !provisional_save_manager_->HasGeneratedPassword() && |
305 !provisional_save_manager_->IsPendingCredentialsPublicSuffixMatch(); | 310 !provisional_save_manager_->IsPendingCredentialsPublicSuffixMatch(); |
306 } | 311 } |
307 | 312 |
308 void PasswordManager::OnPasswordFormsRendered( | 313 void PasswordManager::OnPasswordFormsRendered( |
309 const std::vector<PasswordForm>& visible_forms) { | 314 const std::vector<PasswordForm>& visible_forms) { |
310 if (!provisional_save_manager_.get()) | 315 if (!provisional_save_manager_.get()) |
311 return; | 316 return; |
312 | 317 |
313 DCHECK(IsSavingEnabled()); | 318 DCHECK(IsSavingEnabled()); |
314 | 319 |
315 // First, check for a failed login attempt. | 320 // First, check for a failed login attempt. |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 return; | 425 return; |
421 } | 426 } |
422 default: | 427 default: |
423 FOR_EACH_OBSERVER( | 428 FOR_EACH_OBSERVER( |
424 LoginModelObserver, | 429 LoginModelObserver, |
425 observers_, | 430 observers_, |
426 OnAutofillDataAvailable(preferred_match.username_value, | 431 OnAutofillDataAvailable(preferred_match.username_value, |
427 preferred_match.password_value)); | 432 preferred_match.password_value)); |
428 } | 433 } |
429 } | 434 } |
OLD | NEW |