Chromium Code Reviews| 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; |
|
Mike Mammarella
2012/03/02 01:46:09
How feasible would it be to write a unit test for
Ilya Sherman
2012/03/02 02:50:06
Done.
|
| + } |
| + |
| + // 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_; |
| +} |