Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/browser/password_manager/password_manager.cc

Issue 23140005: Added of new UMA signals in order to be able to discover early if the "save password" feature gets … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Test name changed Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_metrics_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
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
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
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& form_origin) {
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 group_name = password_manager_metrics_util::GroupIdToString(
229 password_manager_metrics_util::MonitoredDomainGroupId(form_origin));
230 if (!group_name.empty()) {
231 password_manager_metrics_util::LogUMAHistogramEnumeration(
232 "PasswordManager.ProvisionalSaveFailure_" + group_name, failure,
233 MAX_FAILURE_VALUE);
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
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 // We now assume that if there is at least one visible password form 320 // We now assume that if there is at least one visible password form
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 return; 420 return;
416 } 421 }
417 default: 422 default:
418 FOR_EACH_OBSERVER( 423 FOR_EACH_OBSERVER(
419 LoginModelObserver, 424 LoginModelObserver,
420 observers_, 425 observers_,
421 OnAutofillDataAvailable(preferred_match.username_value, 426 OnAutofillDataAvailable(preferred_match.username_value,
422 preferred_match.password_value)); 427 preferred_match.password_value));
423 } 428 }
424 } 429 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_manager.h ('k') | chrome/browser/password_manager/password_manager_delegate_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698