Index: components/password_manager/core/browser/password_manager.cc |
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc |
index 1ab931f4684effabaff119fa0b6362237492a0c5..7fdf421f340d641d69a6d56410507867e29662e9 100644 |
--- a/components/password_manager/core/browser/password_manager.cc |
+++ b/components/password_manager/core/browser/password_manager.cc |
@@ -12,6 +12,7 @@ |
#include "base/strings/utf_string_conversions.h" |
#include "base/threading/platform_thread.h" |
#include "components/autofill/core/common/password_autofill_util.h" |
+#include "components/password_manager/core/browser/browser_save_password_progress_logger.h" |
#include "components/password_manager/core/browser/password_form_manager.h" |
#include "components/password_manager/core/browser/password_manager_client.h" |
#include "components/password_manager/core/browser/password_manager_driver.h" |
@@ -28,6 +29,10 @@ namespace { |
const char kSpdyProxyRealm[] = "/SpdyProxy"; |
+// Shorten the name to spare line breaks. The code provides enough context |
+// already. |
+typedef autofill::SavePasswordProgressLogger Logger; |
+ |
// This routine is called when PasswordManagers are constructed. |
// |
// Currently we report metrics only once at startup. We require |
@@ -84,9 +89,9 @@ PasswordManager::~PasswordManager() { |
void PasswordManager::SetFormHasGeneratedPassword(const PasswordForm& form) { |
for (ScopedVector<PasswordFormManager>::iterator iter = |
pending_login_managers_.begin(); |
- iter != pending_login_managers_.end(); ++iter) { |
- if ((*iter)->DoesManage( |
- form, PasswordFormManager::ACTION_MATCH_REQUIRED)) { |
+ iter != pending_login_managers_.end(); |
+ ++iter) { |
+ if ((*iter)->DoesManage(form, PasswordFormManager::ACTION_MATCH_REQUIRED)) { |
(*iter)->SetHasGeneratedPassword(); |
return; |
} |
@@ -96,8 +101,8 @@ void PasswordManager::SetFormHasGeneratedPassword(const PasswordForm& form) { |
// ability to detect forms. |
bool ssl_valid = (form.origin.SchemeIsSecure() && |
!driver_->DidLastPageLoadEncounterSSLErrors()); |
- PasswordFormManager* manager = new PasswordFormManager( |
- this, client_, driver_, form, ssl_valid); |
+ PasswordFormManager* manager = |
+ new PasswordFormManager(this, client_, driver_, form, ssl_valid); |
pending_login_managers_.push_back(manager); |
manager->SetHasGeneratedPassword(); |
// TODO(gcasto): Add UMA stats to track this. |
@@ -108,14 +113,32 @@ bool PasswordManager::IsSavingEnabled() const { |
} |
void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
- if (!IsSavingEnabled()) { |
+ bool is_saving_enabled = IsSavingEnabled(); |
+ |
+ scoped_ptr<password_manager::BrowserSavePasswordProgressLogger> logger; |
+ if (client_->IsLoggingActive()) { |
+ logger.reset( |
+ new password_manager::BrowserSavePasswordProgressLogger(client_)); |
+ logger->LogMessage(Logger::STRING_PROVISIONALLY_SAVE_PASSWORD_METHOD); |
+ logger->LogPasswordForm(Logger::STRING_PROVISIONALLY_SAVE_PASSWORD_FORM, |
+ form); |
+ logger->LogBoolean(Logger::STRING_IS_SAVING_ENABLED, is_saving_enabled); |
+ } |
+ |
+ if (!is_saving_enabled) { |
RecordFailure(SAVING_DISABLED, form.origin.host()); |
+ if (logger) |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
return; |
} |
// No password to save? Then don't. |
if (form.password_value.empty()) { |
RecordFailure(EMPTY_PASSWORD, form.origin.host()); |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_EMPTY_PASSWORD); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
return; |
} |
@@ -124,18 +147,23 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
pending_login_managers_.end(); |
for (ScopedVector<PasswordFormManager>::iterator iter = |
pending_login_managers_.begin(); |
- iter != pending_login_managers_.end(); ++iter) { |
+ iter != pending_login_managers_.end(); |
+ ++iter) { |
// If we find a manager that exactly matches the submitted form including |
// the action URL, exit the loop. |
- if ((*iter)->DoesManage( |
- form, PasswordFormManager::ACTION_MATCH_REQUIRED)) { |
+ if ((*iter)->DoesManage(form, PasswordFormManager::ACTION_MATCH_REQUIRED)) { |
+ if (logger) |
+ logger->LogMessage(Logger::STRING_EXACT_MATCH); |
matched_manager_it = iter; |
break; |
- // If the current manager matches the submitted form excluding the action |
- // URL, remember it as a candidate and continue searching for an exact |
- // match. |
+ // If the current manager matches the submitted form excluding the action |
+ // URL, remember it as a candidate and continue searching for an exact |
+ // match. |
Ilya Sherman
2014/04/23 20:21:44
The previous alignment for this comment was better
vabr (Chromium)
2014/04/24 10:59:27
Thanks for catching this.
I moved this comment ins
|
} else if ((*iter)->DoesManage( |
- form, PasswordFormManager::ACTION_MATCH_NOT_REQUIRED)) { |
+ form, PasswordFormManager::ACTION_MATCH_NOT_REQUIRED)) { |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_MATCH_WITHOUT_ACTION); |
+ } |
Ilya Sherman
2014/04/23 20:21:44
nit: No need for curly braces
vabr (Chromium)
2014/04/24 10:59:27
Done.
|
matched_manager_it = iter; |
} |
} |
@@ -158,6 +186,10 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// give up. |
if (!manager->HasCompletedMatching()) { |
RecordFailure(MATCHING_NOT_COMPLETE, form.origin.host()); |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_NO_FORM_MANAGER); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
return; |
} |
@@ -165,12 +197,20 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// this form. |
if (manager->IsBlacklisted()) { |
RecordFailure(FORM_BLACKLISTED, form.origin.host()); |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_FORM_BLACKLISTED); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
Ilya Sherman
2014/04/23 20:21:44
nit: Maybe it makes sense to move the logging into
vabr (Chromium)
2014/04/24 10:59:27
That's a great idea! Done.
|
+ } |
return; |
} |
// Bail if we're missing any of the necessary form components. |
if (!manager->HasValidPasswordForm()) { |
RecordFailure(INVALID_FORM, form.origin.host()); |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_INVALID_FORM); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
return; |
} |
@@ -178,9 +218,12 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// Chrome to manage such passwords. For other passwords, respect the |
// autocomplete attribute if autocomplete='off' is not ignored. |
if (!autofill::ShouldIgnoreAutocompleteOffForPasswordFields() && |
- !manager->HasGeneratedPassword() && |
- !form.password_autocomplete_set) { |
+ !manager->HasGeneratedPassword() && !form.password_autocomplete_set) { |
RecordFailure(AUTOCOMPLETE_OFF, form.origin.host()); |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_AUTOCOMPLETE_OFF); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
return; |
} |
@@ -189,18 +232,27 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
form.origin.SchemeIsSecure() && |
!driver_->DidLastPageLoadEncounterSSLErrors(); |
provisionally_saved_form.preferred = true; |
+ if (logger) { |
+ logger->LogPasswordForm(Logger::STRING_PROVISIONALLY_SAVED_FORM, |
+ provisionally_saved_form); |
+ } |
PasswordFormManager::OtherPossibleUsernamesAction action = |
PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES; |
if (OtherPossibleUsernamesEnabled()) |
action = PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES; |
+ if (logger) { |
+ logger->LogBoolean( |
+ Logger::STRING_IGNORE_POSSIBLE_USERNAMES, |
+ action == PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); |
+ } |
manager->ProvisionallySave(provisionally_saved_form, action); |
provisional_save_manager_.swap(manager); |
} |
void PasswordManager::RecordFailure(ProvisionalSaveFailure failure, |
const std::string& form_origin) { |
- UMA_HISTOGRAM_ENUMERATION("PasswordManager.ProvisionalSaveFailure", |
- failure, MAX_FAILURE_VALUE); |
+ UMA_HISTOGRAM_ENUMERATION( |
+ "PasswordManager.ProvisionalSaveFailure", failure, MAX_FAILURE_VALUE); |
std::string group_name = metrics_util::GroupIdToString( |
metrics_util::MonitoredDomainGroupId(form_origin, client_->GetPrefs())); |
@@ -248,15 +300,16 @@ void PasswordManager::OnPasswordFormsParsed( |
bool had_ssl_error = driver_->DidLastPageLoadEncounterSSLErrors(); |
for (std::vector<PasswordForm>::const_iterator iter = forms.begin(); |
- iter != forms.end(); ++iter) { |
+ iter != forms.end(); |
+ ++iter) { |
// Don't involve the password manager if this form corresponds to |
// SpdyProxy authentication, as indicated by the realm. |
if (EndsWith(iter->signon_realm, kSpdyProxyRealm, true)) |
continue; |
bool ssl_valid = iter->origin.SchemeIsSecure() && !had_ssl_error; |
- PasswordFormManager* manager = new PasswordFormManager( |
- this, client_, driver_, *iter, ssl_valid); |
+ PasswordFormManager* manager = |
+ new PasswordFormManager(this, client_, driver_, *iter, ssl_valid); |
pending_login_managers_.push_back(manager); |
// Avoid prompting the user for access to a password if they don't have |
@@ -277,11 +330,28 @@ bool PasswordManager::ShouldPromptUserToSavePassword() const { |
void PasswordManager::OnPasswordFormsRendered( |
const std::vector<PasswordForm>& visible_forms) { |
- if (!provisional_save_manager_.get()) |
+ scoped_ptr<password_manager::BrowserSavePasswordProgressLogger> logger; |
+ if (client_->IsLoggingActive()) { |
+ logger.reset( |
+ new password_manager::BrowserSavePasswordProgressLogger(client_)); |
+ logger->LogMessage(Logger::STRING_ON_PASSWORD_FORMS_RENDERED_METHOD); |
+ } |
+ |
+ if (!provisional_save_manager_.get()) { |
+ if (logger) { |
+ logger->LogMessage(Logger::STRING_NO_PROVISIONAL_SAVE_MANAGER); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
return; |
+ } |
DCHECK(IsSavingEnabled()); |
+ if (logger) { |
+ logger->LogNumber(Logger::STRING_NUMBER_OF_VISIBLE_FORMS, |
+ visible_forms.size()); |
+ } |
+ |
// If we see the login form again, then the login failed. |
for (size_t i = 0; i < visible_forms.size(); ++i) { |
// TODO(vabr): The similarity check is just action equality for now. If it |
@@ -290,6 +360,11 @@ void PasswordManager::OnPasswordFormsRendered( |
if (visible_forms[i].action.is_valid() && |
provisional_save_manager_->pending_credentials().action == |
visible_forms[i].action) { |
+ if (logger) { |
+ logger->LogPasswordForm(Logger::STRING_PASSWORD_FORM_REAPPEARED, |
+ visible_forms[i]); |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
provisional_save_manager_->SubmitFailed(); |
provisional_save_manager_.reset(); |
return; |
@@ -303,8 +378,12 @@ void PasswordManager::OnPasswordFormsRendered( |
provisional_save_manager_->SubmitPassed(); |
if (ShouldPromptUserToSavePassword()) { |
+ if (logger) |
+ logger->LogMessage(Logger::STRING_DECISION_ASK); |
client_->PromptUserToSavePassword(provisional_save_manager_.release()); |
} else { |
+ if (logger) |
+ logger->LogMessage(Logger::STRING_DECISION_SAVE); |
provisional_save_manager_->Save(); |
provisional_save_manager_.reset(); |
} |
@@ -317,7 +396,8 @@ void PasswordManager::PossiblyInitializeUsernamesExperiment( |
bool other_possible_usernames_exist = false; |
for (autofill::PasswordFormMap::const_iterator it = best_matches.begin(); |
- it != best_matches.end(); ++it) { |
+ it != best_matches.end(); |
+ ++it) { |
if (!it->second->other_possible_usernames.empty()) { |
other_possible_usernames_exist = true; |
break; |
@@ -333,7 +413,9 @@ void PasswordManager::PossiblyInitializeUsernamesExperiment( |
kOtherPossibleUsernamesExperiment, |
kDivisor, |
"Disabled", |
- 2013, 12, 31, |
+ 2013, |
+ 12, |
+ 31, |
Ilya Sherman
2014/04/23 20:21:44
nit: This seems worse, as it's less obviously a da
vabr (Chromium)
2014/04/24 10:59:27
Agreed. Also filed http://b/14285621 to ask if the
|
base::FieldTrial::ONE_TIME_RANDOMIZED, |
NULL)); |
base::FieldTrial::Probability enabled_probability = |
@@ -343,14 +425,13 @@ void PasswordManager::PossiblyInitializeUsernamesExperiment( |
bool PasswordManager::OtherPossibleUsernamesEnabled() const { |
return base::FieldTrialList::FindFullName( |
- kOtherPossibleUsernamesExperiment) == "Enabled"; |
+ kOtherPossibleUsernamesExperiment) == "Enabled"; |
} |
-void PasswordManager::Autofill( |
- const PasswordForm& form_for_autofill, |
- const PasswordFormMap& best_matches, |
- const PasswordForm& preferred_match, |
- bool wait_for_username) const { |
+void PasswordManager::Autofill(const PasswordForm& form_for_autofill, |
+ const PasswordFormMap& best_matches, |
+ const PasswordForm& preferred_match, |
+ bool wait_for_username) const { |
PossiblyInitializeUsernamesExperiment(best_matches); |
// TODO(tedchoc): Switch to only requesting authentication if the user is |
@@ -358,7 +439,8 @@ void PasswordManager::Autofill( |
// of on page load. |
bool authentication_required = preferred_match.use_additional_authentication; |
for (autofill::PasswordFormMap::const_iterator it = best_matches.begin(); |
- !authentication_required && it != best_matches.end(); ++it) { |
+ !authentication_required && it != best_matches.end(); |
+ ++it) { |
if (it->second->use_additional_authentication) |
authentication_required = true; |
} |