Index: chrome/browser/password_manager/password_manager.cc |
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc |
index 3964d2e4eac9b2aa1861d287d24dfb0c498ba6de..aa097bafb3771c68f5c6ec06ee60fef4546cf1e4 100644 |
--- a/chrome/browser/password_manager/password_manager.cc |
+++ b/chrome/browser/password_manager/password_manager.cc |
@@ -4,9 +4,6 @@ |
#include "chrome/browser/password_manager/password_manager.h" |
-#include <vector> |
- |
-#include "base/stl_util.h" |
#include "base/threading/platform_thread.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/browser/password_manager/password_form_manager.h" |
@@ -24,15 +21,7 @@ using content::WebContents; |
using webkit::forms::PasswordForm; |
using webkit::forms::PasswordFormMap; |
-// static |
-void PasswordManager::RegisterUserPrefs(PrefService* prefs) { |
- prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled, |
- true, |
- PrefService::SYNCABLE_PREF); |
- prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords, |
- true, |
- PrefService::UNSYNCABLE_PREF); |
-} |
+namespace { |
// This routine is called when PasswordManagers are constructed. |
// |
@@ -40,7 +29,7 @@ void PasswordManager::RegisterUserPrefs(PrefService* prefs) { |
// that this is only ever called from a single thread in order to |
// avoid needing to lock (a static boolean flag is then sufficient to |
// guarantee running only once). |
-static void ReportMetrics(bool password_manager_enabled) { |
+void ReportMetrics(bool password_manager_enabled) { |
static base::PlatformThreadId initial_thread_id = |
base::PlatformThread::CurrentId(); |
DCHECK(initial_thread_id == base::PlatformThread::CurrentId()); |
@@ -50,16 +39,29 @@ static void ReportMetrics(bool password_manager_enabled) { |
return; |
ran_once = true; |
+ // TODO(isherman): This does not actually measure a user action. It should be |
+ // a boolean histogram. |
if (password_manager_enabled) |
content::RecordAction(UserMetricsAction("PasswordManager_Enabled")); |
else |
content::RecordAction(UserMetricsAction("PasswordManager_Disabled")); |
} |
+} // anonymous namespace |
+ |
+// static |
+void PasswordManager::RegisterUserPrefs(PrefService* prefs) { |
+ prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled, |
+ true, |
+ PrefService::SYNCABLE_PREF); |
+ prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords, |
+ true, |
+ PrefService::UNSYNCABLE_PREF); |
+} |
+ |
PasswordManager::PasswordManager(WebContents* web_contents, |
PasswordManagerDelegate* delegate) |
: content::WebContentsObserver(web_contents), |
- login_managers_deleter_(&pending_login_managers_), |
delegate_(delegate), |
observer_(NULL) { |
DCHECK(delegate_); |
@@ -72,22 +74,21 @@ PasswordManager::PasswordManager(WebContents* web_contents, |
PasswordManager::~PasswordManager() { |
} |
-void PasswordManager::ProvisionallySavePassword(PasswordForm form) { |
- if (!delegate_->GetProfileForPasswordManager() || |
- delegate_->GetProfileForPasswordManager()->IsOffTheRecord() || |
- !*password_manager_enabled_) |
+void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { |
+ if (!IsEnabled()) |
return; |
// No password to save? Then don't. |
if (form.password_value.empty()) |
return; |
- LoginManagers::iterator iter; |
PasswordFormManager* manager = NULL; |
- for (iter = pending_login_managers_.begin(); |
- iter != pending_login_managers_.end(); iter++) { |
+ for (ScopedVector<PasswordFormManager>::iterator iter = |
+ pending_login_managers_.begin(); |
+ iter != pending_login_managers_.end(); ++iter) { |
if ((*iter)->DoesManage(form)) { |
manager = *iter; |
+ pending_login_managers_.weak_erase(iter); |
break; |
} |
} |
@@ -109,26 +110,12 @@ void PasswordManager::ProvisionallySavePassword(PasswordForm form) { |
if (manager->IsBlacklisted()) |
return; |
- form.ssl_valid = form.origin.SchemeIsSecure() && |
+ PasswordForm provisionally_saved_form(form); |
+ provisionally_saved_form.ssl_valid = form.origin.SchemeIsSecure() && |
!delegate_->DidLastPageLoadEncounterSSLErrors(); |
- form.preferred = true; |
- manager->ProvisionallySave(form); |
+ provisionally_saved_form.preferred = true; |
+ manager->ProvisionallySave(provisionally_saved_form); |
provisional_save_manager_.reset(manager); |
- pending_login_managers_.erase(iter); |
- // We don't care about the rest of the forms on the page now that one |
- // was selected. |
- STLDeleteElements(&pending_login_managers_); |
-} |
- |
-void PasswordManager::DidNavigate() { |
- // As long as this navigation isn't due to a currently pending |
- // password form submit, we're ready to reset and move on. |
- if (!provisional_save_manager_.get() && !pending_login_managers_.empty()) |
- STLDeleteElements(&pending_login_managers_); |
-} |
- |
-void PasswordManager::ClearProvisionalSave() { |
- provisional_save_manager_.reset(); |
} |
void PasswordManager::SetObserver(LoginModelObserver* observer) { |
@@ -139,11 +126,8 @@ void PasswordManager::DidStopLoading() { |
if (!provisional_save_manager_.get()) |
return; |
- DCHECK(!delegate_->GetProfileForPasswordManager()->IsOffTheRecord()); |
- DCHECK(!provisional_save_manager_->IsBlacklisted()); |
+ DCHECK(IsEnabled()); |
- if (!delegate_->GetProfileForPasswordManager()) |
- return; |
// Form is not completely valid - we do not support it. |
if (!provisional_save_manager_->HasValidPasswordForm()) |
return; |
@@ -162,8 +146,17 @@ void PasswordManager::DidStopLoading() { |
void PasswordManager::DidNavigateAnyFrame( |
const content::LoadCommittedDetails& details, |
const content::FrameNavigateParams& params) { |
- if (params.password_form.origin.is_valid()) |
- ProvisionallySavePassword(params.password_form); |
+ if (!params.password_form.origin.is_valid()) { |
+ // This codepath essentially means that a frame not containing a password |
+ // form was navigated. For example, this might be a subframe of the main |
+ // page, navigated either automatically or in response to a user action. |
+ return; |
+ } |
+ |
+ // There might be password data to provisionally save. Other than that, we're |
+ // ready to reset and move on. |
+ ProvisionallySavePassword(params.password_form); |
+ pending_login_managers_.reset(); |
} |
bool PasswordManager::OnMessageReceived(const IPC::Message& message) { |
@@ -180,16 +173,14 @@ bool PasswordManager::OnMessageReceived(const IPC::Message& message) { |
void PasswordManager::OnPasswordFormsFound( |
const std::vector<PasswordForm>& forms) { |
- if (!delegate_->GetProfileForPasswordManager()) |
- return; |
- if (!*password_manager_enabled_) |
+ if (!IsEnabled()) |
return; |
// Ask the SSLManager for current security. |
bool had_ssl_error = delegate_->DidLastPageLoadEncounterSSLErrors(); |
- std::vector<PasswordForm>::const_iterator iter; |
- for (iter = forms.begin(); iter != forms.end(); iter++) { |
+ for (std::vector<PasswordForm>::const_iterator iter = forms.begin(); |
+ iter != forms.end(); ++iter) { |
bool ssl_valid = iter->origin.SchemeIsSecure() && !had_ssl_error; |
PasswordFormManager* manager = |
new PasswordFormManager(delegate_->GetProfileForPasswordManager(), |
@@ -203,15 +194,16 @@ void PasswordManager::OnPasswordFormsVisible( |
const std::vector<PasswordForm>& visible_forms) { |
if (!provisional_save_manager_.get()) |
return; |
- std::vector<PasswordForm>::const_iterator iter; |
- for (iter = visible_forms.begin(); iter != visible_forms.end(); iter++) { |
+ |
+ for (std::vector<PasswordForm>::const_iterator iter = visible_forms.begin(); |
+ iter != visible_forms.end(); ++iter) { |
if (provisional_save_manager_->DoesManage(*iter)) { |
// The form trying to be saved has immediately re-appeared. Assume login |
// failure and abort this save, by clearing provisional_save_manager_. |
// Don't delete the login managers since the user may try again |
// and we want to be able to save in that case. |
provisional_save_manager_->SubmitFailed(); |
- ClearProvisionalSave(); |
+ provisional_save_manager_.reset(); |
break; |
} |
} |
@@ -220,26 +212,30 @@ void PasswordManager::OnPasswordFormsVisible( |
void PasswordManager::Autofill( |
const PasswordForm& form_for_autofill, |
const PasswordFormMap& best_matches, |
- const PasswordForm* const preferred_match, |
+ const PasswordForm& preferred_match, |
bool wait_for_username) const { |
- DCHECK(preferred_match); |
switch (form_for_autofill.scheme) { |
case PasswordForm::SCHEME_HTML: { |
// Note the check above is required because the observer_ for a non-HTML |
// schemed password form may have been freed, so we need to distinguish. |
webkit::forms::PasswordFormFillData fill_data; |
webkit::forms::PasswordFormDomManager::InitFillData(form_for_autofill, |
- best_matches, |
- preferred_match, |
- wait_for_username, |
- &fill_data); |
+ best_matches, |
+ &preferred_match, |
+ wait_for_username, |
+ &fill_data); |
delegate_->FillPasswordForm(fill_data); |
return; |
} |
default: |
if (observer_) { |
- observer_->OnAutofillDataAvailable(preferred_match->username_value, |
- preferred_match->password_value); |
+ observer_->OnAutofillDataAvailable(preferred_match.username_value, |
+ preferred_match.password_value); |
} |
} |
} |
+ |
+bool PasswordManager::IsEnabled() const { |
+ const Profile* profile = delegate_->GetProfileForPasswordManager(); |
+ return profile && !profile->IsOffTheRecord() && *password_manager_enabled_; |
+} |