File: iban_save_manager.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 (226 lines) | stat: -rw-r--r-- 9,468 bytes parent folder | download | duplicates (6)
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
// Copyright 2022 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_PAYMENTS_IBAN_SAVE_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_IBAN_SAVE_MANAGER_H_

#include <string>

#include "base/memory/raw_ptr.h"
#include "components/autofill/core/browser/data_model/payments/iban.h"
#include "components/autofill/core/browser/metrics/autofill_metrics.h"
#include "components/autofill/core/browser/payments/payments_autofill_client.h"
#include "components/autofill/core/browser/payments/payments_request_details.h"
#include "components/autofill/core/browser/payments/payments_requests/payments_request.h"
#include "components/autofill/core/browser/strike_databases/payments/iban_save_strike_database.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/signatures.h"

namespace autofill {

// The maximum number of IBANs allowed to be saved to Google Payments from
// Chrome for a single user. Created as a client-side check instead of a
// server-side one to optimize the user experience.
inline constexpr int kMaxNumServerIbans = 99;

class AutofillClient;
class PaymentsDataManager;

// Decides whether an IBAN local save should be offered and handles the workflow
// for local saves.
class IbanSaveManager {
 public:
  // An observer class used by browsertests that gets notified whenever
  // particular actions occur.
  class ObserverForTest {
   public:
    virtual ~ObserverForTest() = default;
    virtual void OnOfferLocalSave() {}
    virtual void OnOfferUploadSave() {}
    virtual void OnAcceptSaveIbanComplete() {}
    virtual void OnDeclineSaveIbanComplete() {}
    virtual void OnReceivedGetUploadDetailsResponse() {}
    virtual void OnSentUploadRequest() {}
    virtual void OnAcceptUploadSaveIbanComplete() {}
    virtual void OnAcceptUploadSaveIbanFailed() {}
  };

  // The type of save that should be offered for the IBAN candidate.
  enum class TypeOfOfferToSave {
    kDoNotOfferToSave = 0,
    kOfferServerSave = 1,
    kOfferLocalSave = 2,
    kMaxValue = kOfferLocalSave
  };

  explicit IbanSaveManager(AutofillClient* client);
  IbanSaveManager(const IbanSaveManager&) = delete;
  IbanSaveManager& operator=(const IbanSaveManager&) = delete;
  virtual ~IbanSaveManager();

  // Return the first half of hashed IBAN value.
  static std::string GetPartialIbanHashString(const std::string& value);

  // Returns true if uploading IBANs to Payments servers is enabled. This
  // requires the appropriate flags and user settings to be set.
  static bool IsIbanUploadEnabled(
      const syncer::SyncService* sync_service,
      AutofillMetrics::PaymentsSigninState signin_state_for_metrics);

  // Checks that all requirements for offering local/server IBAN save are
  // fulfilled, and if they are, offers save. Returns true if a save prompt was
  // likely shown, and false if a save prompt was definitely not shown.
  // Note that on Clank, the save prompt is *only* shown if this returns true.
  // While on desktop if this returns false, the show save prompt will not be
  // popped up but the omnibox icon still will be shown so the user can trigger
  // the save prompt manually.
  [[nodiscard]] bool AttemptToOfferSave(Iban& import_candidate);

  // TODO(b/352643261): Add TestApi for below ForTesting methods.
  void OnUserDidDecideOnLocalSaveForTesting(
      const Iban& import_candidate,
      payments::PaymentsAutofillClient::SaveIbanOfferUserDecision user_decision,
      std::u16string_view nickname = u"") {
    OnUserDidDecideOnLocalSave(import_candidate, user_decision, nickname);
  }

  void OnUserDidDecideOnUploadSaveForTesting(
      const Iban& import_candidate,
      bool show_save_prompt,
      payments::PaymentsAutofillClient::SaveIbanOfferUserDecision user_decision,
      std::u16string_view nickname = u"") {
    OnUserDidDecideOnUploadSave(import_candidate, show_save_prompt,
                                user_decision, nickname);
  }

  // Returns the IbanSaveStrikeDatabase for `client_`.
  IbanSaveStrikeDatabase* GetIbanSaveStrikeDatabaseForTesting() {
    return GetIbanSaveStrikeDatabase();
  }

  void SetEventObserverForTesting(ObserverForTest* observer) {
    observer_for_testing_ = observer;
  }

  // TODO(crbug.com/b/40937065): Iban needs to be immutable reference
  // and pass it by value in this case.
  bool AttemptToOfferLocalSaveForTesting(Iban& iban) {
    return AttemptToOfferLocalSave(iban);
  }

  bool AttemptToOfferUploadSaveForTesting(Iban& iban) {
    return AttemptToOfferUploadSave(iban);
  }

