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" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 // document load finishes, so we need to clear previous states here before we | 114 // document load finishes, so we need to clear previous states here before we |
115 // hear back from the browser. We only clear this state on main frame load | 115 // hear back from the browser. We only clear this state on main frame load |
116 // as we don't want subframe loads to clear state that we have received from | 116 // as we don't want subframe loads to clear state that we have received from |
117 // the main frame. Note that we assume there is only one account creation | 117 // the main frame. Note that we assume there is only one account creation |
118 // form, but there could be multiple password forms in each frame. | 118 // form, but there could be multiple password forms in each frame. |
119 if (!frame->parent()) { | 119 if (!frame->parent()) { |
120 not_blacklisted_password_form_origins_.clear(); | 120 not_blacklisted_password_form_origins_.clear(); |
121 generation_enabled_forms_.clear(); | 121 generation_enabled_forms_.clear(); |
122 generation_element_.reset(); | 122 generation_element_.reset(); |
123 possible_account_creation_form_.reset(new PasswordForm()); | 123 possible_account_creation_form_.reset(new PasswordForm()); |
| 124 |
| 125 // Log statistics after navigation so that we only log once per page. |
| 126 if (password_elements_.empty()) { |
| 127 password_generation::LogPasswordGenerationEvent( |
| 128 password_generation::NO_SIGN_UP_DETECTED); |
| 129 } else { |
| 130 password_generation::LogPasswordGenerationEvent( |
| 131 password_generation::SIGN_UP_DETECTED); |
| 132 } |
124 password_elements_.clear(); | 133 password_elements_.clear(); |
125 password_is_generated_ = false; | 134 password_is_generated_ = false; |
126 if (password_edited_) { | 135 if (password_edited_) { |
127 password_generation::LogPasswordGenerationEvent( | 136 password_generation::LogPasswordGenerationEvent( |
128 password_generation::PASSWORD_EDITED); | 137 password_generation::PASSWORD_EDITED); |
129 } | 138 } |
130 password_edited_ = false; | 139 password_edited_ = false; |
131 | 140 |
132 if (generation_popup_shown_) { | 141 if (generation_popup_shown_) { |
133 password_generation::LogPasswordGenerationEvent( | 142 password_generation::LogPasswordGenerationEvent( |
134 password_generation::GENERATION_POPUP_SHOWN); | 143 password_generation::GENERATION_POPUP_SHOWN); |
135 } | 144 } |
136 generation_popup_shown_ = false; | 145 generation_popup_shown_ = false; |
137 | 146 |
138 if (editing_popup_shown_) { | 147 if (editing_popup_shown_) { |
139 password_generation::LogPasswordGenerationEvent( | 148 password_generation::LogPasswordGenerationEvent( |
140 password_generation::EDITING_POPUP_SHOWN); | 149 password_generation::EDITING_POPUP_SHOWN); |
141 } | 150 } |
142 editing_popup_shown_ = false; | 151 editing_popup_shown_ = false; |
143 } | 152 } |
144 } | 153 } |
145 | 154 |
| 155 void PasswordGenerationAgent::OnDynamicFormsSeen(blink::WebLocalFrame* frame) { |
| 156 FindPossibleGenerationForm(frame); |
| 157 } |
| 158 |
146 void PasswordGenerationAgent::DidFinishLoad(blink::WebLocalFrame* frame) { | 159 void PasswordGenerationAgent::DidFinishLoad(blink::WebLocalFrame* frame) { |
| 160 FindPossibleGenerationForm(frame); |
| 161 } |
| 162 |
| 163 void PasswordGenerationAgent::FindPossibleGenerationForm( |
| 164 blink::WebLocalFrame* frame) { |
147 if (!enabled_) | 165 if (!enabled_) |
148 return; | 166 return; |
149 | 167 |
150 // We don't want to generate passwords if the browser won't store or sync | 168 // We don't want to generate passwords if the browser won't store or sync |
151 // them. | 169 // them. |
152 if (!ShouldAnalyzeDocument(frame->document())) | 170 if (!ShouldAnalyzeDocument(frame->document())) |
153 return; | 171 return; |
154 | 172 |
| 173 // If we have already found a signup form for this page, no need to continue. |
| 174 if (!password_elements_.empty()) |
| 175 return; |
| 176 |
155 blink::WebVector<blink::WebFormElement> forms; | 177 blink::WebVector<blink::WebFormElement> forms; |
156 frame->document().forms(forms); | 178 frame->document().forms(forms); |
157 for (size_t i = 0; i < forms.size(); ++i) { | 179 for (size_t i = 0; i < forms.size(); ++i) { |
158 if (forms[i].isNull()) | 180 if (forms[i].isNull()) |
159 continue; | 181 continue; |
160 | 182 |
161 // If we can't get a valid PasswordForm, we skip this form because the | 183 // If we can't get a valid PasswordForm, we skip this form because the |
162 // the password won't get saved even if we generate it. | 184 // the password won't get saved even if we generate it. |
163 scoped_ptr<PasswordForm> password_form( | 185 scoped_ptr<PasswordForm> password_form( |
164 CreatePasswordForm(forms[i])); | 186 CreatePasswordForm(forms[i])); |
165 if (!password_form.get()) { | 187 if (!password_form.get()) { |
166 DVLOG(2) << "Skipping form as it would not be saved"; | 188 DVLOG(2) << "Skipping form as it would not be saved"; |
167 continue; | 189 continue; |
168 } | 190 } |
169 | 191 |
170 // Do not generate password for GAIA since it is used to retrieve the | 192 // Do not generate password for GAIA since it is used to retrieve the |
171 // generated paswords. | 193 // generated paswords. |
172 GURL realm(password_form->signon_realm); | 194 GURL realm(password_form->signon_realm); |
173 if (realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) | 195 if (realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) |
174 continue; | 196 continue; |
175 | 197 |
176 std::vector<blink::WebInputElement> passwords; | 198 std::vector<blink::WebInputElement> passwords; |
177 if (GetAccountCreationPasswordFields(forms[i], &passwords)) { | 199 if (GetAccountCreationPasswordFields(forms[i], &passwords)) { |
178 DVLOG(2) << "Account creation form detected"; | 200 DVLOG(2) << "Account creation form detected"; |
179 password_generation::LogPasswordGenerationEvent( | |
180 password_generation::SIGN_UP_DETECTED); | |
181 password_elements_ = passwords; | 201 password_elements_ = passwords; |
182 possible_account_creation_form_.swap(password_form); | 202 possible_account_creation_form_.swap(password_form); |
183 DetermineGenerationElement(); | 203 DetermineGenerationElement(); |
184 // We assume that there is only one account creation field per URL. | 204 // We assume that there is only one account creation field per URL. |
185 return; | 205 return; |
186 } | 206 } |
187 } | 207 } |
188 password_generation::LogPasswordGenerationEvent( | |
189 password_generation::NO_SIGN_UP_DETECTED); | |
190 } | 208 } |
191 | 209 |
192 bool PasswordGenerationAgent::ShouldAnalyzeDocument( | 210 bool PasswordGenerationAgent::ShouldAnalyzeDocument( |
193 const blink::WebDocument& document) const { | 211 const blink::WebDocument& document) const { |
194 // Make sure that this security origin is allowed to use password manager. | 212 // Make sure that this security origin is allowed to use password manager. |
195 // Generating a password that can't be saved is a bad idea. | 213 // Generating a password that can't be saved is a bad idea. |
196 blink::WebSecurityOrigin origin = document.securityOrigin(); | 214 blink::WebSecurityOrigin origin = document.securityOrigin(); |
197 if (!origin.canAccessPasswordManager()) { | 215 if (!origin.canAccessPasswordManager()) { |
198 DVLOG(1) << "No PasswordManager access"; | 216 DVLOG(1) << "No PasswordManager access"; |
199 return false; | 217 return false; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 *possible_account_creation_form_)); | 396 *possible_account_creation_form_)); |
379 | 397 |
380 editing_popup_shown_ = true; | 398 editing_popup_shown_ = true; |
381 } | 399 } |
382 | 400 |
383 void PasswordGenerationAgent::HidePopup() { | 401 void PasswordGenerationAgent::HidePopup() { |
384 Send(new AutofillHostMsg_HidePasswordGenerationPopup(routing_id())); | 402 Send(new AutofillHostMsg_HidePasswordGenerationPopup(routing_id())); |
385 } | 403 } |
386 | 404 |
387 } // namespace autofill | 405 } // namespace autofill |
OLD | NEW |