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

Unified Diff: chrome/browser/ui/passwords/manage_passwords_state.cc

Issue 993513006: Introduce ManagePasswordsState class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/passwords/manage_passwords_state.cc
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.cc b/chrome/browser/ui/passwords/manage_passwords_state.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ad73daa6c40f73059112c913b293aa83fc0b0222
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_state.cc
@@ -0,0 +1,264 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/passwords/manage_passwords_state.h"
+
+#include "components/password_manager/content/common/credential_manager_types.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"
+
+using password_manager::PasswordFormManager;
+using autofill::PasswordFormMap;
+
+namespace {
+
+// Converts the map with pointers or const pointers to the vector of const
+// pointers.
+template <typename T>
+std::vector<const T*> MapToVector(
+ const std::map<base::string16, T*>& map) {
+ std::vector<const autofill::PasswordForm*> ret;
+ ret.reserve(map.size());
+ for (const auto& form_pair : map)
+ ret.push_back(form_pair.second);
+ return ret;
+}
+
+ScopedVector<const autofill::PasswordForm> DeepCopyMapToVector(
+ const PasswordFormMap& password_form_map) {
+ ScopedVector<const autofill::PasswordForm> ret;
+ ret.reserve(password_form_map.size());
+ for (const auto& form_pair : password_form_map)
+ ret.push_back(new autofill::PasswordForm(*form_pair.second));
+ return ret.Pass();
+}
+
+ScopedVector<const autofill::PasswordForm> ConstifyVector(
+ ScopedVector<autofill::PasswordForm>* forms) {
+ ScopedVector<const autofill::PasswordForm> ret;
+ ret.assign(forms->begin(), forms->end());
+ forms->weak_clear();
+ return ret.Pass();
+}
+
+// True if the unique keys for the forms are the same. The unique key is
+// (origin, username_element, username_value, password_element, signon_realm).
+bool IsEqualUniqueKey(const autofill::PasswordForm& left,
+ const autofill::PasswordForm& right) {
+ return left.signon_realm == right.signon_realm &&
+ left.origin == right.origin &&
+ left.username_element == right.username_element &&
+ left.username_value == right.username_value &&
+ left.password_element == right.password_element;
+}
+
+// Updates a form in |forms| that has the same unique key as |updated_form|.
vabr (Chromium) 2015/03/10 12:26:22 Maybe there was a misunderstanding -- the point I
+bool UpdateFormInVector(const autofill::PasswordForm& updated_form,
+ ScopedVector<const autofill::PasswordForm>* forms) {
+ ScopedVector<const autofill::PasswordForm>::iterator it = std::find_if(
+ forms->begin(), forms->end(),
+ [&updated_form](const autofill::PasswordForm* form) {
+ return IsEqualUniqueKey(*form, updated_form);
+ });
+ if (it != forms->end()) {
+ delete *it;
+ *it = new autofill::PasswordForm(updated_form);
+ return true;
+ }
+ return false;
+}
+
+// Removes a form from |forms| that has the same unique key as |form_to_delete|.
+template <class Vector>
+void RemoveFormFromVector(const autofill::PasswordForm& form_to_delete,
+ Vector* forms) {
+ typename Vector::iterator it = std::find_if(
+ forms->begin(), forms->end(),
+ [&form_to_delete](const autofill::PasswordForm* form) {
+ return IsEqualUniqueKey(*form, form_to_delete);
+ });
+ if (it != forms->end())
+ forms->erase(it);
+}
+
+} // namespace
+
+ManagePasswordsState::ManagePasswordsState()
+ : state_(password_manager::ui::INACTIVE_STATE),
+ client_(nullptr) {
+}
+
+ManagePasswordsState::~ManagePasswordsState() {}
+
+void ManagePasswordsState::OnPendingPassword(
+ scoped_ptr<password_manager::PasswordFormManager> form_manager) {
+ ClearData();
+ form_manager_ = form_manager.Pass();
+ current_forms_weak_ = MapToVector(form_manager_->best_matches());
+ origin_ = form_manager_->pending_credentials().origin;
+ SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+}
+
+void ManagePasswordsState::OnRequestCredentials(
+ ScopedVector<autofill::PasswordForm> local_credentials,
+ ScopedVector<autofill::PasswordForm> federated_credentials,
+ const GURL& origin) {
+ ClearData();
+ local_credentials_forms_ = ConstifyVector(&local_credentials);
+ federated_credentials_forms_ = ConstifyVector(&federated_credentials);
+ origin_ = origin;
+ SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE);
+}
+
+void ManagePasswordsState::OnAutoSignin(
+ ScopedVector<autofill::PasswordForm> local_forms) {
+ DCHECK(!local_forms.empty());
+ ClearData();
+ local_credentials_forms_ = ConstifyVector(&local_forms);
+ origin_ = local_credentials_forms_[0]->origin;
+ SetState(password_manager::ui::AUTO_SIGNIN_STATE);
+}
+
+void ManagePasswordsState::OnAutomaticPasswordSave(
+ scoped_ptr<PasswordFormManager> form_manager) {
+ ClearData();
+ form_manager_ = form_manager.Pass();
+ autofill::ConstPasswordFormMap current_forms;
+ current_forms.insert(form_manager_->best_matches().begin(),
+ form_manager_->best_matches().end());
+ current_forms[form_manager_->associated_username()] =
+ &form_manager_->pending_credentials();
+ current_forms_weak_ = MapToVector(current_forms);
+ origin_ = form_manager_->pending_credentials().origin;
+ SetState(password_manager::ui::CONFIRMATION_STATE);
+}
+
+void ManagePasswordsState::OnPasswordAutofilled(
+ const PasswordFormMap& password_form_map) {
+ DCHECK(!password_form_map.empty());
+ ClearData();
+ if (password_form_map.begin()->second->IsPublicSuffixMatch()) {
+ // Don't show the UI for PSL matched passwords. They are not stored for this
+ // page and cannot be deleted.
+ origin_ = GURL();
+ SetState(password_manager::ui::INACTIVE_STATE);
+ } else {
+ local_credentials_forms_ = DeepCopyMapToVector(password_form_map);
+ origin_ = local_credentials_forms_.front()->origin;
+ SetState(password_manager::ui::MANAGE_STATE);
+ }
+}
+
+void ManagePasswordsState::OnBlacklistBlockedAutofill(
+ const autofill::PasswordFormMap& password_form_map) {
+ DCHECK(!password_form_map.empty());
+ ClearData();
+ local_credentials_forms_ = DeepCopyMapToVector(password_form_map);
+ origin_ = local_credentials_forms_.front()->origin;
+ SetState(password_manager::ui::BLACKLIST_STATE);
+}
+
+void ManagePasswordsState::OnInactive() {
+ ClearData();
+ origin_ = GURL();
+ SetState(password_manager::ui::INACTIVE_STATE);
+}
+
+void ManagePasswordsState::TransitionToState(
+ password_manager::ui::State state) {
+ DCHECK_NE(password_manager::ui::INACTIVE_STATE, state_);
+ DCHECK(state == password_manager::ui::BLACKLIST_STATE ||
+ state == password_manager::ui::MANAGE_STATE);
+ if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE &&
+ !credentials_callback_.is_null()) {
+ credentials_callback_.Run(password_manager::CredentialInfo());
+ credentials_callback_.Reset();
+ }
+ SetState(state);
+}
+
+void ManagePasswordsState::ProcessLoginsChanged(
+ const password_manager::PasswordStoreChangeList& changes) {
+ if (state() == password_manager::ui::INACTIVE_STATE)
+ return;
+
+ for (const password_manager::PasswordStoreChange& change : changes) {
+ const autofill::PasswordForm& changed_form = change.form();
+ if (change.type() == password_manager::PasswordStoreChange::REMOVE) {
+ DeleteForm(changed_form);
+ if (changed_form.blacklisted_by_user &&
+ state() == password_manager::ui::BLACKLIST_STATE &&
+ changed_form.origin == origin_) {
+ TransitionToState(password_manager::ui::MANAGE_STATE);
+ }
+ } else {
+ if (change.type() == password_manager::PasswordStoreChange::UPDATE)
+ UpdateForm(changed_form);
+ else
+ AddForm(changed_form);
+ if (changed_form.blacklisted_by_user &&
+ changed_form.origin == origin_) {
+ TransitionToState(password_manager::ui::BLACKLIST_STATE);
+ }
+ }
+ }
+}
+
+void ManagePasswordsState::ClearData() {
+ form_manager_.reset();
+ current_forms_weak_.clear();
+ local_credentials_forms_.clear();
+ federated_credentials_forms_.clear();
+ credentials_callback_.Reset();
+}
+
+void ManagePasswordsState::AddForm(const autofill::PasswordForm& form) {
+ if (form.origin != origin_)
+ return;
+ if (UpdateForm(form))
+ return;
+ local_credentials_forms_.push_back(new autofill::PasswordForm(form));
+ if (form_manager_)
+ current_forms_weak_.push_back(local_credentials_forms_.back());
+}
+
+bool ManagePasswordsState::UpdateForm(const autofill::PasswordForm& form) {
+ if (form_manager_) {
+ // |current_forms_weak_| contains the list of current passwords.
+ std::vector<const autofill::PasswordForm*>::iterator it = std::find_if(
+ current_forms_weak_.begin(), current_forms_weak_.end(),
+ [&form](const autofill::PasswordForm* current_form) {
+ return IsEqualUniqueKey(form, *current_form);
+ });
+ if (it != current_forms_weak_.end()) {
+ RemoveFormFromVector(form, &local_credentials_forms_);
+ local_credentials_forms_.push_back(new autofill::PasswordForm(form));
+ *it = local_credentials_forms_.back();
+ return true;
+ }
+ } else {
+ // |current_forms_weak_| isn't used.
+ bool updated_locals = UpdateFormInVector(form, &local_credentials_forms_);
+ return (UpdateFormInVector(form, &federated_credentials_forms_) ||
+ updated_locals);
+ }
+ return false;
+}
+
+void ManagePasswordsState::DeleteForm(const autofill::PasswordForm& form) {
+ RemoveFormFromVector(form, &current_forms_weak_);
+ RemoveFormFromVector(form, &local_credentials_forms_);
+ RemoveFormFromVector(form, &federated_credentials_forms_);
+}
+
+void ManagePasswordsState::SetState(password_manager::ui::State state) {
+ if (client_ && client_->IsLoggingActive()) {
+ password_manager::BrowserSavePasswordProgressLogger logger(client_);
+ logger.LogNumber(
+ autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE,
+ state);
+ }
+ state_ = state;
+}

Powered by Google App Engine
This is Rietveld 408576698