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