[Password manager] Temporarily add some CHECKs to investigate a crash
[chromium-blink-merge.git] / chrome / browser / ui / autofill / password_generation_popup_controller_impl.cc
blob26a3649ee621f68aa309a8621e11903f04d3233d
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 "components/autofill/content/common/autofill_messages.h"
23 #include "components/autofill/core/browser/password_generator.h"
24 #include "components/password_manager/core/browser/password_manager.h"
25 #include "content/public/browser/native_web_keyboard_event.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/events/keycodes/keyboard_codes.h"
30 #include "ui/gfx/geometry/rect_conversions.h"
31 #include "ui/gfx/text_utils.h"
33 #if defined(OS_ANDROID)
34 #include "chrome/browser/android/chromium_application.h"
35 #endif
37 namespace autofill {
39 base::WeakPtr<PasswordGenerationPopupControllerImpl>
40 PasswordGenerationPopupControllerImpl::GetOrCreate(
41 base::WeakPtr<PasswordGenerationPopupControllerImpl> previous,
42 const gfx::RectF& bounds,
43 const PasswordForm& form,
44 int max_length,
45 password_manager::PasswordManager* password_manager,
46 password_manager::PasswordManagerDriver* driver,
47 PasswordGenerationPopupObserver* observer,
48 content::WebContents* web_contents,
49 gfx::NativeView container_view) {
50 if (previous.get() &&
51 previous->element_bounds() == bounds &&
52 previous->web_contents() == web_contents &&
53 previous->container_view() == container_view) {
54 return previous;
57 if (previous.get())
58 previous->Hide();
60 PasswordGenerationPopupControllerImpl* controller =
61 new PasswordGenerationPopupControllerImpl(
62 bounds, form, max_length, password_manager, driver, observer,
63 web_contents, container_view);
64 return controller->GetWeakPtr();
67 PasswordGenerationPopupControllerImpl::PasswordGenerationPopupControllerImpl(
68 const gfx::RectF& bounds,
69 const PasswordForm& form,
70 int max_length,
71 password_manager::PasswordManager* password_manager,
72 password_manager::PasswordManagerDriver* driver,
73 PasswordGenerationPopupObserver* observer,
74 content::WebContents* web_contents,
75 gfx::NativeView container_view)
76 : view_(NULL),
77 form_(form),
78 password_manager_(password_manager),
79 driver_(driver),
80 observer_(observer),
81 generator_(new PasswordGenerator(max_length)),
82 controller_common_(bounds, container_view, web_contents),
83 password_selected_(false),
84 display_password_(false),
85 weak_ptr_factory_(this) {
86 controller_common_.SetKeyPressCallback(
87 base::Bind(&PasswordGenerationPopupControllerImpl::HandleKeyPressEvent,
88 base::Unretained(this)));
90 std::vector<base::string16> pieces;
91 base::SplitStringDontTrim(
92 l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_PROMPT),
93 '|', // separator
94 &pieces);
95 DCHECK_EQ(3u, pieces.size());
96 link_range_ = gfx::Range(pieces[0].size(),
97 pieces[0].size() + pieces[1].size());
98 help_text_ = JoinString(pieces, base::string16());
101 PasswordGenerationPopupControllerImpl::~PasswordGenerationPopupControllerImpl()
104 base::WeakPtr<PasswordGenerationPopupControllerImpl>
105 PasswordGenerationPopupControllerImpl::GetWeakPtr() {
106 return weak_ptr_factory_.GetWeakPtr();
109 bool PasswordGenerationPopupControllerImpl::HandleKeyPressEvent(
110 const content::NativeWebKeyboardEvent& event) {
111 switch (event.windowsKeyCode) {
112 case ui::VKEY_UP:
113 case ui::VKEY_DOWN:
114 PasswordSelected(true);
115 return true;
116 case ui::VKEY_ESCAPE:
117 Hide();
118 return true;
119 case ui::VKEY_RETURN:
120 case ui::VKEY_TAB:
121 // We suppress tab if the password is selected because we will
122 // automatically advance focus anyway.
123 return PossiblyAcceptPassword();
124 default:
125 return false;
129 bool PasswordGenerationPopupControllerImpl::PossiblyAcceptPassword() {
130 if (password_selected_) {
131 PasswordAccepted(); // This will delete |this|.
132 return true;
135 return false;
138 void PasswordGenerationPopupControllerImpl::PasswordSelected(bool selected) {
139 if (!display_password_ || selected == password_selected_)
140 return;
142 password_selected_ = selected;
143 view_->PasswordSelectionUpdated();
144 view_->UpdateBoundsAndRedrawPopup();
147 void PasswordGenerationPopupControllerImpl::PasswordAccepted() {
148 if (!display_password_)
149 return;
151 driver_->GeneratedPasswordAccepted(current_password_);
152 password_manager_->SetHasGeneratedPasswordForForm(driver_, form_, true);
153 Hide();
156 int PasswordGenerationPopupControllerImpl::GetMinimumWidth() {
157 // Minimum width in pixels.
158 const int minimum_width = 350;
160 // If the width of the field is longer than the minimum, use that instead.
161 return std::max(minimum_width,
162 controller_common_.RoundedElementBounds().width());
165 void PasswordGenerationPopupControllerImpl::CalculateBounds() {
166 gfx::Size bounds = view_->GetPreferredSizeOfPasswordView();
168 popup_bounds_ = controller_common_.GetPopupBounds(bounds.width(),
169 bounds.height());
172 void PasswordGenerationPopupControllerImpl::Show(bool display_password) {
173 display_password_ = display_password;
174 if (display_password_ && current_password_.empty())
175 current_password_ = base::ASCIIToUTF16(generator_->Generate());
177 if (!view_) {
178 view_ = PasswordGenerationPopupView::Create(this);
180 // Treat popup as being hidden if creation fails.
181 if (!view_) {
182 Hide();
183 return;
186 CalculateBounds();
187 view_->Show();
188 } else {
189 CalculateBounds();
190 view_->UpdateBoundsAndRedrawPopup();
193 controller_common_.RegisterKeyPressCallback();
195 if (observer_)
196 observer_->OnPopupShown(display_password_);
199 void PasswordGenerationPopupControllerImpl::HideAndDestroy() {
200 Hide();
203 void PasswordGenerationPopupControllerImpl::Hide() {
204 controller_common_.RemoveKeyPressCallback();
206 if (view_)
207 view_->Hide();
209 if (observer_)
210 observer_->OnPopupHidden();
212 delete this;
215 void PasswordGenerationPopupControllerImpl::ViewDestroyed() {
216 view_ = NULL;
218 Hide();
221 void PasswordGenerationPopupControllerImpl::OnSavedPasswordsLinkClicked() {
222 #if defined(OS_ANDROID)
223 chrome::android::ChromiumApplication::ShowPasswordSettings();
224 #else
225 chrome::ShowSettingsSubPage(
226 chrome::FindBrowserWithWebContents(controller_common_.web_contents()),
227 chrome::kPasswordManagerSubPage);
228 #endif
231 void PasswordGenerationPopupControllerImpl::SetSelectionAtPoint(
232 const gfx::Point& point) {
233 PasswordSelected(view_->IsPointInPasswordBounds(point));
236 bool PasswordGenerationPopupControllerImpl::AcceptSelectedLine() {
237 if (!password_selected_)
238 return false;
240 PasswordAccepted();
241 return true;
244 void PasswordGenerationPopupControllerImpl::SelectionCleared() {
245 PasswordSelected(false);
248 gfx::NativeView PasswordGenerationPopupControllerImpl::container_view() {
249 return controller_common_.container_view();
252 const gfx::Rect& PasswordGenerationPopupControllerImpl::popup_bounds() const {
253 return popup_bounds_;
256 const gfx::RectF& PasswordGenerationPopupControllerImpl::element_bounds()
257 const {
258 return controller_common_.element_bounds();
261 bool PasswordGenerationPopupControllerImpl::IsRTL() const {
262 return base::i18n::IsRTL();
265 bool PasswordGenerationPopupControllerImpl::display_password() const {
266 return display_password_;
269 bool PasswordGenerationPopupControllerImpl::password_selected() const {
270 return password_selected_;
273 base::string16 PasswordGenerationPopupControllerImpl::password() const {
274 return current_password_;
277 base::string16 PasswordGenerationPopupControllerImpl::SuggestedText() {
278 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_SUGGESTION);
281 const base::string16& PasswordGenerationPopupControllerImpl::HelpText() {
282 return help_text_;
285 const gfx::Range& PasswordGenerationPopupControllerImpl::HelpTextLinkRange() {
286 return link_range_;
289 } // namespace autofill