Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: components/autofill/content/renderer/autofill_agent.cc

Issue 23033016: Remove autocheckout code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Even more deletes, and Ilya review. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/autofill_agent.h" 5 #include "components/autofill/content/renderer/autofill_agent.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 namespace { 56 namespace {
57 57
58 // The size above which we stop triggering autofill for an input text field 58 // The size above which we stop triggering autofill for an input text field
59 // (so to avoid sending long strings through IPC). 59 // (so to avoid sending long strings through IPC).
60 const size_t kMaximumTextSizeForAutofill = 1000; 60 const size_t kMaximumTextSizeForAutofill = 1000;
61 61
62 // The maximum number of data list elements to send to the browser process 62 // The maximum number of data list elements to send to the browser process
63 // via IPC (to prevent long IPC messages). 63 // via IPC (to prevent long IPC messages).
64 const size_t kMaximumDataListSizeForAutofill = 30; 64 const size_t kMaximumDataListSizeForAutofill = 30;
65 65
66 const int kAutocheckoutClickTimeout = 3;
67
68 66
69 // Gets all the data list values (with corresponding label) for the given 67 // Gets all the data list values (with corresponding label) for the given
70 // element. 68 // element.
71 void GetDataListSuggestions(const WebKit::WebInputElement& element, 69 void GetDataListSuggestions(const WebKit::WebInputElement& element,
72 std::vector<base::string16>* values, 70 std::vector<base::string16>* values,
73 std::vector<base::string16>* labels) { 71 std::vector<base::string16>* labels) {
74 WebNodeCollection options = element.dataListOptions(); 72 WebNodeCollection options = element.dataListOptions();
75 if (options.isNull()) 73 if (options.isNull())
76 return; 74 return;
77 75
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } // namespace 121 } // namespace
124 122
125 namespace autofill { 123 namespace autofill {
126 124
127 AutofillAgent::AutofillAgent(content::RenderView* render_view, 125 AutofillAgent::AutofillAgent(content::RenderView* render_view,
128 PasswordAutofillAgent* password_autofill_agent) 126 PasswordAutofillAgent* password_autofill_agent)
129 : content::RenderViewObserver(render_view), 127 : content::RenderViewObserver(render_view),
130 password_autofill_agent_(password_autofill_agent), 128 password_autofill_agent_(password_autofill_agent),
131 autofill_query_id_(0), 129 autofill_query_id_(0),
132 autofill_action_(AUTOFILL_NONE), 130 autofill_action_(AUTOFILL_NONE),
133 topmost_frame_(NULL),
134 web_view_(render_view->GetWebView()), 131 web_view_(render_view->GetWebView()),
135 display_warning_if_disabled_(false), 132 display_warning_if_disabled_(false),
136 was_query_node_autofilled_(false), 133 was_query_node_autofilled_(false),
137 has_shown_autofill_popup_for_current_edit_(false), 134 has_shown_autofill_popup_for_current_edit_(false),
138 did_set_node_text_(false), 135 did_set_node_text_(false),
139 autocheckout_click_in_progress_(false),
140 is_autocheckout_supported_(false),
141 has_new_forms_for_browser_(false), 136 has_new_forms_for_browser_(false),
142 ignore_text_changes_(false), 137 ignore_text_changes_(false),
143 weak_ptr_factory_(this) { 138 weak_ptr_factory_(this) {
144 render_view->GetWebView()->setAutofillClient(this); 139 render_view->GetWebView()->setAutofillClient(this);
145 140
146 // The PageClickTracker is a RenderViewObserver, and hence will be freed when 141 // The PageClickTracker is a RenderViewObserver, and hence will be freed when
147 // the RenderView is destroyed. 142 // the RenderView is destroyed.
148 new PageClickTracker(render_view, this); 143 new PageClickTracker(render_view, this);
149 } 144 }
150 145
151 AutofillAgent::~AutofillAgent() {} 146 AutofillAgent::~AutofillAgent() {}
152 147
153 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { 148 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
154 bool handled = true; 149 bool handled = true;
155 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) 150 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message)
156 IPC_MESSAGE_HANDLER(AutofillMsg_GetAllForms, OnGetAllForms)
157 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled) 151 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled)
158 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable, 152 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable,
159 OnFieldTypePredictionsAvailable) 153 OnFieldTypePredictionsAvailable)
160 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill, 154 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill,
161 OnSetAutofillActionFill) 155 OnSetAutofillActionFill)
162 IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm, 156 IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm,
163 OnClearForm) 157 OnClearForm)
164 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview, 158 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview,
165 OnSetAutofillActionPreview) 159 OnSetAutofillActionPreview)
166 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm, 160 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm,
167 OnClearPreviewedForm) 161 OnClearPreviewedForm)
168 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText, 162 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText,
169 OnSetNodeText) 163 OnSetNodeText)
170 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion, 164 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion,
171 OnAcceptDataListSuggestion) 165 OnAcceptDataListSuggestion)
172 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion, 166 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion,
173 OnAcceptPasswordAutofillSuggestion) 167 OnAcceptPasswordAutofillSuggestion)
174 IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteResult, 168 IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteResult,
175 OnRequestAutocompleteResult) 169 OnRequestAutocompleteResult)
176 IPC_MESSAGE_HANDLER(AutofillMsg_FillFormsAndClick,
177 OnFillFormsAndClick)
178 IPC_MESSAGE_HANDLER(AutofillMsg_AutocheckoutSupported,
179 OnAutocheckoutSupported)
180 IPC_MESSAGE_HANDLER(AutofillMsg_PageShown, 170 IPC_MESSAGE_HANDLER(AutofillMsg_PageShown,
181 OnPageShown) 171 OnPageShown)
182 IPC_MESSAGE_UNHANDLED(handled = false) 172 IPC_MESSAGE_UNHANDLED(handled = false)
183 IPC_END_MESSAGE_MAP() 173 IPC_END_MESSAGE_MAP()
184 return handled; 174 return handled;
185 } 175 }
186 176
187 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { 177 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) {
188 // Record timestamp on document load. This is used to record overhead of 178 // Record timestamp on document load. This is used to record overhead of
189 // Autofill feature. 179 // Autofill feature.
190 forms_seen_timestamp_ = base::TimeTicks::Now(); 180 forms_seen_timestamp_ = base::TimeTicks::Now();
191 181
192 // The document has now been fully loaded. Scan for forms to be sent up to 182 // The document has now been fully loaded. Scan for forms to be sent up to
193 // the browser. 183 // the browser.
194 std::vector<FormData> forms; 184 std::vector<FormData> forms;
195 bool has_more_forms = false; 185 bool has_more_forms = false;
196 if (!frame->parent()) { 186 if (!frame->parent()) {
197 topmost_frame_ = frame;
198 form_elements_.clear(); 187 form_elements_.clear();
199 has_more_forms = form_cache_.ExtractFormsAndFormElements( 188 has_more_forms = form_cache_.ExtractFormsAndFormElements(
200 *frame, kRequiredAutofillFields, &forms, &form_elements_); 189 *frame, kRequiredAutofillFields, &forms, &form_elements_);
201 } else { 190 } else {
202 form_cache_.ExtractForms(*frame, &forms); 191 form_cache_.ExtractForms(*frame, &forms);
203 } 192 }
204 193
205 autofill::FormsSeenState state = has_more_forms ? 194 autofill::FormsSeenState state = has_more_forms ?
206 autofill::PARTIAL_FORMS_SEEN : autofill::NO_SPECIAL_FORMS_SEEN; 195 autofill::PARTIAL_FORMS_SEEN : autofill::NO_SPECIAL_FORMS_SEEN;
207 196
208 // Always communicate to browser process for topmost frame. 197 // Always communicate to browser process for topmost frame.
209 if (!forms.empty() || !frame->parent()) { 198 if (!forms.empty() || !frame->parent()) {
210 Send(new AutofillHostMsg_FormsSeen(routing_id(), forms, 199 Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
211 forms_seen_timestamp_, 200 forms_seen_timestamp_,
212 state)); 201 state));
213 } 202 }
214 } 203 }
215 204
216 void AutofillAgent::DidStartProvisionalLoad(WebFrame* frame) {
217 if (!frame->parent()) {
218 is_autocheckout_supported_ = false;
219 topmost_frame_ = NULL;
220 if (click_timer_.IsRunning()) {
221 click_timer_.Stop();
222 autocheckout_click_in_progress_ = true;
223 }
224 }
225 }
226
227 void AutofillAgent::DidFailProvisionalLoad(WebFrame* frame,
228 const WebKit::WebURLError& error) {
229 if (!frame->parent() && autocheckout_click_in_progress_) {
230 autocheckout_click_in_progress_ = false;
231 ClickFailed();
232 }
233 }
234
235 void AutofillAgent::DidCommitProvisionalLoad(WebFrame* frame, 205 void AutofillAgent::DidCommitProvisionalLoad(WebFrame* frame,
236 bool is_new_navigation) { 206 bool is_new_navigation) {
237 in_flight_request_form_.reset(); 207 in_flight_request_form_.reset();
238 if (!frame->parent() && autocheckout_click_in_progress_) {
239 autocheckout_click_in_progress_ = false;
240 CompleteAutocheckoutPage(SUCCESS);
241 }
242 } 208 }
243 209
244 void AutofillAgent::FrameDetached(WebFrame* frame) { 210 void AutofillAgent::FrameDetached(WebFrame* frame) {
245 form_cache_.ResetFrame(*frame); 211 form_cache_.ResetFrame(*frame);
246 if (!frame->parent()) {
247 // |frame| is about to be destroyed so we need to clear |top_most_frame_|.
248 topmost_frame_ = NULL;
249 click_timer_.Stop();
250 }
251 } 212 }
252 213
253 void AutofillAgent::WillSubmitForm(WebFrame* frame, 214 void AutofillAgent::WillSubmitForm(WebFrame* frame,
254 const WebFormElement& form) { 215 const WebFormElement& form) {
255 FormData form_data; 216 FormData form_data;
256 if (WebFormElementToFormData(form, 217 if (WebFormElementToFormData(form,
257 WebFormControlElement(), 218 WebFormControlElement(),
258 REQUIRE_AUTOCOMPLETE, 219 REQUIRE_AUTOCOMPLETE,
259 static_cast<ExtractMask>( 220 static_cast<ExtractMask>(
260 EXTRACT_VALUE | EXTRACT_OPTION_TEXT), 221 EXTRACT_VALUE | EXTRACT_OPTION_TEXT),
(...skipping 20 matching lines...) Expand all
281 if (!web_element.document().frame()) 242 if (!web_element.document().frame())
282 return; 243 return;
283 244
284 const WebInputElement* element = toWebInputElement(&web_element); 245 const WebInputElement* element = toWebInputElement(&web_element);
285 246
286 if (!element || !element->isEnabled() || element->isReadOnly() || 247 if (!element || !element->isEnabled() || element->isReadOnly() ||
287 !element->isTextField() || element->isPasswordField()) 248 !element->isTextField() || element->isPasswordField())
288 return; 249 return;
289 250
290 element_ = *element; 251 element_ = *element;
291
292 MaybeShowAutocheckoutBubble();
293 } 252 }
294 253
295 void AutofillAgent::OrientationChangeEvent(int orientation) { 254 void AutofillAgent::OrientationChangeEvent(int orientation) {
296 HideAutofillUI(); 255 HideAutofillUI();
297 } 256 }
298 257
299 void AutofillAgent::MaybeShowAutocheckoutBubble() {
300 if (element_.isNull() || !element_.focused())
301 return;
302
303 FormData form;
304 FormFieldData field;
305 // This must be called to short circuit this method if it fails.
306 if (!FindFormAndFieldForInputElement(element_, &form, &field, REQUIRE_NONE))
307 return;
308
309 Send(new AutofillHostMsg_MaybeShowAutocheckoutBubble(
310 routing_id(),
311 form,
312 GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_)));
313 }
314
315 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) { 258 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) {
316 HideAutofillUI(); 259 HideAutofillUI();
317 } 260 }
318 261
319 void AutofillAgent::didRequestAutocomplete(WebKit::WebFrame* frame, 262 void AutofillAgent::didRequestAutocomplete(WebKit::WebFrame* frame,
320 const WebFormElement& form) { 263 const WebFormElement& form) {
321 GURL url(frame->document().url()); 264 GURL url(frame->document().url());
322 content::SSLStatus ssl_status = render_view()->GetSSLStatusOfFrame(frame); 265 content::SSLStatus ssl_status = render_view()->GetSSLStatusOfFrame(frame);
323 FormData form_data; 266 FormData form_data;
324 if (!in_flight_request_form_.isNull() || 267 if (!in_flight_request_form_.isNull() ||
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 const base::string16& value) { 464 const base::string16& value) {
522 // We need to make sure this is handled here because the browser process 465 // We need to make sure this is handled here because the browser process
523 // skipped it handling because it believed it would be handled here. If it 466 // skipped it handling because it believed it would be handled here. If it
524 // isn't handled here then the browser logic needs to be updated. 467 // isn't handled here then the browser logic needs to be updated.
525 bool handled = password_autofill_agent_->DidAcceptAutofillSuggestion( 468 bool handled = password_autofill_agent_->DidAcceptAutofillSuggestion(
526 element_, 469 element_,
527 value); 470 value);
528 DCHECK(handled); 471 DCHECK(handled);
529 } 472 }
530 473
531 void AutofillAgent::OnGetAllForms() {
532 form_elements_.clear();
533
534 // Force fetch all non empty forms.
535 std::vector<FormData> forms;
536 form_cache_.ExtractFormsAndFormElements(
537 *topmost_frame_, 0, &forms, &form_elements_);
538
539 // OnGetAllForms should only be called if AutofillAgent reported to
540 // AutofillManager that there are more forms
541 DCHECK(!forms.empty());
542
543 // Report to AutofillManager that all forms are being sent.
544 Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
545 forms_seen_timestamp_,
546 NO_SPECIAL_FORMS_SEEN));
547 }
548
549 void AutofillAgent::OnRequestAutocompleteResult( 474 void AutofillAgent::OnRequestAutocompleteResult(
550 WebFormElement::AutocompleteResult result, const FormData& form_data) { 475 WebFormElement::AutocompleteResult result, const FormData& form_data) {
551 if (in_flight_request_form_.isNull()) 476 if (in_flight_request_form_.isNull())
552 return; 477 return;
553 478
554 if (result == WebFormElement::AutocompleteResultSuccess) { 479 if (result == WebFormElement::AutocompleteResultSuccess) {
555 FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_); 480 FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_);
556 if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents()) 481 if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents())
557 result = WebFormElement::AutocompleteResultErrorInvalid; 482 result = WebFormElement::AutocompleteResultErrorInvalid;
558 } 483 }
559 484
560 in_flight_request_form_.finishRequestAutocomplete(result); 485 in_flight_request_form_.finishRequestAutocomplete(result);
561 in_flight_request_form_.reset(); 486 in_flight_request_form_.reset();
562 } 487 }
563 488
564 void AutofillAgent::OnFillFormsAndClick(
565 const std::vector<FormData>& forms,
566 const std::vector<WebElementDescriptor>& click_elements_before_form_fill,
567 const std::vector<WebElementDescriptor>& click_elements_after_form_fill,
568 const WebElementDescriptor& click_element_descriptor) {
569 DCHECK_EQ(forms.size(), form_elements_.size());
570
571 // Click elements in click_elements_before_form_fill.
572 for (size_t i = 0; i < click_elements_before_form_fill.size(); ++i) {
573 if (!ClickElement(topmost_frame_->document(),
574 click_elements_before_form_fill[i])) {
575 CompleteAutocheckoutPage(MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING);
576 return;
577 }
578 }
579
580 // Fill the form.
581 for (size_t i = 0; i < forms.size(); ++i)
582 FillFormForAllElements(forms[i], form_elements_[i]);
583
584 // Click elements in click_elements_after_form_fill.
585 for (size_t i = 0; i < click_elements_after_form_fill.size(); ++i) {
586 if (!ClickElement(topmost_frame_->document(),
587 click_elements_after_form_fill[i])) {
588 CompleteAutocheckoutPage(MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING);
589 return;
590 }
591 }
592
593 // Exit early if there is nothing to click.
594 if (click_element_descriptor.retrieval_method == WebElementDescriptor::NONE) {
595 CompleteAutocheckoutPage(SUCCESS);
596 return;
597 }
598
599 // It's possible that clicking the element to proceed in an Autocheckout
600 // flow will not actually proceed to the next step in the flow, e.g. there
601 // is a new required field that Autocheckout does not know how to fill. In
602 // order to capture this case and present the user with an error a timer is
603 // set that informs the browser of the error. |click_timer_| has to be started
604 // before clicking so it can start before DidStartProvisionalLoad started.
605 click_timer_.Start(FROM_HERE,
606 base::TimeDelta::FromSeconds(kAutocheckoutClickTimeout),
607 this,
608 &AutofillAgent::ClickFailed);
609 if (!ClickElement(topmost_frame_->document(),
610 click_element_descriptor)) {
611 CompleteAutocheckoutPage(MISSING_ADVANCE);
612 }
613 }
614
615 void AutofillAgent::OnAutocheckoutSupported() {
616 is_autocheckout_supported_ = true;
617 if (has_new_forms_for_browser_)
618 MaybeSendDynamicFormsSeen();
619 MaybeShowAutocheckoutBubble();
620 }
621
622 void AutofillAgent::OnPageShown() { 489 void AutofillAgent::OnPageShown() {
623 if (is_autocheckout_supported_)
624 MaybeShowAutocheckoutBubble();
625 }
626
627 void AutofillAgent::CompleteAutocheckoutPage(
628 autofill::AutocheckoutStatus status) {
629 click_timer_.Stop();
630 Send(new AutofillHostMsg_AutocheckoutPageCompleted(routing_id(), status));
631 }
632
633 void AutofillAgent::ClickFailed() {
634 CompleteAutocheckoutPage(CANNOT_PROCEED);
635 } 490 }
636 491
637 void AutofillAgent::ShowSuggestions(const WebInputElement& element, 492 void AutofillAgent::ShowSuggestions(const WebInputElement& element,
638 bool autofill_on_empty_values, 493 bool autofill_on_empty_values,
639 bool requires_caret_at_end, 494 bool requires_caret_at_end,
640 bool display_warning_if_disabled) { 495 bool display_warning_if_disabled) {
641 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || 496 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
642 element.isPasswordField() || !element.suggestedValue().isEmpty()) 497 element.isPasswordField() || !element.suggestedValue().isEmpty())
643 return; 498 return;
644 499
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 base::string16 substring = value; 600 base::string16 substring = value;
746 substring = substring.substr(0, node->maxLength()); 601 substring = substring.substr(0, node->maxLength());
747 602
748 node->setEditingValue(substring); 603 node->setEditingValue(substring);
749 } 604 }
750 605
751 void AutofillAgent::HideAutofillUI() { 606 void AutofillAgent::HideAutofillUI() {
752 Send(new AutofillHostMsg_HideAutofillUI(routing_id())); 607 Send(new AutofillHostMsg_HideAutofillUI(routing_id()));
753 } 608 }
754 609
610 // TODO(isherman): Decide if we want to support autofill with AJAX.
755 void AutofillAgent::didAssociateFormControls( 611 void AutofillAgent::didAssociateFormControls(
756 const WebKit::WebVector<WebKit::WebNode>& nodes) { 612 const WebKit::WebVector<WebKit::WebNode>& nodes) {
757 for (size_t i = 0; i < nodes.size(); ++i) {
758 WebKit::WebNode node = nodes[i];
759 if (node.document().frame() == topmost_frame_) {
760 forms_seen_timestamp_ = base::TimeTicks::Now();
761 has_new_forms_for_browser_ = true;
762 break;
763 }
764 }
765
766 if (has_new_forms_for_browser_ && is_autocheckout_supported_)
767 MaybeSendDynamicFormsSeen();
768 }
769
770 void AutofillAgent::MaybeSendDynamicFormsSeen() {
771 has_new_forms_for_browser_ = false;
772 form_elements_.clear();
773 std::vector<FormData> forms;
774 // This will only be called for Autocheckout flows, so send all forms to
775 // save an IPC.
776 form_cache_.ExtractFormsAndFormElements(
777 *topmost_frame_, 0, &forms, &form_elements_);
778 autofill::FormsSeenState state = autofill::DYNAMIC_FORMS_SEEN;
779
780 if (!forms.empty()) {
781 if (click_timer_.IsRunning())
782 click_timer_.Stop();
783 Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
784 forms_seen_timestamp_,
785 state));
786 }
787 } 613 }
788 614
789 } // namespace autofill 615 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698