  TypeOfOfferToSave DetermineHowToSaveIbanForTesting(
      const Iban& import_candidate) {
    return DetermineHowToSaveIban(import_candidate);
  }

  void OnDidUploadIbanForTesting(
      const Iban& import_candidate,
      bool show_save_prompt,
      payments::PaymentsAutofillClient::PaymentsRpcResult result) {
    OnDidUploadIban(import_candidate, show_save_prompt, result);
  }

  bool HasContextTokenForTesting() const { return !context_token_.empty(); }

 private:
  // Sets the `record_type` of this given `import_candidate`.
  void UpdateRecordType(Iban& import_candidate);

  // Returns whether the given `import_candidate` should be offered to be saved
  // to GPay, locally, or not at all.
  TypeOfOfferToSave DetermineHowToSaveIban(const Iban& import_candidate) const;

  bool MatchesExistingLocalIban(const Iban& import_candidate) const;
  bool MatchesExistingServerIban(const Iban& import_candidate) const;

  // Returns true if the local save prompt was shown, and false otherwise.
  bool AttemptToOfferLocalSave(Iban& import_candidate);

  // Asynchronously attempts to offer an upload save prompt to the user. Will
  // fall back to a local save prompt if unable to offer server save.
  // Returns true if there will likely be a save prompt shown, and false if we
  // will definitely not be showing one.
  bool AttemptToOfferUploadSave(Iban& import_candidate);

  // Returns the IbanSaveStrikeDatabase for `client_`;
  IbanSaveStrikeDatabase* GetIbanSaveStrikeDatabase();

  // Called once the user makes a decision with respect to the local/server IBAN
  // offer-to-save-prompt. `nickname` is the nickname for the IBAN, which should
  // only be provided in the kAccepted case if the user entered a nickname.
  void OnUserDidDecideOnLocalSave(
      Iban import_candidate,
      payments::PaymentsAutofillClient::SaveIbanOfferUserDecision user_decision,
      std::u16string_view nickname = u"");
  void OnUserDidDecideOnUploadSave(
      Iban import_candidate,
      bool show_save_prompt,
      payments::PaymentsAutofillClient::SaveIbanOfferUserDecision user_decision,
      std::u16string_view nickname = u"");

  // Called when a GetIbanUploadDetails call is completed. `show_save_prompt`
  // being true implies that a save prompt is shown to the user. When false,
  // implies the offer to save will be icon-only on desktop and not shown at all
  // on mobile. The `legal_message` will be used for displaying the Terms of
  // Service and Privacy Notice within the upload-save IBAN bubble view. The
  // `validation_regex` will be used to validate that Google Payments will
  // accept the extracted IBAN value. The `context_token` will serve as the
  // token to initiate the actual Upload IBAN request. The upload flow will be
  // executed only when there is a successful result and the `legal_message` is
  // parsed successfully. In all other cases, local save will be offered if
  // applicable.
  void OnDidGetUploadDetails(
      bool show_save_prompt,
      Iban import_candidate,
      payments::PaymentsAutofillClient::PaymentsRpcResult result,
      const std::u16string& validation_regex,
      const std::u16string& context_token,
      std::unique_ptr<base::Value::Dict> legal_message);

  // Add `risk_data` to `UploadIbanRequestDetails` and send upload IBAN request
  // if the user has accepted the save prompt.
  void OnDidGetUploadRiskData(bool show_save_prompt,
                              const Iban& import_candidate,
                              const std::string& risk_data);

  // Construct `UploadIbanRequestDetails` and send upload IBAN request via
  // PaymentsNetworkInterface.
  void SendUploadRequest(const Iban& import_candidate, bool show_save_prompt);

  // Called when an UploadIban call is completed.
  void OnDidUploadIban(
      const Iban& import_candidate,
      bool show_save_prompt,
      payments::PaymentsAutofillClient::PaymentsRpcResult result);

  PaymentsDataManager& payments_data_manager();
  const PaymentsDataManager& payments_data_manager() const;

  // The associated autofill client.
  const raw_ref<AutofillClient> client_;

  // StrikeDatabase used to check whether to offer to save the IBAN or not.
  std::unique_ptr<IbanSaveStrikeDatabase> iban_save_strike_database_;

  // The context token returned from GetIbanUploadDetails.
  std::u16string context_token_;

  payments::UploadIbanRequestDetails upload_request_details_;

  // `true` if the user has opted to upload save the IBAN to Google Payments.
  bool user_did_accept_upload_prompt_ = false;

  // May be null.
  raw_ptr<ObserverForTest> observer_for_testing_ = nullptr;

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

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_IBAN_SAVE_MANAGER_H_