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 0e018826b2be4afe1868a7c780cdd65df9d9d714..55df537ecfb6cb697ca29f84e82869f2502c1f54 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_autofill_manager.h" |
#include "components/password_manager/core/browser/password_form_manager.h" |
#include "components/password_manager/core/browser/password_manager_client.h" |
@@ -29,6 +30,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 |
@@ -109,14 +114,25 @@ bool PasswordManager::IsSavingEnabled() const { |
} |
void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
- if (!IsSavingEnabled()) { |
- RecordFailure(SAVING_DISABLED, form.origin.host()); |
+ bool is_saving_enabled = IsSavingEnabled(); |
+ |
+ scoped_ptr<BrowserSavePasswordProgressLogger> logger; |
+ if (client_->IsLoggingActive()) { |
+ logger.reset(new 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(), logger.get()); |
return; |
} |
// No password to save? Then don't. |
if (form.password_value.empty()) { |
- RecordFailure(EMPTY_PASSWORD, form.origin.host()); |
+ RecordFailure(EMPTY_PASSWORD, form.origin.host(), logger.get()); |
return; |
} |
@@ -130,6 +146,8 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
if ((*iter)->DoesManage(form, PasswordFormManager::ACTION_MATCH_REQUIRED)) { |
// If we find a manager that exactly matches the submitted form including |
// the action URL, exit the loop. |
+ if (logger) |
+ logger->LogMessage(Logger::STRING_EXACT_MATCH); |
matched_manager_it = iter; |
break; |
} else if ((*iter)->DoesManage( |
@@ -137,6 +155,8 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// 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 (logger) |
+ logger->LogMessage(Logger::STRING_MATCH_WITHOUT_ACTION); |
matched_manager_it = iter; |
} |
} |
@@ -149,7 +169,7 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
manager.reset(*matched_manager_it); |
pending_login_managers_.weak_erase(matched_manager_it); |
} else { |
- RecordFailure(NO_MATCHING_FORM, form.origin.host()); |
+ RecordFailure(NO_MATCHING_FORM, form.origin.host(), logger.get()); |
return; |
} |
@@ -158,20 +178,20 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// results for the given form and autofill. If this is the case, we just |
// give up. |
if (!manager->HasCompletedMatching()) { |
- RecordFailure(MATCHING_NOT_COMPLETE, form.origin.host()); |
+ RecordFailure(MATCHING_NOT_COMPLETE, form.origin.host(), logger.get()); |
return; |
} |
// Also get out of here if the user told us to 'never remember' passwords for |
// this form. |
if (manager->IsBlacklisted()) { |
- RecordFailure(FORM_BLACKLISTED, form.origin.host()); |
+ RecordFailure(FORM_BLACKLISTED, form.origin.host(), logger.get()); |
return; |
} |
// Bail if we're missing any of the necessary form components. |
if (!manager->HasValidPasswordForm()) { |
- RecordFailure(INVALID_FORM, form.origin.host()); |
+ RecordFailure(INVALID_FORM, form.origin.host(), logger.get()); |
return; |
} |
@@ -180,7 +200,7 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
// autocomplete attribute if autocomplete='off' is not ignored. |
if (!autofill::ShouldIgnoreAutocompleteOffForPasswordFields() && |
!manager->HasGeneratedPassword() && !form.password_autocomplete_set) { |
- RecordFailure(AUTOCOMPLETE_OFF, form.origin.host()); |
+ RecordFailure(AUTOCOMPLETE_OFF, form.origin.host(), logger.get()); |
return; |
} |
@@ -189,16 +209,26 @@ 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) { |
+ const std::string& form_origin, |
+ BrowserSavePasswordProgressLogger* logger) { |
UMA_HISTOGRAM_ENUMERATION( |
"PasswordManager.ProvisionalSaveFailure", failure, MAX_FAILURE_VALUE); |
@@ -210,6 +240,36 @@ void PasswordManager::RecordFailure(ProvisionalSaveFailure failure, |
failure, |
MAX_FAILURE_VALUE); |
} |
+ |
+ if (logger) { |
+ switch (failure) { |
+ case SAVING_DISABLED: |
+ logger->LogMessage(Logger::STRING_SAVING_DISABLED); |
+ break; |
+ case EMPTY_PASSWORD: |
+ logger->LogMessage(Logger::STRING_EMPTY_PASSWORD); |
+ break; |
+ case MATCHING_NOT_COMPLETE: |
+ logger->LogMessage(Logger::STRING_NO_FORM_MANAGER); |
+ break; |
+ case NO_MATCHING_FORM: |
+ logger->LogMessage(Logger::STRING_NO_MATCHING_FORM); |
+ break; |
+ case FORM_BLACKLISTED: |
+ logger->LogMessage(Logger::STRING_FORM_BLACKLISTED); |
+ break; |
+ case INVALID_FORM: |
+ logger->LogMessage(Logger::STRING_INVALID_FORM); |
+ break; |
+ case AUTOCOMPLETE_OFF: |
+ logger->LogMessage(Logger::STRING_AUTOCOMPLETE_OFF); |
+ break; |
+ case MAX_FAILURE_VALUE: |
+ NOTREACHED(); |
+ return; |
+ } |
+ logger->LogMessage(Logger::STRING_DECISION_DROP); |
+ } |
} |
void PasswordManager::AddSubmissionCallback( |
@@ -280,11 +340,27 @@ bool PasswordManager::ShouldPromptUserToSavePassword() const { |
void PasswordManager::OnPasswordFormsRendered( |
const std::vector<PasswordForm>& visible_forms) { |
- if (!provisional_save_manager_.get()) |
+ scoped_ptr<BrowserSavePasswordProgressLogger> logger; |
+ if (client_->IsLoggingActive()) { |
+ logger.reset(new 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 |
@@ -293,6 +369,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; |
@@ -306,8 +387,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(); |
} |