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 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
|
// Copyright 2013 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_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_H_
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/common/aliases.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "net/base/isolation_info.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/accessibility/ax_tree_id.h"
#include "url/origin.h"
namespace autofill {
class FormStructure;
class AutofillClient;
class AutofillDriverFactory;
class AutofillManager;
namespace internal {
class FormForest;
}
// AutofillDriver is Autofill's lowest-level abstraction of a frame that is
// shared among all platforms.
//
// Most notably, it is a gateway for all communication from the browser code to
// the DOM, or more precisely, to the AutofillAgent (which are different classes
// of the same name in non-iOS vs iOS).
//
// The reverse communication, from the AutofillAgent to the browser code, goes
// through mojom::AutofillDriver on non-iOS, and directly to AutofillManager on
// iOS.
//
// Events for browser-internal communication do *NOT* belong here. Use
// AutofillManager::Observer instead.
//
// An AutofillDriver corresponds to a frame, rather than a document, in the
// sense that it may survive navigations.
//
// AutofillDriver has two implementations:
// - AutofillDriverIOS for iOS,
// - ContentAutofillDriver for all other platforms.
//
// An AutofillDriver's lifetime must be contained by the associated frame,
// web::WebFrame on iOS and content::RenderFrameHost on non-iOS. This is ensured
// by the AutofillDriverIOSFactory and ContentAutofillDriverFactory,
// respectively, which own the AutofillDrivers.
class AutofillDriver {
public:
// An AutofillDriver's LifecycleState indicates whether its content is
// currently presented to the user. It closely follows
// content::RenderFrameHost's LifecycleState but collapses inactive states.
//
// State changes must not happen during construction or destruction.
//
// State changes fire events in AutofillManager::Observer.
//
// The possible transitions are:
//
// LINT.IfChange(LifecycleStateChanges)
//
// ╭───────────────────────────╮
// │ ▼
// kInactive ◄──► kActive ──► kPendingDeletion
// ▲ ▲
// │ ╰─────► kPendingReset
// ╰──────────────────────► kPendingReset
//
// LINT.ThenChange(autofill_driver.cc:LifecycleStateChanges)
//
// The initial state is kInactive.
//
// Transitions from kPendingReset can only return to the previous state.
// Transitions between kInactive and kPendingReset only happen if the frame is
// prerendering.
// TODO: crbug.com/342132628 - Such transitions won't be possible anymore when
// prerendered CADs are deferred.
//
// Common behavior very shortly after the AutofillDriver's creation is the
// following:
// 1. It transitions to kActive.
// That happens unless the document is prerendering.
// 2. It transitions to kPendingReset and then back to its previous state,
// kActive or kInactive. That happens on non-iOS when the frame does its
// first navigation, which is just a special case of a navigation that the
// AutofillDriver survives.
enum class LifecycleState {
// The AutofillDriver corresponds to a frame that is currently not
// displayed to the user, either because it is being prerendered or because
// it is BFCached.
kInactive,
// The AutofillDriver corresponds to a frame that is being displayed.
kActive,
// The AutofillDriver is about to be reset because the document in its
// associated driver is about to change.
kPendingReset,
// The destructor of AutofillDriver and its associated AutofillDriver are
// about to begin. The AutofillDriver is still fully intact at this point.
kPendingDeletion,
};
virtual ~AutofillDriver();
// The current state of the driver. See LifecycleState for details.
LifecycleState GetLifecycleState() const { return lifecycle_state_; }
// Sets the new lifecycle state.
//
// AutofillDriverFactory (not AutofillDriver) manages the lifecycle because it
// is easiest for the factory to coordinate the different phases:
// - construct the driver,
// - set lifecycle state change,
// - notify observers,
// - destruct the driver.
void SetLifecycleState(LifecycleState new_state,
base::PassKey<AutofillDriverFactory> pass_key);
// Returns the uniquely identifying frame token.
virtual LocalFrameToken GetFrameToken() const = 0;
// Resolves a FrameToken `query` from the perspective of `this` to the
// globally unique LocalFrameToken. Returns `std::nullopt` if `query` is a
// RemoteFrameToken that cannot be resolved from the perspective of `this`.
//
// This function should not be cached: a later Resolve() call may map the same
// RemoteFrameToken to another LocalFrameToken.
//
// See the documentation of LocalFrameToken and RemoteFrameToken for details.
virtual std::optional<LocalFrameToken> Resolve(FrameToken query) = 0;
// Returns the AutofillDriver of the parent frame, if such a frame and driver
// exist, and nullptr otherwise.
virtual AutofillDriver* GetParent() = 0;
// The owning AutofillClient.
virtual AutofillClient& GetAutofillClient() = 0;
// Returns the AutofillManager owned by the AutofillDriver.
virtual AutofillManager& GetAutofillManager() = 0;
// Gets the UKM source ID associated with this driver's outermost main frame's
// document.
//
// That implies the following properties:
// - A child frame has the same UKM source ID as its parent frame.
// - When a cross-document navigation in the outermost main frame leads to ...
// - ... a *new* AutofillDriver, the new driver has a new UKM source ID.
// - ... the *same* AutofillDriver (i.e., the driver transitions into the
// LifecycleState::kPendingReset), the driver gets a new UKM source ID.
virtual ukm::SourceId GetPageUkmSourceId() const = 0;
// Returns whether the AutofillDriver instance is associated with an active
// frame in the MPArch sense.
virtual bool IsActive() const = 0;
// Returns whether the policy-controlled feature "shared-autofill" is enabled
// in the document. In the main frame the permission is enabled by default.
// The main frame may pass it on to its children.
virtual bool HasSharedAutofillPermission() const = 0;
// Returns the IsolationInfo of the associated frame. May be nullopt if the
// IsolationInfo is not used (for example, on iOS).
virtual std::optional<net::IsolationInfo> GetIsolationInfo() = 0;
// Returns true iff a popup can be shown on the behalf of the associated
// frame.
virtual bool CanShowAutofillUi() const = 0;
class AutofillDriverRouterAndFormForestPassKey {
friend class AutofillDriverRouter;
friend class internal::FormForest;
friend class AutofillDriverTestApi;
AutofillDriverRouterAndFormForestPassKey() = default;
};
// Triggers a form extraction of the new forms in the AutofillAgent. This is
// necessary when a form is seen in a child frame and it is not known which
// form is its parent.
//
// Unlike other events, this is *not* be routed or broadcast to other frames;
// it refers to the frame associated with the driver.
//
// Generally, this may happen because AutofillAgent is only notified about
// newly created form control elements, but not about newly created or loaded
// child frames.
//
// For example, consider a parent frame with a form that contains an <iframe>.
// Suppose the parent form is seen (processed by AutofillDriver::FormsSeen())
// before the iframe is loaded. Loading a cross-origin page into the iframe
// may change the iframe's frame token. Then, the frame token in the parent
// form's FormData::child_frames may be outdated. When a form is now seen in
// the child frame, it is not known *which form* in the parent frame is its
// parent form. In this scenario, a form extraction should be triggered.
virtual void TriggerFormExtractionInDriverFrame(
AutofillDriverRouterAndFormForestPassKey pass_key) = 0;
// Triggers a form_extraction on all frames of the same frame tree. Calls
// `form_extraction_finished_callback` when all frames reported back
// being done. `success == false` indicates that in some frame, a
// form_extraction was triggered while another form_extraction was ongoing.
virtual void TriggerFormExtractionInAllFrames(
base::OnceCallback<void(bool success)>
form_extraction_finished_callback) = 0;
// Response handler for ExtractForm(). The `host_frame_driver` manages `form`,
// i.e., `form.host_frame == host_frame_driver->GetFrameToken()`. The form is
// the flattened representation of the form (see autofill_driver_router.h or
// form_forest.h for the definition of a browser form).
using BrowserFormHandler =
base::OnceCallback<void(AutofillDriver* host_frame_driver,
const std::optional<FormData>& form)>;
// Extracts the given form and calls `response_handler` for the browser form
// that includes `form`.
//
// The semantics may be a little surprising. Consider the following example:
// <form id=f>
// <input>
// <iframe>
// <form id=g>
// <input id=i>
// </form>
// </iframe>
// </form>
// Calling ExtractForm() for "g" re-extracts that form and may then flatten it
// into "f". So the `response_handler` is called for that browser form that
// includes "f" and the newly-extracted "g".
//
// To re-extract all forms (in all frames), see TriggerFormExtractionIn*().
//
// More precisely:
//
// If the `form` is found, `response_handler` is called with the driver that
// manages the browser form that includes `form` and that browser form itself
// (i.e., their `FormData.host_frame` and `AutofillDriver::GetFrameToken()`
// are equal). The driver is distinct from `this` if the form is managed by
// another frame (e.g., when `this` is a subframe and the form is managed by
// an ancestor).
//
// If the form is not found, the `response_handler` is called with nullptr for
// the driver and std::nullopt for the form.
virtual void ExtractForm(FormGlobalId form,
BrowserFormHandler response_handler) = 0;
// Forwards `form` to the renderer.
//
// `field_type_map` contains the type predictions of the fields that may be
// modified; this parameter can be taken into account to decide which fields
// to modify across frames. See FormForest::GetRendererFormsOfBrowserForm()
// for the details on Autofill's security policy. Note that this map contains
// the types of the fields at filling time and not at undo time, to ensure
// consistency.
//
// `triggered_origin` is the origin of the field that triggered the filling
// operation currently being filled or undone.
//
// Returns the FieldGlobalIds that were safe to modify according to Autofill's
// security policy. This is a subset of the FieldGlobalIds of `form.fields`.
//
// This method is a no-op if the renderer is not currently available.
virtual 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) = 0;
// Tells the renderer to perform actions on the node text.
// If the `action_type` is kSelectAll, then `value` needs to be empty.
virtual void ApplyFieldAction(mojom::FieldActionType action_type,
mojom::ActionPersistence action_persistence,
const FieldGlobalId& field_id,
const std::u16string& value) = 0;
// Sends the field type predictions of `form` to the renderer.
virtual void SendTypePredictionsToRenderer(const FormStructure& forms) = 0;
// Calls the agent and exposes DOM Node IDS as part of devtools protocol.
virtual void ExposeDomNodeIDs() = 0;
// Tells the renderer to accept data list suggestions for |value|.
virtual void RendererShouldAcceptDataListSuggestion(
const FieldGlobalId& field_id,
const std::u16string& value) = 0;
// Tells the renderer to clear the currently previewed Autofill results.
virtual void RendererShouldClearPreviewedForm() = 0;
// Tells the renderer to trigger a AskForValuesToFill() event.
virtual void RendererShouldTriggerSuggestions(
const FieldGlobalId& field_id,
AutofillSuggestionTriggerSource trigger_source) = 0;
// Tells the renderer to set the currently focused node's corresponding
// accessibility node's autofill suggestion_availability to
// |suggestion_availability|.
virtual void RendererShouldSetSuggestionAvailability(
const FieldGlobalId& field_id,
mojom::AutofillSuggestionAvailability suggestion_availability) = 0;
// Query's the DOM for four digit combinations that could potentially be of a
// card number.
virtual void GetFourDigitCombinationsFromDom(
base::OnceCallback<void(const std::vector<std::string>&)>
potential_matches) = 0;
// Searches for the final checkout amount in the DOM and returns the amount
// back to the browser process.
// See `form_util::ExtractFinalCheckoutAmountFromDom()` for details.
virtual 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) = 0;
private:
friend class AutofillDriverTestApi;
LifecycleState lifecycle_state_ = LifecycleState::kInactive;
#if DCHECK_IS_ON()
LifecycleState previous_lifecycle_state_ = LifecycleState::kInactive;
#endif
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_H_
|