File: votes_uploader.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (188 lines) | stat: -rw-r--r-- 8,305 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
// Copyright 2024 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_CROWDSOURCING_VOTES_UPLOADER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_CROWDSOURCING_VOTES_UPLOADER_H_

#include <list>
#include <memory>
#include <string>

#include "base/functional/callback.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "base/scoped_observation.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/foundations/autofill_driver_factory.h"
#include "components/autofill/core/common/language_code.h"
#include "components/autofill/core/common/signatures.h"
#include "services/metrics/public/cpp/ukm_source_id.h"

namespace autofill {

class BrowserAutofillManager;

// Determines, buffers, and uploads votes for a form to the crowdsourcing
// server.
//
// A form's vote contains the `FormSignature` and, for each field, a tuple of
// the `FieldSignature` and its `FieldType`, and further metadata. See
// autofill_crowdsourcing_encoding.h for further details.
//
// In VotesUploader, "to vote" also includes "to emit quality metrics" and
// "to potentially display an Autofill survey". For brevity, function names
// don't mention this explicitly.
//
// VotesUploader enqueues votes that are cast before form submission are
// enqueued. New votes for a form signature replace already-enqueued ones for
// that signature. Enqueued votes are flushed by BrowserAutofillManager when it
// dies or is reset. Therefore, votes are called "pending" while they are in the
// queue.
//
//   MaybeStartVoteUploadProcess()◄─────────BrowserAutofillManager
//       │
//       │async
//       │
//       ▼
//   DeterminePossibleFieldTypesForUpload()
//       │
//       │async
//       │
//       ▼
//   OnFieldTypesDetermined()
//       │
//       │       if submission
//       ├──────►────────────────────────────────┐
//       │else                                   │
//       │                                       │
//       ▼                                       │
//   Store PendingVote, which is uploaded when   │
//   - a submission happens in the frame;        │
//   - the frame becomes inactive;               │
//   - the frame is reset;                       │
//   - the frame is deleted;                     │
//   - the queue becomes too large.              │
//                                               │
//   PendingVote::upload_vote                    │
//       │                                       │
//       │                                       │
//       ▼                                       │
//   UploadVote()◄───────────────────────────────┘
//
// Owned by AutofillClient. This is so votes can be determined and uploaded when
// the frame's AutofillDriver and AutofillManager have been destroyed already.
// Since the AutofillCrowdsourcingManager is also owned by AutofillClient and
// since uploading votes is asynchronous, this implies that voting cannot happen
// when the tab is closed.
class VotesUploader : public AutofillDriverFactory::Observer {
 public:
  explicit VotesUploader(AutofillClient* owner);
  VotesUploader(const VotesUploader&) = delete;
  VotesUploader& operator=(const VotesUploader&) = delete;
  ~VotesUploader() override;

  // Will send an upload based on the |form| data and the local Autofill profile
  // data. |observed_submission| is specified if the upload follows an observed
  // submission event. Returns false if the upload couldn't start.
  virtual bool MaybeStartVoteUploadProcess(
      std::unique_ptr<FormStructure> form,
      bool observed_submission,
      LanguageCode current_page_language,
      base::TimeTicks initial_interaction_timestamp,
      const std::u16string& last_unlocked_credit_card_cvc,
      ukm::SourceId ukm_source_id);

 protected:
  // Logs quality metrics, perhaps displays an Autofill survey, and uploads the
  // vote. All these three activities depend on the determined field types.
  //
  // `initial_interaction_timestamp` is the last interaction with the form
  // passed to MaybeStartVoteUploadProcess(). `submission_timestamp` is the time
  // MaybeStartVoteUploadProcess() was called. `observed_submission` indicates
  // whether the upload is a result of an observed submission event.
  // `ukm_source_id` is the form's page's UKM source ID.
  //
  // Virtual and protected for testing.
  virtual void UploadVote(std::unique_ptr<FormStructure> submitted_form,
                          std::vector<AutofillUploadContents> upload_contents,
                          base::TimeTicks initial_interaction_timestamp,
                          base::TimeTicks submission_timestamp,
                          bool observed_submission,
                          const std::u16string& last_unlocked_credit_card_cvc,
                          ukm::SourceId ukm_source_id);

 private:
  friend class VotesUploaderTestApi;

  struct PendingVote;

  // The reply of DeterminePossibleFieldTypesForUpload().
  // Either calls UploadVote() or stores a PendingVote.
  void OnFieldTypesDetermined(
      base::TimeTicks initial_interaction_timestamp,
      base::TimeTicks submission_timestamp,
      bool observed_submission,
      const std::u16string& last_unlocked_credit_card_cvc,
      ukm::SourceId ukm_source_id,
      std::pair<std::unique_ptr<FormStructure>,
                std::vector<AutofillUploadContents>> form_and_upload_contents);

  // Uploads all pending votes for forms from `frame`.
  void FlushPendingVotesForFrame(const LocalFrameToken& frame);

  // Removes the callbacks for the given `form_signature` without calling them.
  void WipePendingVotesForForm(FormSignature form_signature);

  // Uploads the oldest votes if the queue of votes has become too long.
  void FlushOldestPendingVotesIfNecessary();

  // AutofillDriverFactory::Observer:
  void OnAutofillDriverFactoryDestroyed(
      AutofillDriverFactory& factory) override;
  void OnAutofillDriverStateChanged(
      AutofillDriverFactory& factory,
      AutofillDriver& driver,
      AutofillDriver::LifecycleState old_state,
      AutofillDriver::LifecycleState new_state) override;

  // Task runner for asynchronously determining possible field types.
  base::SequencedTaskRunner& task_runner();

  const raw_ref<AutofillClient> client_;

  // List of pending votes. These votes were cast not when a form submission
  // happened but, for example, when a form lost focus ("blur votes").
  //
  // Only one callback is stored per FormSignature. We rely on FormSignatures
  // rather than FormGlobalId to send votes for the various signatures of a form
  // while it evolves (when fields are added or removed). The list of votes is
  // ordered by time of creation: newest elements first. If the list becomes too
  // long, the oldest votes are popped from the list and uploaded.
  //
  // Beware that this (like the other members) must not be accessed from
  // `task_runner_`.
  std::list<PendingVote> pending_votes_;

  // Task runner for DeterminePossibleFieldTypesForUpload(). It is important
  // that this is a *sequenced* task runner for reasons:
  // - Form submission not only uploads the submission vote but also flushes
  //   blur votes. For that to work, the blur votes' OnFieldTypesDetermined()
  //   must be called before the submission vote's OnFieldTypesDetermined().
  // - When a frame becomes inactive or is reset, pending votes should be
  //   flushed -- but first, pending DeterminePossibleFieldTypesForUpload()
  //   calls need to finish.
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  base::ScopedObservation<AutofillDriverFactory,
                          AutofillDriverFactory::Observer>
      driver_observer_{this};

  base::WeakPtrFactory<VotesUploader> weak_ptr_factory_{this};
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_CROWDSOURCING_VOTES_UPLOADER_H_