Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / autofill / password_generation_popup_controller_impl.cc
blobf6415e51e60c22e73f34dba189d7fda476abaea5
1 // Copyright 2014 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/autofill/password_generation_popup_controller_impl.h"
7 #include <math.h>
9 #include "base/i18n/rtl.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversion_utils.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/ui/autofill/password_generation_popup_observer.h"
15 #include "chrome/browser/ui/autofill/password_generation_popup_view.h"
16 #include "chrome/browser/ui/autofill/popup_constants.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/chrome_pages.h"
19 #include "chrome/common/url_constants.h"
20 #include "chrome/grit/chromium_strings.h"
21 #include "chrome/grit/generated_resources.h"
22 #include "chrome/grit/google_chrome_strings.h"
23 #include "components/autofill/content/common/autofill_messages.h"
24 #include "components/autofill/core/browser/password_generator.h"
25 #include "components/password_manager/core/browser/password_manager.h"
26 #include "content/public/browser/native_web_keyboard_event.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/events/keycodes/keyboard_codes.h"
31 #include "ui/gfx/geometry/rect_conversions.h"
32 #include "ui/gfx/text_utils.h"
34 #if defined(OS_ANDROID)
35 #include "chrome/browser/android/chromium_application.h"
36 #endif
38 namespace autofill {
40 base::WeakPtr<PasswordGenerationPopupControllerImpl>
41 PasswordGenerationPopupControllerImpl::GetOrCreate(
42 base::WeakPtr<PasswordGenerationPopupControllerImpl> previous,
43 const gfx::RectF& bounds,
44 const PasswordForm& form,
45 int max_length,
46 password_manager::PasswordManager* password_manager,
47 password_manager::PasswordManagerDriver* driver,
48 PasswordGenerationPopupObserver* observer,
49 content::WebContents* web_contents,
50 gfx::NativeView container_view) {
51 if (previous.get() &&
52 previous->element_bounds() == bounds &&
53 previous->web_contents() == web_contents &&
54 previous->container_view() == container_view) {
55 return previous;
58 if (previous.get())
59 previous->Hide();
61 PasswordGenerationPopupControllerImpl* controller =
62 new PasswordGenerationPopupControllerImpl(
63 bounds, form, max_length, password_manager, driver, observer,
64 web_contents, container_view);
65 return controller->GetWeakPtr();
68 PasswordGenerationPopupControllerImpl::PasswordGenerationPopupControllerImpl(
69 const gfx::RectF& bounds,
70 const PasswordForm& form,
71 int max_length,
72 password_manager::PasswordManager* password_manager,
73 password_manager::PasswordManagerDriver* driver,
74 PasswordGenerationPopupObserver* observer,
75 content::WebContents* web_contents,
76 gfx::NativeView container_view)
77 : view_(NULL),
78 form_(form),
79 password_manager_(password_manager),
80 driver_(driver),
81 observer_(observer),
82 generator_(new PasswordGenerator(max_length)),
83 controller_common_(bounds, container_view, web_contents),
84 password_selected_(false),
85 display_password_(false),
86 weak_ptr_factory_(this) {
87 controller_common_.SetKeyPressCallback(
88 base::Bind(&PasswordGenerationPopupControllerImpl::HandleKeyPressEvent,
89 base::Unretained(this)));
91 std::vector<base::string16> pieces;
92 base::SplitStringDontTrim(
93 l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_PROMPT),
94 '|', // separator
95 &pieces);
96 DCHECK_EQ(3u, pieces.size());
97 link_range_ = gfx::Range(pieces[0].size(),
98 pieces[0].size() + pieces[1].size());
99 help_text_ = JoinString(pieces, base::string16());
102 PasswordGenerationPopupControllerImpl::~PasswordGenerationPopupControllerImpl()
105 base::WeakPtr<PasswordGenerationPopupControllerImpl>
106 PasswordGenerationPopupControllerImpl::GetWeakPtr() {
107 return weak_ptr_factory_.GetWeakPtr();
110 bool PasswordGenerationPopupControllerImpl::HandleKeyPressEvent(
111 const content::NativeWebKeyboardEvent& event) {
112 switch (event.windowsKeyCode) {
113 case ui::VKEY_UP:
114 case ui::VKEY_DOWN:
115 PasswordSelected(true);
116 return true;
117 case ui::VKEY_ESCAPE:
118 Hide();
119 return true;
120 case ui::VKEY_RETURN:
121 case ui::VKEY_TAB:
122 // We suppress tab if the password is selected because we will
123 // automatically advance focus anyway.
124 return PossiblyAcceptPassword();
125 default:
126 return false;
130 bool PasswordGenerationPopupControllerImpl::PossiblyAcceptPassword() {
131 if (password_selected_) {
132 PasswordAccepted(); // This will delete |this|.
133 return true;
136 return false;
139 void PasswordGenerationPopupControllerImpl::PasswordSelected(bool selected) {
140 if (!display_password_ || selected == password_selected_)
141 return;
143 password_selected_ = selected;
144 view_->PasswordSelectionUpdated();
145 view_->UpdateBoundsAndRedrawPopup();
148 void PasswordGenerationPopupControllerImpl::PasswordAccepted() {
149 if (!display_password_)
150 return;
152 driver_->GeneratedPasswordAccepted(current_password_);
153 password_manager_->SetFormHasGeneratedPassword(driver_, form_);
154 Hide();
157 int PasswordGenerationPopupControllerImpl::GetMinimumWidth() {
158 // Minimum width in pixels.
159 const int minimum_width = 350;
161 // If the width of the field is longer than the minimum, use that instead.
162 return std::max(minimum_width,
163 controller_common_.RoundedElementBounds().width());
166 void PasswordGenerationPopupControllerImpl::CalculateBounds() {
167 gfx::Size bounds = view_->GetPreferredSizeOfPasswordView();
169 popup_bounds_ = controller_common_.GetPopupBounds(bounds.width(),
170 bounds.height());
173 void PasswordGenerationPopupControllerImpl::Show(bool display_password) {
174 display_password_ = display_password;
175 if (display_password_ && current_password_.empty())
176 current_password_ = base::ASCIIToUTF16(generator_->Generate());
178 if (!view_) {
179 view_ = PasswordGenerationPopupView::Create(this);
181 // Treat popup as being hidden if creation fails.
182 if (!view_) {
183 Hide();
184 return;
187 CalculateBounds();
188 view_->Show();
189 } else {
190 CalculateBounds();
191 view_->UpdateBoundsAndRedrawPopup();
194 controller_common_.RegisterKeyPressCallback();
196 if (observer_)
197 observer_->OnPopupShown(display_password_);
200 void PasswordGenerationPopupControllerImpl::HideAndDestroy() {
201 Hide();
204 void PasswordGenerationPopupControllerImpl::Hide() {
205 controller_common_.RemoveKeyPressCallback();
207 if (view_)
208 view_->Hide();
210 if (observer_)
211 observer_->OnPopupHidden();
213 delete this;
216 void PasswordGenerationPopupControllerImpl::ViewDestroyed() {
217 view_ = NULL;
219 Hide();
222 void PasswordGenerationPopupControllerImpl::OnSavedPasswordsLinkClicked() {
223 #if defined(OS_ANDROID)
224 chrome::android::ChromiumApplication::ShowPasswordSettings();
225 #else
226 chrome::ShowSettingsSubPage(
227 chrome::FindBrowserWithWebContents(controller_common_.web_contents()),
228 chrome::kPasswordManagerSubPage);
229 #endif
232 void PasswordGenerationPopupControllerImpl::SetSelectionAtPoint(
233 const gfx::Point& point) {
234 PasswordSelected(view_->IsPointInPasswordBounds(point));
237 bool PasswordGenerationPopupControllerImpl::AcceptSelectedLine() {
238 if (!password_selected_)
239 return false;
241 PasswordAccepted();
242 return true;
245 void PasswordGenerationPopupControllerImpl::SelectionCleared() {
246 PasswordSelected(false);
249 gfx::NativeView PasswordGenerationPopupControllerImpl::container_view() {
250 return controller_common_.container_view();
253 const gfx::Rect& PasswordGenerationPopupControllerImpl::popup_bounds() const {
254 return popup_bounds_;
257 const gfx::RectF& PasswordGenerationPopupControllerImpl::element_bounds()
258 const {
259 return controller_common_.element_bounds();
262 bool PasswordGenerationPopupControllerImpl::IsRTL() const {
263 return base::i18n::IsRTL();
266 bool PasswordGenerationPopupControllerImpl::display_password() const {
267 return display_password_;
270 bool PasswordGenerationPopupControllerImpl::password_selected() const {
271 return password_selected_;
274 base::string16 PasswordGenerationPopupControllerImpl::password() const {
275 return current_password_;
278 base::string16 PasswordGenerationPopupControllerImpl::SuggestedText() {
279 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_SUGGESTION);
282 const base::string16& PasswordGenerationPopupControllerImpl::HelpText() {
283 return help_text_;
286 const gfx::Range& PasswordGenerationPopupControllerImpl::HelpTextLinkRange() {
287 return link_range_;
290 } // namespace autofill