File: strike_database_integrator_base.h

package info (click to toggle)
chromium 141.0.7390.122-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,246,384 kB
  • sloc: cpp: 35,265,044; ansic: 7,169,920; javascript: 4,250,185; python: 1,460,635; asm: 950,788; xml: 751,771; pascal: 187,972; sh: 89,459; perl: 88,691; objc: 79,953; sql: 53,924; cs: 44,622; fortran: 24,137; makefile: 22,313; tcl: 15,277; php: 14,018; yacc: 8,995; ruby: 7,553; awk: 3,720; lisp: 3,096; lex: 1,330; ada: 727; jsp: 228; sed: 36
file content (207 lines) | stat: -rw-r--r-- 8,788 bytes parent folder | download | duplicates (3)
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
// Copyright 2018 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_STRIKE_DATABASE_STRIKE_DATABASE_INTEGRATOR_BASE_H_
#define COMPONENTS_STRIKE_DATABASE_STRIKE_DATABASE_INTEGRATOR_BASE_H_

#include <stdint.h>

#include <map>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <vector>

#include "base/check.h"
#include "base/functional/function_ref.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "components/strike_database/strike_database_base.h"

namespace autofill {

// Contains virtual functions for per-project implementations of StrikeDatabase
// to interface from, as well as a pointer to StrikeDatabase. This class is
// seperated from StrikeDatabase since we only want StrikeDatabase's cache to
// be loaded once per browser session.
class StrikeDatabaseIntegratorBase {
 public:
  // The StrikeDatabase's decision on whether the feature should be blocked or
  // not, and if so, why.
  enum StrikeDatabaseDecision {
    // The feature should not be blocked.
    kDoNotBlock = 0,
    // Block feature: The maximum strike limit has been reached.
    kMaxStrikeLimitReached = 1,
    // Block feature: Not enough time has passed since the last strike.
    kRequiredDelayNotPassed = 2,
  };

  static constexpr std::string_view kSharedId = "shared_id";

  explicit StrikeDatabaseIntegratorBase(StrikeDatabaseBase* strike_database);
  virtual ~StrikeDatabaseIntegratorBase();

  // Returns the StrikeDatabase's decision on whether a particular feature
  // should be blocked (not offered) for the given `id`.
  StrikeDatabaseDecision GetStrikeDatabaseDecision(std::string_view id) const;

  // Returns the StrikeDatabase's decision on whether a particular feature
  // should be blocked (not offered).
  StrikeDatabaseDecision GetStrikeDatabaseDecision() const;

  // Returns whether a particular feature should be blocked (not offered) for
  // the given `id`. Same as calling `GetStrikeDatabaseDecision`, where a result
  // of `kDoNotBlock` returns false.
  bool ShouldBlockFeature(std::string_view id) const;

  // Returns whether a particular feature should be blocked (not offered). Same
  // as calling `GetStrikeDatabaseDecision`, where a result of `kDoNotBlock`
  // returns false.
  bool ShouldBlockFeature() const;

  // Increments in-memory cache and updates underlying ProtoDatabase.
  int AddStrike(std::string_view id = kSharedId);

  // Increases in-memory cache by `strikes_increase` and updates underlying
  // ProtoDatabase.
  int AddStrikes(int strikes_increase, std::string_view id = kSharedId);

  // Removes an in-memory cache strike, updates last_update_timestamp, and
  // updates underlying ProtoDatabase.
  int RemoveStrike(std::string_view id = kSharedId);

  // Removes `strikes_decrease` in-memory cache strikes, updates
  // `last_update_timestamp`, and updates underlying ProtoDatabase.
  int RemoveStrikes(int strikes_decrease, std::string_view id = kSharedId);

  // Returns strike count from in-memory cache.
  int GetStrikes(std::string_view id = kSharedId) const;

  // Removes all database entries from in-memory cache and underlying
  // ProtoDatabase.
  void ClearStrikes(std::string_view id = kSharedId);

  // Removes all database entries from in-memory cache and underlying
  // ProtoDatabase for the whole project.
  void ClearAllStrikes();

  // Count strike entries for this project.
  size_t CountEntries() const;

 protected:
  // Runs a cleanup routine to remove the stored strike elements with the oldest
  // update timestamps when `NumberOfEntriesExceedsLimits()`. The number of
  // elements should be reduced to `GetMaximumEntriesAfterCleanup()`.
  void LimitNumberOfStoredEntries();

