File: content_autofill_driver.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (318 lines) | stat: -rw-r--r-- 14,695 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_H_
#define COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_H_

#include <map>
#include <optional>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/types/optional_ref.h"
#include "components/autofill/content/browser/content_autofill_client.h"
#include "components/autofill/content/common/mojom/autofill_agent.mojom.h"
#include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
#include "components/autofill/core/browser/foundations/autofill_driver.h"
#include "components/autofill/core/browser/foundations/autofill_manager.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"

namespace autofill {

class ContentAutofillDriverFactory;
class AutofillDriverRouter;

// ContentAutofillDriver drives the Autofill flow in the browser process based
// on communication from the renderer and from the external world.
//
// Each ContentAutofillDriver is associated with exactly one RenderFrameHost
// and communicates with exactly one AutofillAgent throughout its entire
// lifetime.
//
// This RenderFrameHost owns all forms and fields in the renderer-browser
// communication:
// - ContentAutofillDriver may assume that forms and fields received in the
//   mojom::AutofillDriver events are owned by that RenderFrameHost.
// - Conversely, the forms and fields which ContentAutofillDriver passes to
//   mojom::AutofillAgent events must be owned by that RenderFrameHost.
//
// Events in AutofillDriver and mojom::AutofillDriver are passed on to
// AutofillDriverRouter, which has one instance per WebContents. The naming
// pattern is that for all of these events, there are two functions:
//
//   1. ReturnType ContentAutofillDriver::Foo(Args...)
//   2. ReturnType AutofillDriverRouter::Foo(RoutedCallback, Args...)
//
// The first function calls the second, and the second calls the callback.
// That callback takes a target AutofillDriver, which may be different from the
// first function's ContentAutofillDriver.
//
// Consider the following pseudo-HTML:
//   <!-- frame name "ABC" -->
//   <form>
//     <input> <!-- renderer_id = 12 -->
//     <input> <!-- renderer_id = 34 -->
//     <iframe name="DEF">
//       <input> <!-- renderer_id = 56 -->
//       <input> <!-- renderer_id = 78 -->
//     </iframe>
//   </form>
// In this case, the frame "ABC" holds a form with fields
//   FormFieldData{.host_frame = ABC, .renderer_id = 12, ...},
//   FormFieldData{.host_frame = ABC, .renderer_id = 34, ...},
// and the frame "DEF" holds a form with fields
//   FormFieldData{.host_frame = DEF, .renderer_id = 56, ...},
//   FormFieldData{.host_frame = DEF, .renderer_id = 78, ...}.
// The SendFieldsEligibleForManualFillingToRenderer() event, for example, is
// initiated by ABC's AutofillManager by calling
//   abc_driver->SendFieldsEligibleForManualFillingToRenderer({
//     FieldGlobalId{.host_frame = ABC, .renderer_id = 12},
//     FieldGlobalId{.host_frame = ABC, .renderer_id = 34},
//     FieldGlobalId{.host_frame = DEF, .renderer_id = 56},
//     FieldGlobalId{.host_frame = DEF, .renderer_id = 78}
//   }).
// |abc_driver| forwards the event to the router by calling
//   router->SendFieldsEligibleForManualFillingToRenderer(abc_driver, {
//     FieldGlobalId{.host_frame = ABC, .renderer_id = 12},
//     FieldGlobalId{.host_frame = ABC, .renderer_id = 34},
//     FieldGlobalId{.host_frame = DEF, .renderer_id = 56},
//     FieldGlobalId{.host_frame = DEF, .renderer_id = 78}
//   }, callback).
// The router splits the groups the fields by their host frame token and routes
// the calls to the respective frame's drivers:
//   callback(abc_driver, {
//     FieldRendererId{.renderer_id = 12},
//     FieldRendererId{.renderer_id = 34},
//   });
//   callback(def_driver, {
//     FieldRendererId{.renderer_id = 56},
//     FieldRendererId{.renderer_id = 78}
//   });
// These callbacks call the agents in the renderer processes:
//   abc_agent->SetFieldsEligibleForManualFilling({
//     FieldRendererId{.renderer_id = 12},
//     FieldRendererId{.renderer_id = 34},
//   });
//   def_agent->SetFieldsEligibleForManualFilling({
//     FieldRendererId{.renderer_id = 56},
//     FieldRendererId{.renderer_id = 78}
//   });
//
// See AutofillDriverRouter for further details.
class ContentAutofillDriver : public AutofillDriver,
                              public mojom::AutofillDriver {
 public:
  class ContentAutofillDriverFactoryPassKey {
   private:
    friend class ContentAutofillDriverFactory;
    friend class ContentAutofillDriverTestApi;
    ContentAutofillDriverFactoryPassKey() = default;
  };

  // Gets the driver for |render_frame_host|.
  // If |render_frame_host| is currently being deleted, this may be nullptr.
  static ContentAutofillDriver* GetForRenderFrameHost(
      content::RenderFrameHost* render_frame_host);

  // Part of the initialization may be embedder-specific, implemented in
  // ContentAutofillClient::CreateManager().
  ContentAutofillDriver(content::RenderFrameHost* render_frame_host,
                        ContentAutofillDriverFactory* owner);
  ContentAutofillDriver(const ContentAutofillDriver&) = delete;
  ContentAutofillDriver& operator=(const ContentAutofillDriver&) = delete;
  ~ContentAutofillDriver() override;

  // Clears the driver's and the manager's stored forms and other state,
  // *except* for the LifecycleState, which is controlled by the
  // AutofillDriverFactory. Called on certain types of navigations.
  void Reset(ContentAutofillDriverFactoryPassKey pass_key);

  content::RenderFrameHost* render_frame_host() { return &*render_frame_host_; }
  const content::RenderFrameHost* render_frame_host() const {
    return &*render_frame_host_;
  }

  // Expose the events that originate from the browser and renderer processes,
  // respectively.
  //
  // The purpose of not exposing these events directly in ContentAutofillDriver
  // is to make the caller aware of the event's intended source. This is
  // relevant because renderer forms and browser forms have distinct properties:
  // certain fields are not set in renderer form (see SetFrameAndFormMetaData()
  // for details) and, if they are part of a frame-transcending form, they are
  // not flattened yet (see AutofillDriverRouter for details).
  autofill::AutofillDriver& browser_events() { return *this; }
  mojom::AutofillDriver& renderer_events() { return *this; }

  void BindPendingReceiver(
      mojo::PendingAssociatedReceiver<mojom::AutofillDriver> pending_receiver);
  const mojo::AssociatedRemote<mojom::AutofillAgent>& GetAutofillAgent();

  // autofill::AutofillDriver:
  // These are the non-event functions from autofill::AutofillDriver. The events
  // are defined in the private part below.
  LocalFrameToken GetFrameToken() const override;
  std::optional<LocalFrameToken> Resolve(FrameToken query) override;
  ContentAutofillDriver* GetParent() override;
  ContentAutofillClient& GetAutofillClient() override;
  AutofillManager& GetAutofillManager() override;
  ukm::SourceId GetPageUkmSourceId() const override;
  bool IsActive() const override;
  bool HasSharedAutofillPermission() const override;
  bool CanShowAutofillUi() const override;
  std::optional<net::IsolationInfo> GetIsolationInfo() override;

 private:
  friend class ContentAutofillDriverTestApi;

  // Communication falls into two groups:
  //
  // (1) Browser -> renderer (autofill::AutofillDriver):
  //     These events are triggered by an AutofillManager or similar and are
  //     passed to one or multiple AutofillAgents. They fall into three groups:
  //     (1a) Broadcast events are sent to many AutofillAgents.
  //     (1b) Routed events are sent to a single AutofillAgent, which may
  //          be not this driver's AutofillAgent.
  //     (1c) Main-frame events are sent to the driver's main frame's
  //          AutofillAgent.
  //     (1d) Unrouted events are sent to this driver's AutofillAgent.
  // (2) Renderer -> browser (mojom::AutofillDriver):
  //     These events are triggered by an AutofillAgent and are passed to one or
  //     multiple AutofillManagers. They fall into two groups:
  //     (2a) Broadcast events are sent to many AutofillManagers.
  //     (2b) Routed events are sent to a single AutofillManager, which may
  //          be not this driver's AutofillManager.
  //
  // These events are private to avoid accidental use in the browser process.
  // Groups (1) and (2) can be accessed explicitly through browser_events() and
  // renderer_events(), respectively.
  //
  // Keep the events of each group in alphabetic order.

  // Group (1a): browser -> renderer events, broadcast (see comment above).
  // autofill::AutofillDriver:
  void TriggerFormExtractionInAllFrames(
      base::OnceCallback<void(bool success)> form_extraction_finished_callback)
      override;
  void RendererShouldClearPreviewedForm() override;

  // Group (1b): browser -> renderer events, routed (see comment above).
  // autofill::AutofillDriver:
  base::flat_set<FieldGlobalId> ApplyFormAction(
      mojom::FormActionType action_type,
      mojom::ActionPersistence action_persistence,
      base::span<const FormFieldData> data,
      const url::Origin& triggered_origin,
      const base::flat_map<FieldGlobalId, FieldType>& field_type_map) override;
  void ApplyFieldAction(mojom::FieldActionType action_type,
                        mojom::ActionPersistence action_persistence,
                        const FieldGlobalId& field_id,
                        const std::u16string& value) override;
  void ExtractForm(FormGlobalId form,
                   BrowserFormHandler final_handler) override;
  void RendererShouldAcceptDataListSuggestion(
      const FieldGlobalId& field_id,
      const std::u16string& value) override;
  void RendererShouldSetSuggestionAvailability(
      const FieldGlobalId& field_id,
      mojom::AutofillSuggestionAvailability suggestion_availability) override;
  void RendererShouldTriggerSuggestions(
      const FieldGlobalId& field_id,
      AutofillSuggestionTriggerSource trigger_source) override;
  void SendTypePredictionsToRenderer(const FormStructure& form) override;
  void ExposeDomNodeIDs() override;

  // Group (1c): browser -> renderer events, directed to to this driver's main
  // driver (see comment above).
  // autofill::AutofillDriver:
  void GetFourDigitCombinationsFromDom(
      base::OnceCallback<void(const std::vector<std::string>&)>
          potential_matches) override;
  // TODO(crbug.com/356442446): This event is currently routed to the main frame
  // but it should be broadcasted to all RenderFrames when we want to collect
  // the final checkout amount from all frames.
  void ExtractLabeledTextNodeValue(
      const std::u16string& value_regex,
      const std::u16string& label_regex,
      uint32_t number_of_ancestor_levels_to_search,
      base::OnceCallback<void(const std::string& amount)> response_callback)
      override;

  // Group (1d): browser -> renderer events, unrouted (see comment above).
  // autofill::AutofillDriver:
  void TriggerFormExtractionInDriverFrame(
      AutofillDriverRouterAndFormForestPassKey pass_key) override;

  // Group (2a): renderer -> browser events, broadcast (see comment above).
  // mojom::AutofillDriver:
  void DidEndTextFieldEditing() override;
  void FocusOnNonFormField() override;
  void HidePopup() override;

  // Group (2b): renderer -> browser events, routed (see comment above).
  // mojom::AutofillDriver:
  void AskForValuesToFill(const FormData& form,
                          FieldRendererId field_id,
                          const gfx::Rect& caret_bounds,
                          AutofillSuggestionTriggerSource trigger_source,
                          const std::optional<PasswordSuggestionRequest>&
                              password_request) override;
  void DidFillAutofillFormData(const FormData& form,
                               base::TimeTicks timestamp) override;
  void FocusOnFormField(const FormData& form,
                        FieldRendererId field_id) override;
  void FormsSeen(const std::vector<FormData>& updated_forms,
                 const std::vector<FormRendererId>& removed_forms) override;
  void FormSubmitted(const FormData& form,
                     mojom::SubmissionSource submission_source) override;
  void JavaScriptChangedAutofilledValue(
      const FormData& form,
      FieldRendererId field_id,
      const std::u16string& old_value) override;
  void SelectControlSelectionChanged(const FormData& form,
                                     FieldRendererId field_id) override;
  void SelectFieldOptionsDidChange(const FormData& form) override;
  void CaretMovedInFormField(const FormData& form,
                             FieldRendererId field_id,
                             const gfx::Rect& caret_bounds) override;
  void TextFieldValueChanged(const FormData& form,
                             FieldRendererId field_id,
                             base::TimeTicks timestamp) override;
  void TextFieldDidScroll(const FormData& form,
                          FieldRendererId field_id) override;

  void LiftForTest(FormData& form);

  // The router must only route among ContentAutofillDrivers because
  // ContentAutofillDriver casts AutofillDrivers to ContentAutofillDrivers.
  AutofillDriverRouter& router();

  // The frame/document to which this driver is associated. Outlives `this`.
  // RFH is corresponds to neither a frame nor a document: it may survive
  // navigations that documents don't, but it may not survive cross-origin
  // navigations.
  const raw_ref<content::RenderFrameHost> render_frame_host_;

  // The factory that created this driver. Outlives `this`.
  const raw_ref<ContentAutofillDriverFactory> owner_;

  mojo::AssociatedReceiver<mojom::AutofillDriver> receiver_{this};

  mojo::AssociatedRemote<mojom::AutofillAgent> autofill_agent_;

  std::unique_ptr<AutofillManager> autofill_manager_ = nullptr;
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_H_