OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "components/autofill/content/renderer/password_generation_agent.h" | 5 #include "components/autofill/content/renderer/password_generation_agent.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "components/autofill/content/common/autofill_messages.h" | 10 #include "components/autofill/content/common/autofill_messages.h" |
11 #include "components/autofill/content/renderer/form_autofill_util.h" | 11 #include "components/autofill/content/renderer/form_autofill_util.h" |
12 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 12 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
13 #include "components/autofill/core/common/autofill_switches.h" | 13 #include "components/autofill/core/common/autofill_switches.h" |
14 #include "components/autofill/core/common/form_data.h" | 14 #include "components/autofill/core/common/form_data.h" |
15 #include "components/autofill/core/common/password_form.h" | 15 #include "components/autofill/core/common/password_form.h" |
16 #include "components/autofill/core/common/password_generation_util.h" | 16 #include "components/autofill/core/common/password_generation_util.h" |
17 #include "content/public/renderer/render_frame.h" | |
17 #include "content/public/renderer/render_view.h" | 18 #include "content/public/renderer/render_view.h" |
18 #include "google_apis/gaia/gaia_urls.h" | 19 #include "google_apis/gaia/gaia_urls.h" |
19 #include "third_party/WebKit/public/platform/WebVector.h" | 20 #include "third_party/WebKit/public/platform/WebVector.h" |
20 #include "third_party/WebKit/public/web/WebDocument.h" | 21 #include "third_party/WebKit/public/web/WebDocument.h" |
21 #include "third_party/WebKit/public/web/WebFormElement.h" | 22 #include "third_party/WebKit/public/web/WebFormElement.h" |
22 #include "third_party/WebKit/public/web/WebInputElement.h" | 23 #include "third_party/WebKit/public/web/WebInputElement.h" |
23 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 24 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
24 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 25 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
25 #include "third_party/WebKit/public/web/WebView.h" | 26 #include "third_party/WebKit/public/web/WebView.h" |
26 #include "ui/gfx/rect.h" | 27 #include "ui/gfx/rect.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 std::vector<blink::WebInputElement>* elements) { | 98 std::vector<blink::WebInputElement>* elements) { |
98 for (std::vector<blink::WebInputElement>::iterator it = elements->begin(); | 99 for (std::vector<blink::WebInputElement>::iterator it = elements->begin(); |
99 it != elements->end(); ++it) { | 100 it != elements->end(); ++it) { |
100 it->setValue(value, true /* sendEvents */); | 101 it->setValue(value, true /* sendEvents */); |
101 } | 102 } |
102 } | 103 } |
103 | 104 |
104 } // namespace | 105 } // namespace |
105 | 106 |
106 PasswordGenerationAgent::PasswordGenerationAgent( | 107 PasswordGenerationAgent::PasswordGenerationAgent( |
107 content::RenderView* render_view) | 108 content::RenderFrame* render_frame) |
108 : content::RenderViewObserver(render_view), | 109 : content::RenderFrameObserver(render_frame), |
109 render_view_(render_view), | |
110 password_is_generated_(false), | 110 password_is_generated_(false), |
111 password_edited_(false), | 111 password_edited_(false), |
112 generation_popup_shown_(false), | 112 generation_popup_shown_(false), |
113 editing_popup_shown_(false), | 113 editing_popup_shown_(false), |
114 enabled_(password_generation::IsPasswordGenerationEnabled()) { | 114 enabled_(password_generation::IsPasswordGenerationEnabled()) { |
115 DVLOG(2) << "Password Generation is " << (enabled_ ? "Enabled" : "Disabled"); | 115 DVLOG(2) << "Password Generation is " << (enabled_ ? "Enabled" : "Disabled"); |
116 } | 116 } |
117 PasswordGenerationAgent::~PasswordGenerationAgent() {} | 117 PasswordGenerationAgent::~PasswordGenerationAgent() {} |
118 | 118 |
119 void PasswordGenerationAgent::DidFinishDocumentLoad( | 119 void PasswordGenerationAgent::DidFinishDocumentLoad() { |
120 blink::WebLocalFrame* frame) { | |
121 // In every navigation, the IPC message sent by the password autofill manager | 120 // In every navigation, the IPC message sent by the password autofill manager |
122 // to query whether the current form is blacklisted or not happens when the | 121 // to query whether the current form is blacklisted or not happens when the |
123 // document load finishes, so we need to clear previous states here before we | 122 // document load finishes, so we need to clear previous states here before we |
124 // hear back from the browser. We only clear this state on main frame load | 123 // hear back from the browser. Note that we assume there is only one account |
125 // as we don't want subframe loads to clear state that we have received from | 124 // creation form, but there could be multiple password forms in each frame. |
126 // the main frame. Note that we assume there is only one account creation | 125 not_blacklisted_password_form_origins_.clear(); |
vabr (Chromium)
2014/11/10 14:34:40
Again, the old code only acted upon main frames, w
Garrett Casto
2014/11/12 08:09:55
Confirmed.
Evan Stade
2014/11/14 23:25:50
Reverted. The reason I changed this was that the c
| |
127 // form, but there could be multiple password forms in each frame. | 126 generation_enabled_forms_.clear(); |
128 if (!frame->parent()) { | 127 generation_element_.reset(); |
129 not_blacklisted_password_form_origins_.clear(); | 128 possible_account_creation_form_.reset(new PasswordForm()); |
130 generation_enabled_forms_.clear(); | |
131 generation_element_.reset(); | |
132 possible_account_creation_form_.reset(new PasswordForm()); | |
133 | 129 |
134 // Log statistics after navigation so that we only log once per page. | 130 // Log statistics after navigation so that we only log once per page. |
135 if (password_elements_.empty()) { | 131 if (password_elements_.empty()) { |
136 password_generation::LogPasswordGenerationEvent( | 132 password_generation::LogPasswordGenerationEvent( |
137 password_generation::NO_SIGN_UP_DETECTED); | 133 password_generation::NO_SIGN_UP_DETECTED); |
138 } else { | 134 } else { |
139 password_generation::LogPasswordGenerationEvent( | 135 password_generation::LogPasswordGenerationEvent( |
140 password_generation::SIGN_UP_DETECTED); | 136 password_generation::SIGN_UP_DETECTED); |
141 } | 137 } |
142 password_elements_.clear(); | 138 password_elements_.clear(); |
143 password_is_generated_ = false; | 139 password_is_generated_ = false; |
144 if (password_edited_) { | 140 if (password_edited_) { |
145 password_generation::LogPasswordGenerationEvent( | 141 password_generation::LogPasswordGenerationEvent( |
146 password_generation::PASSWORD_EDITED); | 142 password_generation::PASSWORD_EDITED); |
147 } | 143 } |
148 password_edited_ = false; | 144 password_edited_ = false; |
149 | 145 |
150 if (generation_popup_shown_) { | 146 if (generation_popup_shown_) { |
151 password_generation::LogPasswordGenerationEvent( | 147 password_generation::LogPasswordGenerationEvent( |
152 password_generation::GENERATION_POPUP_SHOWN); | 148 password_generation::GENERATION_POPUP_SHOWN); |
153 } | 149 } |
154 generation_popup_shown_ = false; | 150 generation_popup_shown_ = false; |
155 | 151 |
156 if (editing_popup_shown_) { | 152 if (editing_popup_shown_) { |
157 password_generation::LogPasswordGenerationEvent( | 153 password_generation::LogPasswordGenerationEvent( |
158 password_generation::EDITING_POPUP_SHOWN); | 154 password_generation::EDITING_POPUP_SHOWN); |
159 } | |
160 editing_popup_shown_ = false; | |
161 } | 155 } |
156 editing_popup_shown_ = false; | |
162 } | 157 } |
163 | 158 |
164 void PasswordGenerationAgent::OnDynamicFormsSeen(blink::WebLocalFrame* frame) { | 159 void PasswordGenerationAgent::OnDynamicFormsSeen() { |
165 FindPossibleGenerationForm(frame); | 160 FindPossibleGenerationForm(); |
166 } | 161 } |
167 | 162 |
168 void PasswordGenerationAgent::DidFinishLoad(blink::WebLocalFrame* frame) { | 163 void PasswordGenerationAgent::DidFinishLoad() { |
169 FindPossibleGenerationForm(frame); | 164 FindPossibleGenerationForm(); |
170 } | 165 } |
171 | 166 |
172 void PasswordGenerationAgent::FindPossibleGenerationForm( | 167 void PasswordGenerationAgent::FindPossibleGenerationForm() { |
173 blink::WebLocalFrame* frame) { | |
174 if (!enabled_) | 168 if (!enabled_) |
175 return; | 169 return; |
176 | 170 |
177 // We don't want to generate passwords if the browser won't store or sync | 171 // We don't want to generate passwords if the browser won't store or sync |
178 // them. | 172 // them. |
179 if (!ShouldAnalyzeDocument(frame->document())) | 173 if (!ShouldAnalyzeDocument()) |
180 return; | 174 return; |
181 | 175 |
182 // If we have already found a signup form for this page, no need to continue. | 176 // If we have already found a signup form for this page, no need to continue. |
183 if (!password_elements_.empty()) | 177 if (!password_elements_.empty()) |
184 return; | 178 return; |
185 | 179 |
186 blink::WebVector<blink::WebFormElement> forms; | 180 blink::WebVector<blink::WebFormElement> forms; |
187 frame->document().forms(forms); | 181 render_frame()->GetWebFrame()->document().forms(forms); |
188 for (size_t i = 0; i < forms.size(); ++i) { | 182 for (size_t i = 0; i < forms.size(); ++i) { |
189 if (forms[i].isNull()) | 183 if (forms[i].isNull()) |
190 continue; | 184 continue; |
191 | 185 |
192 // If we can't get a valid PasswordForm, we skip this form because the | 186 // If we can't get a valid PasswordForm, we skip this form because the |
193 // the password won't get saved even if we generate it. | 187 // the password won't get saved even if we generate it. |
194 scoped_ptr<PasswordForm> password_form( | 188 scoped_ptr<PasswordForm> password_form( |
195 CreatePasswordForm(forms[i])); | 189 CreatePasswordForm(forms[i])); |
196 if (!password_form.get()) { | 190 if (!password_form.get()) { |
197 DVLOG(2) << "Skipping form as it would not be saved"; | 191 DVLOG(2) << "Skipping form as it would not be saved"; |
(...skipping 11 matching lines...) Expand all Loading... | |
209 DVLOG(2) << "Account creation form detected"; | 203 DVLOG(2) << "Account creation form detected"; |
210 password_elements_ = passwords; | 204 password_elements_ = passwords; |
211 possible_account_creation_form_.swap(password_form); | 205 possible_account_creation_form_.swap(password_form); |
212 DetermineGenerationElement(); | 206 DetermineGenerationElement(); |
213 // We assume that there is only one account creation field per URL. | 207 // We assume that there is only one account creation field per URL. |
214 return; | 208 return; |
215 } | 209 } |
216 } | 210 } |
217 } | 211 } |
218 | 212 |
219 bool PasswordGenerationAgent::ShouldAnalyzeDocument( | 213 bool PasswordGenerationAgent::ShouldAnalyzeDocument() const { |
220 const blink::WebDocument& document) const { | |
221 // Make sure that this security origin is allowed to use password manager. | 214 // Make sure that this security origin is allowed to use password manager. |
222 // Generating a password that can't be saved is a bad idea. | 215 // Generating a password that can't be saved is a bad idea. |
223 blink::WebSecurityOrigin origin = document.securityOrigin(); | 216 blink::WebSecurityOrigin origin = |
217 render_frame()->GetWebFrame()->document().securityOrigin(); | |
224 if (!origin.canAccessPasswordManager()) { | 218 if (!origin.canAccessPasswordManager()) { |
225 DVLOG(1) << "No PasswordManager access"; | 219 DVLOG(1) << "No PasswordManager access"; |
226 return false; | 220 return false; |
227 } | 221 } |
228 | 222 |
229 return true; | 223 return true; |
230 } | 224 } |
231 | 225 |
232 bool PasswordGenerationAgent::OnMessageReceived(const IPC::Message& message) { | 226 bool PasswordGenerationAgent::OnMessageReceived(const IPC::Message& message) { |
233 bool handled = true; | 227 bool handled = true; |
(...skipping 19 matching lines...) Expand all Loading... | |
253 password_is_generated_ = true; | 247 password_is_generated_ = true; |
254 password_generation::LogPasswordGenerationEvent( | 248 password_generation::LogPasswordGenerationEvent( |
255 password_generation::PASSWORD_ACCEPTED); | 249 password_generation::PASSWORD_ACCEPTED); |
256 for (std::vector<blink::WebInputElement>::iterator it = | 250 for (std::vector<blink::WebInputElement>::iterator it = |
257 password_elements_.begin(); | 251 password_elements_.begin(); |
258 it != password_elements_.end(); ++it) { | 252 it != password_elements_.end(); ++it) { |
259 it->setValue(password, true /* sendEvents */); | 253 it->setValue(password, true /* sendEvents */); |
260 it->setAutofilled(true); | 254 it->setAutofilled(true); |
261 // Advance focus to the next input field. We assume password fields in | 255 // Advance focus to the next input field. We assume password fields in |
262 // an account creation form are always adjacent. | 256 // an account creation form are always adjacent. |
263 render_view_->GetWebView()->advanceFocus(false); | 257 render_frame()->GetRenderView()->GetWebView()->advanceFocus(false); |
264 } | 258 } |
265 } | 259 } |
266 | 260 |
267 void PasswordGenerationAgent::OnAccountCreationFormsDetected( | 261 void PasswordGenerationAgent::OnAccountCreationFormsDetected( |
268 const std::vector<autofill::FormData>& forms) { | 262 const std::vector<autofill::FormData>& forms) { |
269 generation_enabled_forms_.insert( | 263 generation_enabled_forms_.insert( |
270 generation_enabled_forms_.end(), forms.begin(), forms.end()); | 264 generation_enabled_forms_.end(), forms.begin(), forms.end()); |
271 DetermineGenerationElement(); | 265 DetermineGenerationElement(); |
272 } | 266 } |
273 | 267 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 // Password isn't generated and there are fewer than kMaximumOfferSize | 365 // Password isn't generated and there are fewer than kMaximumOfferSize |
372 // characters typed, so keep offering the password. Note this function | 366 // characters typed, so keep offering the password. Note this function |
373 // will just keep the previous popup if one is already showing. | 367 // will just keep the previous popup if one is already showing. |
374 ShowGenerationPopup(); | 368 ShowGenerationPopup(); |
375 } | 369 } |
376 | 370 |
377 return true; | 371 return true; |
378 } | 372 } |
379 | 373 |
380 void PasswordGenerationAgent::ShowGenerationPopup() { | 374 void PasswordGenerationAgent::ShowGenerationPopup() { |
381 gfx::RectF bounding_box_scaled = | 375 gfx::RectF bounding_box_scaled = GetScaledBoundingBox( |
382 GetScaledBoundingBox(render_view_->GetWebView()->pageScaleFactor(), | 376 render_frame()->GetRenderView()->GetWebView()->pageScaleFactor(), |
383 &generation_element_); | 377 &generation_element_); |
384 | 378 |
385 Send(new AutofillHostMsg_ShowPasswordGenerationPopup( | 379 Send(new AutofillHostMsg_ShowPasswordGenerationPopup( |
386 routing_id(), | 380 routing_id(), |
387 bounding_box_scaled, | 381 bounding_box_scaled, |
388 generation_element_.maxLength(), | 382 generation_element_.maxLength(), |
389 *possible_account_creation_form_)); | 383 *possible_account_creation_form_)); |
390 | 384 |
391 generation_popup_shown_ = true; | 385 generation_popup_shown_ = true; |
392 } | 386 } |
393 | 387 |
394 void PasswordGenerationAgent::ShowEditingPopup() { | 388 void PasswordGenerationAgent::ShowEditingPopup() { |
395 gfx::RectF bounding_box_scaled = | 389 gfx::RectF bounding_box_scaled = GetScaledBoundingBox( |
396 GetScaledBoundingBox(render_view_->GetWebView()->pageScaleFactor(), | 390 render_frame()->GetRenderView()->GetWebView()->pageScaleFactor(), |
397 &generation_element_); | 391 &generation_element_); |
398 | 392 |
399 Send(new AutofillHostMsg_ShowPasswordEditingPopup( | 393 Send(new AutofillHostMsg_ShowPasswordEditingPopup( |
400 routing_id(), | 394 routing_id(), |
401 bounding_box_scaled, | 395 bounding_box_scaled, |
402 *possible_account_creation_form_)); | 396 *possible_account_creation_form_)); |
403 | 397 |
404 editing_popup_shown_ = true; | 398 editing_popup_shown_ = true; |
405 } | 399 } |
406 | 400 |
407 void PasswordGenerationAgent::HidePopup() { | 401 void PasswordGenerationAgent::HidePopup() { |
408 Send(new AutofillHostMsg_HidePasswordGenerationPopup(routing_id())); | 402 Send(new AutofillHostMsg_HidePasswordGenerationPopup(routing_id())); |
409 } | 403 } |
410 | 404 |
411 } // namespace autofill | 405 } // namespace autofill |
OLD | NEW |