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
3// found in the LICENSE file.
4
5#include "components/autofill/content/browser/content_autofill_driver.h"
6
7#include "base/command_line.h"
8#include "base/threading/sequenced_worker_pool.h"
9#include "components/autofill/content/common/autofill_messages.h"
10#include "components/autofill/core/browser/autofill_client.h"
11#include "components/autofill/core/browser/autofill_external_delegate.h"
12#include "components/autofill/core/browser/autofill_manager.h"
13#include "components/autofill/core/browser/form_structure.h"
14#include "components/autofill/core/common/autofill_switches.h"
15#include "content/public/browser/browser_context.h"
16#include "content/public/browser/browser_thread.h"
17#include "content/public/browser/navigation_controller.h"
18#include "content/public/browser/navigation_details.h"
19#include "content/public/browser/render_view_host.h"
20#include "content/public/browser/web_contents.h"
21#include "content/public/common/frame_navigate_params.h"
22#include "ipc/ipc_message_macros.h"
23
24namespace autofill {
25
26namespace {
27
28const char kContentAutofillDriverWebContentsUserDataKey[] =
29    "web_contents_autofill_driver_impl";
30
31}  // namespace
32
33// static
34void ContentAutofillDriver::CreateForWebContentsAndDelegate(
35    content::WebContents* contents,
36    AutofillClient* client,
37    const std::string& app_locale,
38    AutofillManager::AutofillDownloadManagerState enable_download_manager) {
39  if (FromWebContents(contents))
40    return;
41
42  contents->SetUserData(
43      kContentAutofillDriverWebContentsUserDataKey,
44      new ContentAutofillDriver(
45          contents, client, app_locale, enable_download_manager));
46}
47
48// static
49ContentAutofillDriver* ContentAutofillDriver::FromWebContents(
50    content::WebContents* contents) {
51  return static_cast<ContentAutofillDriver*>(
52      contents->GetUserData(kContentAutofillDriverWebContentsUserDataKey));
53}
54
55ContentAutofillDriver::ContentAutofillDriver(
56    content::WebContents* web_contents,
57    AutofillClient* client,
58    const std::string& app_locale,
59    AutofillManager::AutofillDownloadManagerState enable_download_manager)
60    : content::WebContentsObserver(web_contents),
61      autofill_manager_(new AutofillManager(this,
62                                            client,
63                                            app_locale,
64                                            enable_download_manager)),
65      autofill_external_delegate_(autofill_manager_.get(), this),
66      request_autocomplete_manager_(this) {
67  autofill_manager_->SetExternalDelegate(&autofill_external_delegate_);
68}
69
70ContentAutofillDriver::~ContentAutofillDriver() {}
71
72bool ContentAutofillDriver::IsOffTheRecord() const {
73  return web_contents()->GetBrowserContext()->IsOffTheRecord();
74}
75
76net::URLRequestContextGetter* ContentAutofillDriver::GetURLRequestContext() {
77  return web_contents()->GetBrowserContext()->GetRequestContext();
78}
79
80base::SequencedWorkerPool* ContentAutofillDriver::GetBlockingPool() {
81  return content::BrowserThread::GetBlockingPool();
82}
83
84bool ContentAutofillDriver::RendererIsAvailable() {
85  return (web_contents()->GetRenderViewHost() != NULL);
86}
87
88void ContentAutofillDriver::SendFormDataToRenderer(
89    int query_id,
90    RendererFormDataAction action,
91    const FormData& data) {
92  if (!RendererIsAvailable())
93    return;
94  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
95  switch (action) {
96    case FORM_DATA_ACTION_FILL:
97      host->Send(
98          new AutofillMsg_FillForm(host->GetRoutingID(), query_id, data));
99      break;
100    case FORM_DATA_ACTION_PREVIEW:
101      host->Send(
102          new AutofillMsg_PreviewForm(host->GetRoutingID(), query_id, data));
103      break;
104  }
105}
106
107void ContentAutofillDriver::PingRenderer() {
108  if (!RendererIsAvailable())
109    return;
110  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
111  host->Send(new AutofillMsg_Ping(host->GetRoutingID()));
112}
113
114void ContentAutofillDriver::SendAutofillTypePredictionsToRenderer(
115    const std::vector<FormStructure*>& forms) {
116  if (!CommandLine::ForCurrentProcess()->HasSwitch(
117          switches::kShowAutofillTypePredictions))
118    return;
119
120  if (!RendererIsAvailable())
121    return;
122  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
123
124  std::vector<FormDataPredictions> type_predictions;
125  FormStructure::GetFieldTypePredictions(forms, &type_predictions);
126  host->Send(new AutofillMsg_FieldTypePredictionsAvailable(host->GetRoutingID(),
127                                                           type_predictions));
128}
129
130void ContentAutofillDriver::RendererShouldAcceptDataListSuggestion(
131    const base::string16& value) {
132  if (!RendererIsAvailable())
133    return;
134  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
135  host->Send(
136      new AutofillMsg_AcceptDataListSuggestion(host->GetRoutingID(), value));
137}
138
139void ContentAutofillDriver::RendererShouldClearFilledForm() {
140  if (!RendererIsAvailable())
141    return;
142  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
143  host->Send(new AutofillMsg_ClearForm(host->GetRoutingID()));
144}
145
146void ContentAutofillDriver::RendererShouldClearPreviewedForm() {
147  if (!RendererIsAvailable())
148    return;
149  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
150  host->Send(new AutofillMsg_ClearPreviewedForm(host->GetRoutingID()));
151}
152
153void ContentAutofillDriver::RendererShouldFillFieldWithValue(
154    const base::string16& value) {
155  if (!RendererIsAvailable())
156    return;
157  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
158  host->Send(new AutofillMsg_FillFieldWithValue(host->GetRoutingID(), value));
159}
160void ContentAutofillDriver::RendererShouldPreviewFieldWithValue(
161    const base::string16& value) {
162  if (!RendererIsAvailable())
163    return;
164  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
165  host->Send(new AutofillMsg_PreviewFieldWithValue(host->GetRoutingID(),
166                                                   value));
167}
168
169bool ContentAutofillDriver::OnMessageReceived(const IPC::Message& message) {
170  bool handled = true;
171  IPC_BEGIN_MESSAGE_MAP(ContentAutofillDriver, message)
172  IPC_MESSAGE_FORWARD(AutofillHostMsg_FormsSeen,
173                      autofill_manager_.get(),
174                      AutofillManager::OnFormsSeen)
175  IPC_MESSAGE_FORWARD(AutofillHostMsg_FormSubmitted,
176                      autofill_manager_.get(),
177                      AutofillManager::OnFormSubmitted)
178  IPC_MESSAGE_FORWARD(AutofillHostMsg_TextFieldDidChange,
179                      autofill_manager_.get(),
180                      AutofillManager::OnTextFieldDidChange)
181  IPC_MESSAGE_FORWARD(AutofillHostMsg_QueryFormFieldAutofill,
182                      autofill_manager_.get(),
183                      AutofillManager::OnQueryFormFieldAutofill)
184  IPC_MESSAGE_FORWARD(AutofillHostMsg_DidPreviewAutofillFormData,
185                      autofill_manager_.get(),
186                      AutofillManager::OnDidPreviewAutofillFormData)
187  IPC_MESSAGE_FORWARD(AutofillHostMsg_PingAck,
188                      &autofill_external_delegate_,
189                      AutofillExternalDelegate::OnPingAck)
190  IPC_MESSAGE_FORWARD(AutofillHostMsg_DidFillAutofillFormData,
191                      autofill_manager_.get(),
192                      AutofillManager::OnDidFillAutofillFormData)
193  IPC_MESSAGE_FORWARD(AutofillHostMsg_DidEndTextFieldEditing,
194                      autofill_manager_.get(),
195                      AutofillManager::OnDidEndTextFieldEditing)
196  IPC_MESSAGE_FORWARD(AutofillHostMsg_HidePopup,
197                      autofill_manager_.get(),
198                      AutofillManager::OnHidePopup)
199  IPC_MESSAGE_FORWARD(AutofillHostMsg_SetDataList,
200                      autofill_manager_.get(),
201                      AutofillManager::OnSetDataList)
202  IPC_MESSAGE_FORWARD(AutofillHostMsg_RequestAutocomplete,
203                      &request_autocomplete_manager_,
204                      RequestAutocompleteManager::OnRequestAutocomplete)
205  IPC_MESSAGE_FORWARD(AutofillHostMsg_CancelRequestAutocomplete,
206                      &request_autocomplete_manager_,
207                      RequestAutocompleteManager::OnCancelRequestAutocomplete)
208  IPC_MESSAGE_UNHANDLED(handled = false)
209  IPC_END_MESSAGE_MAP()
210  return handled;
211}
212
213void ContentAutofillDriver::DidNavigateMainFrame(
214    const content::LoadCommittedDetails& details,
215    const content::FrameNavigateParams& params) {
216  if (details.is_navigation_to_different_page())
217    autofill_manager_->Reset();
218}
219
220void ContentAutofillDriver::SetAutofillManager(
221    scoped_ptr<AutofillManager> manager) {
222  autofill_manager_ = manager.Pass();
223  autofill_manager_->SetExternalDelegate(&autofill_external_delegate_);
224}
225
226void ContentAutofillDriver::NavigationEntryCommitted(
227    const content::LoadCommittedDetails& load_details) {
228  autofill_manager_->client()->HideAutofillPopup();
229}
230
231void ContentAutofillDriver::WasHidden() {
232  autofill_manager_->client()->HideAutofillPopup();
233}
234
235}  // namespace autofill
236