OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h
" | 5 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h
" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/strings/utf_string_conversion_utils.h" | 9 #include "base/strings/utf_string_conversion_utils.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "chrome/browser/password_manager/password_manager.h" | 11 #include "chrome/browser/password_manager/password_manager.h" |
12 #include "chrome/browser/ui/autofill/password_generation_popup_observer.h" | 12 #include "chrome/browser/ui/autofill/password_generation_popup_observer.h" |
13 #include "chrome/browser/ui/autofill/password_generation_popup_view.h" | 13 #include "chrome/browser/ui/autofill/password_generation_popup_view.h" |
14 #include "chrome/browser/ui/autofill/popup_constants.h" | 14 #include "chrome/browser/ui/autofill/popup_constants.h" |
15 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/browser_finder.h" | 16 #include "chrome/browser/ui/browser_finder.h" |
17 #include "chrome/common/url_constants.h" | 17 #include "chrome/common/url_constants.h" |
18 #include "components/autofill/content/common/autofill_messages.h" | 18 #include "components/autofill/content/common/autofill_messages.h" |
19 #include "components/autofill/core/browser/password_generator.h" | 19 #include "components/autofill/core/browser/password_generator.h" |
20 #include "content/public/browser/native_web_keyboard_event.h" | 20 #include "content/public/browser/native_web_keyboard_event.h" |
21 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
22 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
24 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/base/resource/resource_bundle.h" |
25 #include "ui/events/keycodes/keyboard_codes.h" | 26 #include "ui/events/keycodes/keyboard_codes.h" |
26 #include "ui/gfx/rect_conversions.h" | 27 #include "ui/gfx/rect_conversions.h" |
| 28 #include "ui/gfx/text_utils.h" |
27 | 29 |
28 namespace autofill { | 30 namespace autofill { |
29 | 31 |
30 const int kMinimumWidth = 60; | 32 // All measurements in pixels |
| 33 const int kMinimumWidth = 300; |
31 const int kDividerHeight = 1; | 34 const int kDividerHeight = 1; |
32 | 35 |
33 base::WeakPtr<PasswordGenerationPopupControllerImpl> | 36 base::WeakPtr<PasswordGenerationPopupControllerImpl> |
34 PasswordGenerationPopupControllerImpl::GetOrCreate( | 37 PasswordGenerationPopupControllerImpl::GetOrCreate( |
35 base::WeakPtr<PasswordGenerationPopupControllerImpl> previous, | 38 base::WeakPtr<PasswordGenerationPopupControllerImpl> previous, |
36 const gfx::RectF& bounds, | 39 const gfx::RectF& bounds, |
37 const PasswordForm& form, | 40 PasswordForm* form, |
38 PasswordGenerator* generator, | 41 PasswordGenerator* generator, |
39 PasswordManager* password_manager, | 42 PasswordManager* password_manager, |
40 PasswordGenerationPopupObserver* observer, | 43 PasswordGenerationPopupObserver* observer, |
41 content::WebContents* web_contents, | 44 content::WebContents* web_contents, |
42 gfx::NativeView container_view) { | 45 gfx::NativeView container_view) { |
43 if (previous.get() && | 46 if (previous.get() && |
44 previous->element_bounds() == bounds && | 47 previous->element_bounds() == bounds && |
45 previous->web_contents() == web_contents && | 48 previous->web_contents() == web_contents && |
46 previous->container_view() == container_view) { | 49 previous->container_view() == container_view) { |
47 // TODO(gcasto): Should we clear state here? | 50 previous->set_form(form); |
| 51 previous->set_generator(generator); |
| 52 previous->set_password_manager(password_manager); |
48 return previous; | 53 return previous; |
49 } | 54 } |
50 | 55 |
51 if (previous.get()) | 56 if (previous.get()) |
52 previous->Hide(); | 57 previous->Hide(); |
53 | 58 |
54 PasswordGenerationPopupControllerImpl* controller = | 59 PasswordGenerationPopupControllerImpl* controller = |
55 new PasswordGenerationPopupControllerImpl( | 60 new PasswordGenerationPopupControllerImpl( |
56 bounds, | 61 bounds, |
57 form, | 62 form, |
58 generator, | 63 generator, |
59 password_manager, | 64 password_manager, |
60 observer, | 65 observer, |
61 web_contents, | 66 web_contents, |
62 container_view); | 67 container_view); |
63 return controller->GetWeakPtr(); | 68 return controller->GetWeakPtr(); |
64 } | 69 } |
65 | 70 |
66 PasswordGenerationPopupControllerImpl::PasswordGenerationPopupControllerImpl( | 71 PasswordGenerationPopupControllerImpl::PasswordGenerationPopupControllerImpl( |
67 const gfx::RectF& bounds, | 72 const gfx::RectF& bounds, |
68 const PasswordForm& form, | 73 PasswordForm* form, |
69 PasswordGenerator* generator, | 74 PasswordGenerator* generator, |
70 PasswordManager* password_manager, | 75 PasswordManager* password_manager, |
71 PasswordGenerationPopupObserver* observer, | 76 PasswordGenerationPopupObserver* observer, |
72 content::WebContents* web_contents, | 77 content::WebContents* web_contents, |
73 gfx::NativeView container_view) | 78 gfx::NativeView container_view) |
74 : form_(form), | 79 : form_(form), |
75 generator_(generator), | 80 generator_(generator), |
76 password_manager_(password_manager), | 81 password_manager_(password_manager), |
77 observer_(observer), | 82 observer_(observer), |
78 controller_common_(bounds, container_view, web_contents), | 83 controller_common_(bounds, container_view, web_contents), |
79 view_(NULL), | 84 view_(NULL), |
80 current_password_(base::ASCIIToUTF16(generator->Generate())), | 85 font_list_(ResourceBundle::GetSharedInstance().GetFontList( |
| 86 ResourceBundle::SmallFont)), |
81 password_selected_(false), | 87 password_selected_(false), |
| 88 display_password_(false), |
82 weak_ptr_factory_(this) { | 89 weak_ptr_factory_(this) { |
83 controller_common_.SetKeyPressCallback( | 90 controller_common_.SetKeyPressCallback( |
84 base::Bind(&PasswordGenerationPopupControllerImpl::HandleKeyPressEvent, | 91 base::Bind(&PasswordGenerationPopupControllerImpl::HandleKeyPressEvent, |
85 base::Unretained(this))); | 92 base::Unretained(this))); |
86 } | 93 } |
87 | 94 |
88 PasswordGenerationPopupControllerImpl::~PasswordGenerationPopupControllerImpl() | 95 PasswordGenerationPopupControllerImpl::~PasswordGenerationPopupControllerImpl() |
89 {} | 96 {} |
90 | 97 |
91 base::WeakPtr<PasswordGenerationPopupControllerImpl> | 98 base::WeakPtr<PasswordGenerationPopupControllerImpl> |
(...skipping 15 matching lines...) Expand all Loading... |
107 case ui::VKEY_TAB: | 114 case ui::VKEY_TAB: |
108 // We supress tab if the password is selected because we will | 115 // We supress tab if the password is selected because we will |
109 // automatically advance focus anyway. | 116 // automatically advance focus anyway. |
110 return PossiblyAcceptPassword(); | 117 return PossiblyAcceptPassword(); |
111 default: | 118 default: |
112 return false; | 119 return false; |
113 } | 120 } |
114 } | 121 } |
115 | 122 |
116 bool PasswordGenerationPopupControllerImpl::PossiblyAcceptPassword() { | 123 bool PasswordGenerationPopupControllerImpl::PossiblyAcceptPassword() { |
| 124 if (!display_password_) |
| 125 return false; |
| 126 |
117 if (password_selected_) | 127 if (password_selected_) |
118 PasswordAccepted(); | 128 PasswordAccepted(); |
119 | 129 |
120 return password_selected_; | 130 return password_selected_; |
121 } | 131 } |
122 | 132 |
123 void PasswordGenerationPopupControllerImpl::PasswordSelected(bool selected) { | 133 void PasswordGenerationPopupControllerImpl::PasswordSelected(bool selected) { |
| 134 if (!display_password_) |
| 135 return; |
| 136 |
124 password_selected_ = selected; | 137 password_selected_ = selected; |
125 view_->UpdateBoundsAndRedrawPopup(); | 138 view_->UpdateBoundsAndRedrawPopup(); |
126 } | 139 } |
127 | 140 |
128 void PasswordGenerationPopupControllerImpl::PasswordAccepted() { | 141 void PasswordGenerationPopupControllerImpl::PasswordAccepted() { |
| 142 if (!display_password_) |
| 143 return; |
| 144 |
129 web_contents()->GetRenderViewHost()->Send( | 145 web_contents()->GetRenderViewHost()->Send( |
130 new AutofillMsg_GeneratedPasswordAccepted( | 146 new AutofillMsg_GeneratedPasswordAccepted( |
131 web_contents()->GetRenderViewHost()->GetRoutingID(), | 147 web_contents()->GetRenderViewHost()->GetRoutingID(), |
132 current_password_)); | 148 current_password_)); |
133 password_manager_->SetFormHasGeneratedPassword(form_); | 149 password_manager_->SetFormHasGeneratedPassword(*form_); |
134 Hide(); | 150 Hide(); |
135 } | 151 } |
136 | 152 |
137 int PasswordGenerationPopupControllerImpl::GetDesiredWidth() { | 153 int PasswordGenerationPopupControllerImpl::GetDesiredWidth() { |
138 // Minimum width we want to display the password. | |
139 int minimum_length_for_text = 2 * kHorizontalPadding + | |
140 font_.GetExpectedTextWidth(kMinimumWidth) + | |
141 2 * kPopupBorderThickness; | |
142 | |
143 // If the width of the field is longer than the minimum, use that instead. | 154 // If the width of the field is longer than the minimum, use that instead. |
144 return std::max(minimum_length_for_text, | 155 return std::max(kMinimumWidth, |
145 controller_common_.RoundedElementBounds().width()); | 156 controller_common_.RoundedElementBounds().width()); |
146 } | 157 } |
147 | 158 |
148 int PasswordGenerationPopupControllerImpl::GetDesiredHeight(int width) { | 159 int PasswordGenerationPopupControllerImpl::GetDesiredHeight(int width) { |
149 // Note that this wrapping isn't exactly what the popup will do. It shouldn't | 160 // Note that this wrapping isn't exactly what the popup will do. It shouldn't |
150 // line break in the middle of the link, but as long as the link isn't longer | 161 // line break in the middle of the link, but as long as the link isn't longer |
151 // than given width this shouldn't affect the height calculated here. The | 162 // than given width this shouldn't affect the height calculated here. The |
152 // default width should be wide enough to prevent this from being an issue. | 163 // default width should be wide enough to prevent this from being an issue. |
153 int total_length = font_.GetStringWidth(HelpText() + LearnMoreLink()); | 164 int total_length = |
| 165 gfx::GetStringWidth(HelpText() + SavedPasswordsLink(), font_list_); |
154 int usable_width = width - 2 * kHorizontalPadding; | 166 int usable_width = width - 2 * kHorizontalPadding; |
155 int text_height = | 167 int text_height = |
156 static_cast<int>(ceil(static_cast<double>(total_length)/usable_width)) * | 168 static_cast<int>(ceil(static_cast<double>(total_length)/usable_width)) * |
157 font_.GetHeight(); | 169 font_list_.GetFontSize(); |
158 int help_section_height = text_height + 2 * kHelpVerticalPadding; | 170 int help_section_height = text_height + 2 * kHelpVerticalPadding; |
159 | 171 |
160 int password_section_height = | 172 int password_section_height = 0; |
161 font_.GetHeight() + 2 * kPasswordVerticalPadding; | 173 if (display_password_) { |
| 174 password_section_height = |
| 175 font_list_.GetFontSize() + 2 * kPasswordVerticalPadding; |
| 176 } |
162 | 177 |
163 return (2 * kPopupBorderThickness + | 178 return (2 * kPopupBorderThickness + |
164 help_section_height + | 179 help_section_height + |
165 password_section_height); | 180 password_section_height); |
166 } | 181 } |
167 | 182 |
168 void PasswordGenerationPopupControllerImpl::CalculateBounds() { | 183 void PasswordGenerationPopupControllerImpl::CalculateBounds() { |
169 int popup_width = GetDesiredWidth(); | 184 int popup_width = GetDesiredWidth(); |
170 int popup_height = GetDesiredHeight(popup_width); | 185 int popup_height = GetDesiredHeight(popup_width); |
171 | 186 |
172 popup_bounds_ = controller_common_.GetPopupBounds(popup_height, popup_width); | 187 popup_bounds_ = controller_common_.GetPopupBounds(popup_height, popup_width); |
| 188 int sub_view_width = popup_bounds_.width() - 2 * kPopupBorderThickness; |
173 | 189 |
174 // Calculate the bounds for the rest of the elements given the bounds of | 190 // Calculate the bounds for the rest of the elements given the bounds of |
175 // the popup. | 191 // the popup. |
176 password_bounds_ = gfx::Rect( | 192 if (display_password_) { |
177 kPopupBorderThickness, | 193 password_bounds_ = gfx::Rect( |
178 kPopupBorderThickness, | 194 kPopupBorderThickness, |
179 popup_bounds_.width() - 2 * kPopupBorderThickness, | 195 kPopupBorderThickness, |
180 font_.GetHeight() + 2 * kPasswordVerticalPadding); | 196 sub_view_width, |
| 197 font_list_.GetFontSize() + 2 * kPasswordVerticalPadding); |
181 | 198 |
182 divider_bounds_ = gfx::Rect(kPopupBorderThickness, | 199 divider_bounds_ = gfx::Rect(kPopupBorderThickness, |
183 password_bounds_.bottom(), | 200 password_bounds_.bottom(), |
184 password_bounds_.width(), | 201 sub_view_width, |
185 kDividerHeight); | 202 kDividerHeight); |
| 203 } else { |
| 204 password_bounds_ = gfx::Rect(); |
| 205 divider_bounds_ = gfx::Rect(); |
| 206 } |
186 | 207 |
| 208 int help_y = std::max(kPopupBorderThickness, divider_bounds_.bottom()); |
187 int help_height = | 209 int help_height = |
188 popup_bounds_.height() - divider_bounds_.bottom() - kPopupBorderThickness; | 210 popup_bounds_.height() - help_y - kPopupBorderThickness; |
189 help_bounds_ = gfx::Rect( | 211 help_bounds_ = gfx::Rect( |
190 kPopupBorderThickness, | 212 kPopupBorderThickness, |
191 divider_bounds_.bottom(), | 213 help_y, |
192 password_bounds_.width(), | 214 sub_view_width, |
193 help_height); | 215 help_height); |
194 } | 216 } |
195 | 217 |
196 void PasswordGenerationPopupControllerImpl::Show() { | 218 void PasswordGenerationPopupControllerImpl::Show(bool display_password) { |
| 219 display_password_ = display_password; |
| 220 if (display_password_) |
| 221 current_password_ = base::ASCIIToUTF16(generator_->Generate()); |
| 222 |
197 CalculateBounds(); | 223 CalculateBounds(); |
198 | 224 |
199 if (!view_) { | 225 if (!view_) { |
200 view_ = PasswordGenerationPopupView::Create(this); | 226 view_ = PasswordGenerationPopupView::Create(this); |
201 view_->Show(); | 227 view_->Show(); |
| 228 } else { |
| 229 view_->UpdateBoundsAndRedrawPopup(); |
202 } | 230 } |
203 | 231 |
204 controller_common_.RegisterKeyPressCallback(); | 232 controller_common_.RegisterKeyPressCallback(); |
205 | 233 |
206 if (observer_) | 234 if (observer_) |
207 observer_->OnPopupShown(); | 235 observer_->OnPopupShown(display_password_); |
| 236 } |
| 237 |
| 238 void PasswordGenerationPopupControllerImpl::HideAndDestroy() { |
| 239 Hide(); |
208 } | 240 } |
209 | 241 |
210 void PasswordGenerationPopupControllerImpl::Hide() { | 242 void PasswordGenerationPopupControllerImpl::Hide() { |
211 controller_common_.RemoveKeyPressCallback(); | 243 controller_common_.RemoveKeyPressCallback(); |
212 | 244 |
213 if (view_) | 245 if (view_) |
214 view_->Hide(); | 246 view_->Hide(); |
215 | 247 |
216 if (observer_) | 248 if (observer_) |
217 observer_->OnPopupHidden(); | 249 observer_->OnPopupHidden(); |
218 | 250 |
219 delete this; | 251 delete this; |
220 } | 252 } |
221 | 253 |
222 void PasswordGenerationPopupControllerImpl::ViewDestroyed() { | 254 void PasswordGenerationPopupControllerImpl::ViewDestroyed() { |
223 view_ = NULL; | 255 view_ = NULL; |
224 | 256 |
225 Hide(); | 257 Hide(); |
226 } | 258 } |
227 | 259 |
228 void PasswordGenerationPopupControllerImpl::OnHelpLinkClicked() { | 260 void PasswordGenerationPopupControllerImpl::OnSavedPasswordsLinkClicked() { |
| 261 // TODO(gcasto): Change this to navigate to account central once passwords |
| 262 // are visible there. |
229 Browser* browser = | 263 Browser* browser = |
230 chrome::FindBrowserWithWebContents(controller_common_.web_contents()); | 264 chrome::FindBrowserWithWebContents(controller_common_.web_contents()); |
231 content::OpenURLParams params( | 265 content::OpenURLParams params( |
232 GURL(chrome::kAutoPasswordGenerationLearnMoreURL), content::Referrer(), | 266 GURL(chrome::kAutoPasswordGenerationLearnMoreURL), content::Referrer(), |
233 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false); | 267 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false); |
234 browser->OpenURL(params); | 268 browser->OpenURL(params); |
235 } | 269 } |
236 | 270 |
237 void PasswordGenerationPopupControllerImpl::SetSelectionAtPoint( | 271 void PasswordGenerationPopupControllerImpl::SetSelectionAtPoint( |
238 const gfx::Point& point) { | 272 const gfx::Point& point) { |
(...skipping 18 matching lines...) Expand all Loading... |
257 | 291 |
258 bool PasswordGenerationPopupControllerImpl::ShouldHideOnOutsideClick() const { | 292 bool PasswordGenerationPopupControllerImpl::ShouldHideOnOutsideClick() const { |
259 // Will be hidden when focus changes anyway. | 293 // Will be hidden when focus changes anyway. |
260 return false; | 294 return false; |
261 } | 295 } |
262 | 296 |
263 gfx::NativeView PasswordGenerationPopupControllerImpl::container_view() { | 297 gfx::NativeView PasswordGenerationPopupControllerImpl::container_view() { |
264 return controller_common_.container_view(); | 298 return controller_common_.container_view(); |
265 } | 299 } |
266 | 300 |
| 301 const gfx::FontList& PasswordGenerationPopupControllerImpl::font_list() const { |
| 302 return font_list_; |
| 303 } |
| 304 |
267 const gfx::Rect& PasswordGenerationPopupControllerImpl::popup_bounds() const { | 305 const gfx::Rect& PasswordGenerationPopupControllerImpl::popup_bounds() const { |
268 return popup_bounds_; | 306 return popup_bounds_; |
269 } | 307 } |
270 | 308 |
271 const gfx::Rect& PasswordGenerationPopupControllerImpl::password_bounds() | 309 const gfx::Rect& PasswordGenerationPopupControllerImpl::password_bounds() |
272 const { | 310 const { |
273 return password_bounds_; | 311 return password_bounds_; |
274 } | 312 } |
275 | 313 |
276 const gfx::Rect& PasswordGenerationPopupControllerImpl::divider_bounds() | 314 const gfx::Rect& PasswordGenerationPopupControllerImpl::divider_bounds() |
277 const { | 315 const { |
278 return divider_bounds_; | 316 return divider_bounds_; |
279 } | 317 } |
280 | 318 |
281 const gfx::Rect& PasswordGenerationPopupControllerImpl::help_bounds() const { | 319 const gfx::Rect& PasswordGenerationPopupControllerImpl::help_bounds() const { |
282 return help_bounds_; | 320 return help_bounds_; |
283 } | 321 } |
284 | 322 |
| 323 bool PasswordGenerationPopupControllerImpl::display_password() const { |
| 324 return display_password_; |
| 325 } |
| 326 |
285 bool PasswordGenerationPopupControllerImpl::password_selected() const { | 327 bool PasswordGenerationPopupControllerImpl::password_selected() const { |
286 return password_selected_; | 328 return password_selected_; |
287 } | 329 } |
288 | 330 |
289 base::string16 PasswordGenerationPopupControllerImpl::password() const { | 331 base::string16 PasswordGenerationPopupControllerImpl::password() const { |
290 return current_password_; | 332 return current_password_; |
291 } | 333 } |
292 | 334 |
| 335 base::string16 PasswordGenerationPopupControllerImpl::SuggestedText() { |
| 336 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_SUGGESTION); |
| 337 } |
| 338 |
293 base::string16 PasswordGenerationPopupControllerImpl::HelpText() { | 339 base::string16 PasswordGenerationPopupControllerImpl::HelpText() { |
294 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_PROMPT); | 340 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_PROMPT); |
295 } | 341 } |
296 | 342 |
297 base::string16 PasswordGenerationPopupControllerImpl::LearnMoreLink() { | 343 base::string16 PasswordGenerationPopupControllerImpl::SavedPasswordsLink() { |
298 return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_LEARN_MORE_LINK); | 344 return l10n_util::GetStringUTF16( |
| 345 IDS_PASSWORD_GENERATION_SAVED_PASSWORDS_LINK); |
299 } | 346 } |
300 | 347 |
301 } // namespace autofill | 348 } // namespace autofill |
OLD | NEW |