chromium/components/autofill/content/renderer/autofill_agent.cc

// 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.

#include "components/autofill/content/renderer/autofill_agent.h"

#include <stddef.h>

#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

#include "base/check_deref.h"
#include "base/containers/contains.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/i18n/case_conversion.h"
#include "base/memory/raw_ref.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/content/renderer/a11y_utils.h"
#include "components/autofill/content/renderer/form_autofill_issues.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/form_cache.h"
#include "components/autofill/content/renderer/form_tracker.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/autofill/content/renderer/password_generation_agent.h"
#include "components/autofill/content/renderer/suggestion_properties.h"
#include "components/autofill/core/common/aliases.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_data_predictions.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "components/autofill/core/common/unique_ids.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "content/public/renderer/render_frame.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/web/web_autofill_state.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_form_control_element.h"
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_form_related_change_type.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_range.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes.h"

WebAutofillClient;
WebAutofillState;
WebDocument;
WebElement;
WebFormControlElement;
WebFormElement;
WebFormRelatedChangeType;
WebFrame;
WebInputElement;
WebKeyboardEvent;
WebLocalFrame;
WebNode;
WebRange;
WebString;

namespace autofill {

namespace {

using enum CallTimerState::CallSite;

constexpr char kSubmissionSourceHistogram[] =;

// Time to wait in ms to ensure that only a single select or datalist change
// will be acted upon, instead of multiple in close succession (debounce time).
constexpr base::TimeDelta kWaitTimeForOptionsChanges =;

FormAndField;

// TODO(crbug.com/40753022): Move this to the browser process.
blink::FormElementPiiType MapTypePredictionToFormElementPiiType(
    std::string_view type) {}

std::string GetButtonTitlesString(const ButtonTitleList& titles_list) {}

// For each field in the |form|, if |attach_predictions_to_dom| is true, sets
// the title to include the field's heuristic type, server type, and
// signature; as well as the form's signature and the experiment id for the
// server predictions.
//
// It also calls WebFormControlElement::SetFormElementPiiType() for every form
// control (which is actually unrelated to this function.)
//
// TODO(crbug.com/40753022): FormDataPredictions should be sent to the renderer
// process and this function should be called only if
// chrome://flags/#show-autofill-type-predictions is enabled. For this, the
// PII metric related to WebFormControlElement::SetFormElementPiiType() must be
// moved to the browser process.
bool ShowPredictions(const WebDocument& document,
                     const FormDataPredictions& form,
                     bool attach_predictions_to_dom) {}

// Compare the values before and after JavaScript value changes after:
// - Converting to lower case.
// - Removing special characters
// - Removing whitespaces.
// If values are equal after this comparison, we claim that the modification
// was not big enough to drop the autofilled state of the field.
bool JavaScriptOnlyReformattedValue(std::u16string old_value,
                                    std::u16string new_value) {}

gfx::Rect GetCaretBounds(content::RenderFrame& frame) {}

}  // namespace

// During prerendering, we do not want the renderer to send messages to the
// corresponding driver. Since we use a channel associated interface, we still
// need to set up the mojo connection as before (i.e., we can't defer binding
// the interface). Instead, we enqueue our messages here as post-activation
// tasks. See post-prerendering activation steps here:
// https://wicg.github.io/nav-speculation/prerendering.html#prerendering-bcs-subsection
class AutofillAgent::DeferringAutofillDriver : public mojom::AutofillDriver {};

AutofillAgent::FocusStateNotifier::FocusStateNotifier(AutofillAgent* agent)
    :{}

AutofillAgent::FocusStateNotifier::~FocusStateNotifier() = default;

void AutofillAgent::FocusStateNotifier::FocusedInputChanged(
    const WebNode& node) {}

void AutofillAgent::FocusStateNotifier::ResetFocus() {}

mojom::FocusedFieldType AutofillAgent::FocusStateNotifier::GetFieldType(
    const WebFormControlElement& node) {}

void AutofillAgent::FocusStateNotifier::NotifyIfChanged(
    mojom::FocusedFieldType new_focused_field_type,
    FieldRendererId new_focused_field_id) {}

AutofillAgent::AutofillAgent(
    content::RenderFrame* render_frame,
    Config config,
    std::unique_ptr<PasswordAutofillAgent> password_autofill_agent,
    std::unique_ptr<PasswordGenerationAgent> password_generation_agent,
    blink::AssociatedInterfaceRegistry* registry)
    :{}

// The destructor is not guaranteed to be called. Destruction happens (only)
// through the OnDestruct() event, which posts a task to delete this object.
// The process may be killed before this deletion can happen.
AutofillAgent::~AutofillAgent() {}

WebDocument AutofillAgent::GetDocument() const {}

void AutofillAgent::BindPendingReceiver(
    mojo::PendingAssociatedReceiver<mojom::AutofillAgent> pending_receiver) {}

void AutofillAgent::DidCommitProvisionalLoad(ui::PageTransition transition) {}

void AutofillAgent::DidCreateDocumentElement() {}

void AutofillAgent::Reset() {}

void AutofillAgent::DidDispatchDOMContentLoadedEvent() {}

void AutofillAgent::DidChangeScrollOffset() {}

void AutofillAgent::DidChangeScrollOffsetImpl(FieldRendererId element_id) {}

CallTimerState AutofillAgent::GetCallTimerState(
    CallTimerState::CallSite call_site) const {}

void AutofillAgent::FocusedElementChanged(
    const WebElement& new_focused_element) {}

void AutofillAgent::ObserveCaret(WebElement element) {}

void AutofillAgent::HandleCaretMovedInFormField(WebElement element,
                                                blink::WebDOMEvent) {}

// AutofillAgent is deleted asynchronously because OnDestruct() may be
// triggered by JavaScript, which in turn may be triggered by AutofillAgent.
void AutofillAgent::OnDestruct() {}

void AutofillAgent::AccessibilityModeChanged(const ui::AXMode& mode) {}

void AutofillAgent::FireHostSubmitEvents(const FormData& form_data,
                                         bool known_success,
                                         mojom::SubmissionSource source) {}

void AutofillAgent::TextFieldCleared(const WebFormControlElement& element) {}

void AutofillAgent::TextFieldDidEndEditing(const WebInputElement& element) {}

void AutofillAgent::TextFieldDidChange(const WebFormControlElement& element) {}

void AutofillAgent::ContentEditableDidChange(const WebElement& element) {}

void AutofillAgent::OnTextFieldDidChange(const WebFormControlElement& element) {}

void AutofillAgent::TextFieldDidReceiveKeyDown(const WebInputElement& element,
                                               const WebKeyboardEvent& event) {}

void AutofillAgent::OpenTextDataListChooser(const WebInputElement& element) {}

// Notifies the AutofillDriver about changes in the <datalist> options in
// batches.
//
// A batch ends if no event occurred for `kWaitTimeForOptionsChanges`.
// For a given batch, the AutofillDriver is informed only about the last field.
// That is, if within one batch the options of different fields changed, all but
// one of these events will be lost.
void AutofillAgent::DataListOptionsChanged(const WebInputElement& element) {}

void AutofillAgent::BatchDataListOptionChange(FieldRendererId element_id) {}

void AutofillAgent::UserGestureObserved() {}

// mojom::AutofillAgent:
void AutofillAgent::ApplyFieldsAction(
    mojom::FormActionType action_type,
    mojom::ActionPersistence action_persistence,
    const std::vector<FormFieldData::FillData>& fields) {}

void AutofillAgent::FieldTypePredictionsAvailable(
    const std::vector<FormDataPredictions>& forms) {}

void AutofillAgent::ClearPreviewedForm() {}

void AutofillAgent::TriggerSuggestions(
    FieldRendererId field_id,
    AutofillSuggestionTriggerSource trigger_source) {}

void AutofillAgent::ApplyFieldAction(
    mojom::FieldActionType action_type,
    mojom::ActionPersistence action_persistence,
    FieldRendererId field_id,
    const std::u16string& value) {}

void AutofillAgent::SetSuggestionAvailability(
    FieldRendererId field_id,
    mojom::AutofillSuggestionAvailability suggestion_availability) {}

void AutofillAgent::AcceptDataListSuggestion(
    FieldRendererId field_id,
    const std::u16string& suggested_value) {}

void AutofillAgent::PreviewPasswordSuggestion(const std::u16string& username,
                                              const std::u16string& password) {}

void AutofillAgent::PreviewPasswordGenerationSuggestion(
    const std::u16string& password) {}

void AutofillAgent::ShowSuggestions(
    const WebFormControlElement& element,
    AutofillSuggestionTriggerSource trigger_source) {}

void AutofillAgent::ShowSuggestionsForContentEditable(
    const blink::WebElement& element,
    AutofillSuggestionTriggerSource trigger_source) {}

void AutofillAgent::GetPotentialLastFourCombinationsForStandaloneCvc(
    base::OnceCallback<void(const std::vector<std::string>&)>
        potential_matches) {}

void AutofillAgent::QueryAutofillSuggestions(
    const WebFormControlElement& element,
    AutofillSuggestionTriggerSource trigger_source) {}

void AutofillAgent::DoFillFieldWithValue(std::u16string_view value,
                                         WebFormControlElement& element,
                                         WebAutofillState autofill_state) {}

void AutofillAgent::TriggerFormExtraction() {}

void AutofillAgent::TriggerFormExtractionWithResponse(
    base::OnceCallback<void(bool)> callback) {}

void AutofillAgent::ExtractForm(
    FormRendererId form_id,
    base::OnceCallback<void(const std::optional<FormData>&)> callback) {}

void AutofillAgent::EmitFormIssuesToDevtools() {}

void AutofillAgent::ExtractForms(base::OneShotTimer& timer,
                                 base::OnceCallback<void(bool)> callback) {}

void AutofillAgent::ExtractFormsAndNotifyPasswordAutofillAgent(
    base::OneShotTimer& timer) {}

void AutofillAgent::ExtractFormsUnthrottled(
    base::OnceCallback<void(bool)> callback) {}

void AutofillAgent::HidePopup() {}

void AutofillAgent::DidChangeFormRelatedElementDynamically(
    const WebElement& element,
    WebFormRelatedChangeType form_related_change) {}

void AutofillAgent::DidCompleteFocusChangeInFrame() {}

void AutofillAgent::DidReceiveLeftMouseDownOrGestureTapInNode(
    const WebNode& node) {}

void AutofillAgent::SelectControlDidChange(
    const WebFormControlElement& element) {}

// Notifies the AutofillDriver about changes in the <select> or <selectlist>
// options in batches.
//
// A batch ends if no event occurred for `kWaitTimeForOptionsChanges`. For a
// given batch, the AutofillDriver is informed only about the last FormData.
// That is, if within one batch the options of different forms changed, all but
// one of these events will be lost.
void AutofillAgent::SelectOrSelectListFieldOptionsChanged(
    const WebFormControlElement& element) {}

void AutofillAgent::BatchSelectOrSelectListOptionChange(
    FieldRendererId element_id) {}

bool AutofillAgent::ShouldSuppressKeyboard(
    const WebFormControlElement& element) {}

void AutofillAgent::FormElementReset(const WebFormElement& form) {}

void AutofillAgent::PasswordFieldReset(const WebInputElement& element) {}

bool AutofillAgent::IsPrerendering() const {}

void AutofillAgent::HandleFocusChangeComplete(
    bool focused_node_was_last_clicked) {}

void AutofillAgent::SendFocusedInputChangedNotificationToBrowser(
    const WebElement& node) {}

void AutofillAgent::AjaxSucceeded() {}

void AutofillAgent::JavaScriptChangedValue(WebFormControlElement element,
                                           const WebString& old_value,
                                           bool was_autofilled) {}

void AutofillAgent::OnProvisionallySaveForm(
    const WebFormElement& form_element,
    const WebFormControlElement& element,
    SaveFormReason source) {}

void AutofillAgent::OnProbablyFormSubmitted() {}

void AutofillAgent::OnFormSubmitted(const WebFormElement& form) {}

void AutofillAgent::OnInferredFormSubmission(mojom::SubmissionSource source) {}

void AutofillAgent::AddFormObserver(Observer* observer) {}

void AutofillAgent::RemoveFormObserver(Observer* observer) {}

void AutofillAgent::TrackAutofilledElement(
    const WebFormControlElement& element) {}

void AutofillAgent::UpdateStateForTextChange(
    const WebFormControlElement& element,
    FieldPropertiesFlags flag) {}

std::optional<FormData> AutofillAgent::GetSubmittedForm() const {}

void AutofillAgent::ResetLastInteractedElements() {}

void AutofillAgent::UpdateLastInteractedElement(
    absl::variant<FormRendererId, FieldRendererId> element_id) {}

void AutofillAgent::OnFormNoLongerSubmittable() {}

DenseSet<form_util::ExtractOption> AutofillAgent::MaybeExtractDatalist(
    DenseSet<form_util::ExtractOption> extract_options) {}

mojom::AutofillDriver* AutofillAgent::unsafe_autofill_driver() {}

mojom::PasswordManagerDriver& AutofillAgent::GetPasswordManagerDriver() {}

}  // namespace autofill