app_shell: Add version number in user agent
[chromium-blink-merge.git] / chrome / browser / ui / passwords / manage_passwords_bubble_model.cc
blob677965f6802d22969f79043f05c99996ea7008cf
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/string_util.h"
9 #include "chrome/browser/password_manager/password_store_factory.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_finder.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
13 #include "components/password_manager/core/browser/password_store.h"
14 #include "components/password_manager/core/common/password_manager_ui.h"
15 #include "grit/generated_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
19 using autofill::PasswordFormMap;
20 using content::WebContents;
21 namespace metrics_util = password_manager::metrics_util;
23 namespace {
25 enum FieldType { USERNAME_FIELD, PASSWORD_FIELD };
27 const int kUsernameFieldSize = 30;
28 const int kPasswordFieldSize = 22;
30 // Returns the width of |type| field.
31 int GetFieldWidth(FieldType type) {
32 return ui::ResourceBundle::GetSharedInstance()
33 .GetFontList(ui::ResourceBundle::SmallFont)
34 .GetExpectedTextWidth(type == USERNAME_FIELD ? kUsernameFieldSize
35 : kPasswordFieldSize);
38 void SetupLinkifiedText(const base::string16& string_with_separator,
39 base::string16* text,
40 gfx::Range* link_range) {
41 std::vector<base::string16> pieces;
42 base::SplitStringDontTrim(string_with_separator,
43 '|', // separator
44 &pieces);
45 DCHECK_EQ(3u, pieces.size());
46 *link_range = gfx::Range(pieces[0].size(),
47 pieces[0].size() + pieces[1].size());
48 *text = JoinString(pieces, base::string16());
51 } // namespace
53 ManagePasswordsBubbleModel::ManagePasswordsBubbleModel(
54 content::WebContents* web_contents)
55 : content::WebContentsObserver(web_contents),
56 display_disposition_(
57 metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING),
58 dismissal_reason_(metrics_util::NOT_DISPLAYED) {
59 ManagePasswordsUIController* controller =
60 ManagePasswordsUIController::FromWebContents(web_contents);
62 // TODO(mkwst): Reverse this logic. The controller should populate the model
63 // directly rather than the model pulling from the controller. Perhaps like
64 // `controller->PopulateModel(this)`.
65 state_ = controller->state();
66 if (password_manager::ui::IsPendingState(state_))
67 pending_credentials_ = controller->PendingCredentials();
68 best_matches_ = controller->best_matches();
70 if (password_manager::ui::IsPendingState(state_)) {
71 title_ = l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD);
72 } else if (state_ == password_manager::ui::BLACKLIST_STATE) {
73 title_ = l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_BLACKLISTED_TITLE);
74 } else if (state_ == password_manager::ui::CONFIRMATION_STATE) {
75 title_ =
76 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TITLE);
77 } else {
78 title_ = l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_TITLE);
81 SetupLinkifiedText(
82 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT),
83 &save_confirmation_text_,
84 &save_confirmation_link_range_);
86 manage_link_ =
87 l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK);
90 ManagePasswordsBubbleModel::~ManagePasswordsBubbleModel() {}
92 void ManagePasswordsBubbleModel::OnBubbleShown(
93 ManagePasswordsBubble::DisplayReason reason) {
94 if (reason == ManagePasswordsBubble::USER_ACTION) {
95 if (password_manager::ui::IsPendingState(state_)) {
96 display_disposition_ = metrics_util::MANUAL_WITH_PASSWORD_PENDING;
97 } else if (state_ == password_manager::ui::BLACKLIST_STATE) {
98 display_disposition_ = metrics_util::MANUAL_BLACKLISTED;
99 } else {
100 display_disposition_ = metrics_util::MANUAL_MANAGE_PASSWORDS;
102 } else {
103 if (state_ == password_manager::ui::CONFIRMATION_STATE) {
104 display_disposition_ =
105 metrics_util::AUTOMATIC_GENERATED_PASSWORD_CONFIRMATION;
106 } else {
107 display_disposition_ = metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING;
110 metrics_util::LogUIDisplayDisposition(display_disposition_);
112 // Default to a dismissal reason of "no interaction". If the user interacts
113 // with the button in such a way that it closes, we'll reset this value
114 // accordingly.
115 dismissal_reason_ = metrics_util::NO_DIRECT_INTERACTION;
118 void ManagePasswordsBubbleModel::OnBubbleHidden() {
119 if (dismissal_reason_ == metrics_util::NOT_DISPLAYED)
120 return;
122 metrics_util::LogUIDismissalReason(dismissal_reason_);
125 void ManagePasswordsBubbleModel::OnNopeClicked() {
126 dismissal_reason_ = metrics_util::CLICKED_NOPE;
127 state_ = password_manager::ui::PENDING_PASSWORD_STATE;
130 void ManagePasswordsBubbleModel::OnNeverForThisSiteClicked() {
131 dismissal_reason_ = metrics_util::CLICKED_NEVER;
132 ManagePasswordsUIController* manage_passwords_ui_controller =
133 ManagePasswordsUIController::FromWebContents(web_contents());
134 manage_passwords_ui_controller->NeverSavePassword();
135 state_ = password_manager::ui::BLACKLIST_STATE;
138 void ManagePasswordsBubbleModel::OnUnblacklistClicked() {
139 dismissal_reason_ = metrics_util::CLICKED_UNBLACKLIST;
140 ManagePasswordsUIController* manage_passwords_ui_controller =
141 ManagePasswordsUIController::FromWebContents(web_contents());
142 manage_passwords_ui_controller->UnblacklistSite();
143 state_ = password_manager::ui::MANAGE_STATE;
146 void ManagePasswordsBubbleModel::OnSaveClicked() {
147 dismissal_reason_ = metrics_util::CLICKED_SAVE;
148 ManagePasswordsUIController* manage_passwords_ui_controller =
149 ManagePasswordsUIController::FromWebContents(web_contents());
150 manage_passwords_ui_controller->SavePassword();
151 state_ = password_manager::ui::MANAGE_STATE;
154 void ManagePasswordsBubbleModel::OnDoneClicked() {
155 dismissal_reason_ = metrics_util::CLICKED_DONE;
158 // TODO(gcasto): Is it worth having this be separate from OnDoneClicked()?
159 // User intent is pretty similar in both cases.
160 void ManagePasswordsBubbleModel::OnOKClicked() {
161 dismissal_reason_ = metrics_util::CLICKED_OK;
164 void ManagePasswordsBubbleModel::OnManageLinkClicked() {
165 dismissal_reason_ = metrics_util::CLICKED_MANAGE;
166 ManagePasswordsUIController::FromWebContents(web_contents())
167 ->NavigateToPasswordManagerSettingsPage();
170 // TODO(gcasto): Is it worth having a new dismissal reason to distinguish
171 // the two management cases? User intention is pretty similar between the two,
172 // but the context in which they are shown is pretty different since one is
173 // from an explict action and the other isn't.
174 void ManagePasswordsBubbleModel::OnRemoteManageLinkClicked() {
175 dismissal_reason_ = metrics_util::CLICKED_MANAGE;
176 ManagePasswordsUIController::FromWebContents(web_contents())
177 ->NavigateToAccountCentralManagementPage();
180 void ManagePasswordsBubbleModel::OnPasswordAction(
181 const autofill::PasswordForm& password_form,
182 PasswordAction action) {
183 if (!web_contents())
184 return;
185 Profile* profile =
186 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
187 password_manager::PasswordStore* password_store =
188 PasswordStoreFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS)
189 .get();
190 DCHECK(password_store);
191 if (action == REMOVE_PASSWORD)
192 password_store->RemoveLogin(password_form);
193 else
194 password_store->AddLogin(password_form);
197 // static
198 int ManagePasswordsBubbleModel::UsernameFieldWidth() {
199 return GetFieldWidth(USERNAME_FIELD);
202 // static
203 int ManagePasswordsBubbleModel::PasswordFieldWidth() {
204 return GetFieldWidth(PASSWORD_FIELD);