  // Returns true if the number of stored entries exceeds the limit.
  bool NumberOfEntriesExceedsLimits() const;

  // Removes one strike for each key where it has been longer than
  // GetExpiryTimeMicros() since `last_update_timestamp`.
  void RemoveExpiredStrikes();

  // Removes all database entries for which `id_map(ID)` is in `ids_to_delete`.
  void ClearStrikesByIdMatching(
      const std::set<std::string>& ids_to_delete,
      base::FunctionRef<std::string(const std::string&)> id_map);

  // Removes all database entries from in-memory for which `id_map(ID)` is in
  // `ids_to_delete` and were added between `delete_begin` and `delete_end`.
  void ClearStrikesByIdMatchingAndTime(
      const std::set<std::string>& ids_to_delete,
      base::Time delete_begin,
      base::Time delete_end,
      base::FunctionRef<std::string(const std::string&)> id_map);

  // Removes all database entries from in-memory cache and underlying
  // ProtoDatabase for keys in `keys`.
  void ClearStrikesForKeys(const std::vector<std::string>& keys);

  // Get a readonly reference to the cache.
  const std::map<std::string, StrikeData>& GetStrikeCache() const {
    return strike_database_->GetStrikeCache();
  }

  // Returns the id the key was built from with `GetKey(id)`.
  std::string_view GetIdFromKey(std::string_view key) const;

  // Returns the age of a strike entry.
  static base::TimeDelta GetEntryAge(const StrikeData& strike_data);

 private:
  FRIEND_TEST_ALL_PREFIXES(ChromeBrowsingDataRemoverDelegateTest,
                           StrikeDatabaseEmptyOnAutofillRemoveEverything);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           ClearStrikesForKeys);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           GetKeyForStrikeDatabaseIntegratorUniqueIdTest);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           IdFromKey);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           NonExpiringStrikesDoNotExpire);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           RemoveExpiredStrikesOnlyConsidersCurrentIntegrator);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           RemoveExpiredStrikesTest);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           RemoveExpiredStrikesTestLogsUMA);
  FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
                           RemoveExpiredStrikesUniqueIdTest);
  friend class FakeCreditCardServer;
  friend class StrikeDatabaseTest;
  friend class StrikeDatabaseTester;

  const raw_ptr<StrikeDatabaseBase> strike_database_;

  // For projects in which strikes don't have unique identifiers, the
  // id suffix is set to `kSharedId`. This makes sure that projects requiring
  // unique IDs always specify `id` instead of relying on the default shared
  // value, while projects where unique IDs are unnecessary always fall back to
  // the default shared value.
  void CheckIdUniqueness(std::string_view id) const {
    DCHECK(UniqueIdsRequired() == (id != kSharedId));
  }

  // Generates key based on project-specific string identifier.
  std::string GetKey(std::string_view id) const;

  // Returns the maximum number of entries that should be stored for this
  // project prefix. std::nullopt means that there is no limit.
  virtual std::optional<size_t> GetMaximumEntries() const;

  // Returns the maximum number of entries that should remain after a cleanup.
  // This number should be smaller then `GetMaximumEntries()` to create some
  // headroom. std::nullopt means that `GetMaximumEntries()` should be used.
  virtual std::optional<size_t> GetMaximumEntriesAfterCleanup() const;

  // Returns a prefix unique to each project, which will be used to create
  // database key.
  virtual std::string GetProjectPrefix() const = 0;

  // Returns the maximum number of strikes after which the project's Autofill
  // opportunity stops being offered.
  virtual int GetMaxStrikesLimit() const = 0;

  // Returns the time delta after which the most recent strike should expire.
  // If the Optional is empty, then strikes don't expire.
  virtual std::optional<base::TimeDelta> GetExpiryTimeDelta() const = 0;

  // Returns whether or not a unique string identifier is required for every
  // strike in this project.
  virtual bool UniqueIdsRequired() const = 0;

  // Returns the time delta to wait for before prompting the feature again. If
  // the Optional is empty, then there is no required delay during which the
  // feature is blocked.
  virtual std::optional<base::TimeDelta> GetRequiredDelaySinceLastStrike()
      const;
};

}  // namespace autofill

#endif  // COMPONENTS_STRIKE_DATABASE_STRIKE_DATABASE_INTEGRATOR_BASE_H_