File: password_generation_agent.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 (206 lines) | stat: -rw-r--r-- 8,755 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
// 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_CONTENT_RENDERER_PASSWORD_GENERATION_AGENT_H_
#define COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_GENERATION_AGENT_H_

#include <stddef.h>

#include <map>
#include <memory>
#include <utility>

#include "base/memory/raw_ptr.h"
#include "components/autofill/content/common/mojom/autofill_agent.mojom.h"
#include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
#include "components/autofill/core/common/unique_ids.h"
#include "content/public/renderer/render_frame_observer.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/web/web_input_element.h"

namespace autofill {

class PasswordAutofillAgent;
class SynchronousFormCache;

// This class is responsible for controlling communication for password
// generation between the browser (which shows the popup and generates
// passwords) and WebKit (shows the generation icon in the password field).
class PasswordGenerationAgent : public content::RenderFrameObserver,
                                public mojom::PasswordGenerationAgent {
 public:
  // Maximum number of characters typed by user while the generation is still
  // offered. When the (kMaximumCharsForGenerationOffer + 1)-th character is
  // typed, the generation becomes unavailable.
  static const size_t kMaximumCharsForGenerationOffer = 5;

  // User can edit the generated password. If the length falls below this value,
  // the password is no longer considered generated.
  static const size_t kMinimumLengthForEditedPassword = 4;

  PasswordGenerationAgent(content::RenderFrame* render_frame,
                          PasswordAutofillAgent* password_agent,
                          blink::AssociatedInterfaceRegistry* registry);

  PasswordGenerationAgent(const PasswordGenerationAgent&) = delete;
  PasswordGenerationAgent& operator=(const PasswordGenerationAgent&) = delete;

  ~PasswordGenerationAgent() override;

  void BindPendingReceiver(
      mojo::PendingAssociatedReceiver<mojom::PasswordGenerationAgent>
          pending_receiver);

  // mojom::PasswordGenerationAgent:
  void GeneratedPasswordAccepted(const std::u16string& password) override;
  void GeneratedPasswordRejected() override;
  void FoundFormEligibleForGeneration(
      const PasswordFormGenerationData& form) override;
  // Sets |generation_element_| to the focused password field and responds back
  // if the generation was triggered successfully.
  void TriggeredGeneratePassword(
      TriggeredGeneratePasswordCallback callback) override;
  void FocusNextFieldAfterPasswords() override;

  // Returns true if the field being changed is one where a generated password
  // is being offered. Updates the state of the popup if necessary. `form_cache`
  // can be used to optimize form extractions occurring synchronously after this
  // function call.
  bool TextDidChangeInTextField(const blink::WebInputElement& element,
                                const SynchronousFormCache& form_cache);

  // Returns true if the newly focused node caused the generation UI to show.
  bool ShowPasswordGenerationSuggestions(
      const blink::WebInputElement& element,
      const SynchronousFormCache& form_cache);

  // Event forwarded by AutofillAgent from WebAutofillClient, informing that
  // the text field editing has ended, which means that the field is not
  // focused anymore. This is required for Android, where moving focus
  // to a non-focusable element doesn't result in |FocusedNodeHasChanged|
  // being called.
  void DidEndTextFieldEditing(const blink::WebInputElement& element);

  // Event forwarded by AutofillAgent from WebAutofillClient, informing that the
  // text field was cleared. For password fields this means that they are no
  // longer generated and should be masked.
  void TextFieldCleared(const blink::WebInputElement& element);

  // Called right before PasswordAutofillAgent filled |password_element|.
  void OnFieldAutofilled(const blink::WebInputElement& password_element);

  // Returns true iff the currently handled 'blur' event is fake and should be
  // ignored.
  bool ShouldIgnoreBlur() const;

#if defined(UNIT_TEST)
  // This method requests the mojom::PasswordManagerClient which binds
  // requests the binding if it wasn't bound yet.
  void RequestPasswordManagerClientForTesting() {
    GetPasswordGenerationDriver();
  }
#endif

  bool IsPrerendering() const;

  // Previews the generation suggestion for the current generation element.
  void PreviewGenerationSuggestion(const std::u16string& password);

  // Clears the previewed field if it was previously previewed.
  void ClearPreviewedForm();

 private:
  class DeferringPasswordGenerationDriver;

  // Contains information about generation status for an element for the
  // lifetime of the possible interaction.
  struct GenerationItemInfo;

  // RenderFrameObserver:
  void DidCommitProvisionalLoad(ui::PageTransition transition) override;
  void DidChangeScrollOffset() override;
  void OnDestruct() override;

  mojom::PasswordManagerDriver& GetPasswordManagerDriver();

  // Callers should not store the returned value longer than a function scope.
  mojom::PasswordGenerationDriver& GetPasswordGenerationDriver();

  // Helper function which takes care of the form processing and collecting the
  // information which is required to show the generation popup. Returns true if
  // all required information is collected.
  bool SetUpTriggeredGeneration();

  // This is called whenever automatic generation could be offered, and returns
  // true if generation was offered.
  // If manual generation was already requested, automatic generation is not
  // offered.
  bool MaybeOfferAutomaticGeneration();

  // Signals the browser that it should offer automatic password generation
  // as a result of the user focusing a password field eligible for generation.
  void AutomaticGenerationAvailable();

#if !BUILDFLAG(IS_ANDROID)
  // Show UI for editing a generated password at |generation_element_|.
  void ShowEditingPopup(const SynchronousFormCache& form_cache);
#endif  // !BUILDFLAG(IS_ANDROID)

  // Stops treating a password as generated.
  void PasswordNoLongerGenerated();

  // Creates |current_generation_item_| for |element| if |element| is a
  // generation enabled element. If |current_generation_item_| is already
  // created for |element| it is not recreated.
  void MaybeCreateCurrentGenerationItem(
      blink::WebInputElement element,
      FieldRendererId confirmation_password_renderer_id,
      const SynchronousFormCache& form_cache);

  void LogMessage(SavePasswordProgressLogger::StringID message_id);
  void LogBoolean(SavePasswordProgressLogger::StringID message_id,
                  bool truth_value);

  // Creates a FormData to presave a generated password. It copies behavior
  // of CreateFromDataFromWebForm/FromUnownedInputElements. If a form
  // creating is failed, returns an empty unique_ptr. `form_cache` can be used
  // to optimize form extractions occurring synchronously after this function
  // call.
  std::optional<FormData> CreateFormDataToPresave(
      const SynchronousFormCache& form_cache);

  // Contains the current element where generation is offered at the moment. It
  // can be either automatic or manual password generation.
  std::unique_ptr<GenerationItemInfo> current_generation_item_;

  // Contains correspondence between generation enabled element and data for
  // generation.
  std::map<FieldRendererId, PasswordFormGenerationData>
      generation_enabled_fields_;

  // True iff the generation element should be marked with special HTML
  // attribute (only for experimental purposes).
  const bool mark_generation_element_;

  // Unowned pointer. Used to notify PassowrdAutofillAgent when values
  // in password fields are updated.
  const raw_ptr<PasswordAutofillAgent> password_agent_;

  mojo::AssociatedRemote<mojom::PasswordGenerationDriver>
      password_generation_client_;

  // Used for deferring messages while prerendering.
  std::unique_ptr<DeferringPasswordGenerationDriver>
      deferring_password_generation_driver_;

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

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_GENERATION_AGENT_H_