File: search_engine_choice_utils.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 (338 lines) | stat: -rw-r--r-- 13,450 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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// Copyright 2023 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_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_UTILS_H_
#define COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_UTILS_H_

#include <optional>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/types/expected.h"
#include "base/version.h"
#include "build/build_config.h"
#include "components/country_codes/country_codes.h"
#include "components/search_engines/choice_made_location.h"
#include "components/search_engines/search_engine_type.h"
#include "components/search_engines/template_url.h"

class PrefService;
class SearchTermsData;
struct TemplateURLData;

namespace base {
class Time;
}  // namespace base

namespace search_engines {

inline constexpr char
    kSearchEngineChoiceScreenProfileInitConditionsHistogram[] =
        "Search.ChoiceScreenProfileInitConditions";
inline constexpr char kSearchEngineChoiceScreenNavigationConditionsHistogram[] =
    "Search.ChoiceScreenNavigationConditions";
inline constexpr char kSearchEngineChoiceScreenEventsHistogram[] =
    "Search.ChoiceScreenEvents";
inline constexpr char
    kSearchEngineChoiceScreenDefaultSearchEngineTypeHistogram[] =
        "Search.ChoiceScreenDefaultSearchEngineType";
inline constexpr char
    kSearchEngineChoiceScreenDefaultSearchEngineType2Histogram[] =
        "Search.ChoiceScreenDefaultSearchEngineType2";
inline constexpr char kSearchEngineChoiceScreenSelectedEngineIndexHistogram[] =
    "Search.ChoiceScreenSelectedEngineIndex";
inline constexpr char
    kSearchEngineChoiceScreenShowedEngineAtHistogramPattern[] =
        "Search.ChoiceScreenShowedEngineAt.Index%d";
inline constexpr char
    kSearchEngineChoiceScreenShowedEngineAtCountryMismatchHistogram[] =
        "Search.ChoiceScreenShowedEngineAt.CountryMismatch";
inline constexpr char kSearchEngineChoiceWipeReasonHistogram[] =
    "Search.ChoiceWipeReason";
inline constexpr char kSearchEngineChoiceRepromptHistogram[] =
    "Search.ChoiceReprompt";
inline constexpr char kSearchEngineChoiceRepromptWildcardHistogram[] =
    "Search.ChoiceReprompt.Wildcard";
inline constexpr char kSearchEngineChoiceRepromptSpecificCountryHistogram[] =
    "Search.ChoiceReprompt.SpecificCountry";
inline constexpr char kSearchEngineChoiceCompletedOnMonthHistogram[] =
    "Search.ChoiceCompletedOnMonth.OnProfileLoad2";

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// LINT.IfChange(SearchEngineChoiceScreenConditions)
enum class SearchEngineChoiceScreenConditions {
  // The user has a custom search engine set.
  kHasCustomSearchEngine = 0,
  // The user has a search provider list override.
  kSearchProviderOverride = 1,
  // The user is not in the regional scope.
  kNotInRegionalScope = 2,
  // A policy sets the default search engine or disables search altogether.
  kControlledByPolicy = 3,
  // The profile is out of scope.
  kProfileOutOfScope = 4,
  // An extension controls the default search engine.
  kExtensionControlled = 5,
  // The user is eligible to see the screen at the next opportunity.
  kEligible = 6,
  // The choice has already been completed.
  kAlreadyCompleted = 7,
  // The browser type is unsupported.
  kUnsupportedBrowserType = 8,
  // The feature can't run, it is disabled by local or remote configuration.
  kFeatureSuppressed = 9,
  // Some other dialog is showing and interfering with the choice one.
  kSuppressedByOtherDialog = 10,
  // The browser window can't fit the dialog's smallest variant.
  kBrowserWindowTooSmall = 11,
  // The user has a distribution custom search engine set as default.
  kHasDistributionCustomSearchEngine = 12,
  // The user has an unknown (which we assume is because it has been removed)
  // prepopulated search engine set as default.
  kHasRemovedPrepopulatedSearchEngine = 13,
  // The user does not have Google as the default search engine.
  kHasNonGoogleSearchEngine = 14,
  // The user is eligible, the app could have presented a dialog but the
  // application was started via an external intent and the dialog skipped.
  kAppStartedByExternalIntent = 15,
  // The browser attempting to show the choice screen in a dialog is already
  // showing a choice screen.
  kAlreadyBeingShown = 16,
  // The user made the choice in the guest session and opted to save it across
  // guest sessions.
  kUsingPersistedGuestSessionChoice = 17,

  kMaxValue = kUsingPersistedGuestSessionChoice,
};
// LINT.ThenChange(/tools/metrics/histograms/metadata/search/enums.xml:SearchEngineChoiceScreenConditions)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// LINT.IfChange(SearchEngineChoiceScreenEvents)
enum class SearchEngineChoiceScreenEvents {
  kUnknown = 0,
  // The non-FRE version of the choice screen was displayed.
  kChoiceScreenWasDisplayed = 1,
  // The FRE-specific flavor of the screen was displayed.
  kFreChoiceScreenWasDisplayed = 2,
  // The user clicked/tapped `Set as default` on the non-FRE screen.
  kDefaultWasSet = 3,
  // The user clicked/tapped `Set as default` on the
  // FRE-specific screen.
  kFreDefaultWasSet = 4,
  // The "Learn more" screen was displayed on the non-FRE screen.
  kLearnMoreWasDisplayed = 5,
  // The "Learn more" screen was displayed on the FRE-specific screen.
  kFreLearnMoreWasDisplayed = 6,
  // The profile creation specific flavor of the screen was displayed.
  kProfileCreationChoiceScreenWasDisplayed = 7,
  // The user clicked `Set as default` on the profile creation specific screen.
  kProfileCreationDefaultWasSet = 8,
  // The "Learn more" screen was displayed on the profile creation specific
  // screen.
  kProfileCreationLearnMoreDisplayed = 9,
  // The "More" button was clicked on the modal dialog.
  kMoreButtonClicked = 10,
  // The "More" button was clicked on the FRE-specific screen.
  kFreMoreButtonClicked = 11,
  // The "More" button was clicked on the profile creation specific screen.
  kProfileCreationMoreButtonClicked = 12,
  kMaxValue = kProfileCreationMoreButtonClicked,
};
// LINT.ThenChange(/tools/metrics/histograms/metadata/search/enums.xml:SearchEngineChoiceScreenEvents)

// The cause for wiping the search engine choice preferences. Only used for
// metrics.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class SearchEngineChoiceWipeReason {
  kProfileWipe = 0,
  kMissingMetadataVersion = 1,
  kInvalidMetadataVersion = 2,
  kFinchBasedReprompt = 3,
  kCommandLineFlag = 4,
  kDeviceRestored = 5,
  kInvalidMetadata = 6,
  kMissingDefaultSearchEngine = 7,

  kMaxValue = kMissingDefaultSearchEngine,
};

// Exposed for testing.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class RepromptResult {
  // Reprompt.
  kReprompt = 0,

  // Cases below do not reprompt.
  //
  // Wrong JSON syntax.
  kInvalidDictionary = 1,
  // There was no applicable key (specific country or wildcard).
  kNoDictionaryKey = 2,
  // The reprompt version could not be parsed.
  kInvalidVersion = 3,
  // Chrome older than the requested version, reprompting would not make the
  // version recent enough.
  kChromeTooOld = 4,
  // The choice was made recently enough.
  kRecentChoice = 5,
  // Do not reprompt the users.
  kNoReprompt = 6,

  kMaxValue = kNoReprompt,
};

struct ChoiceScreenDisplayState {
 public:
  ChoiceScreenDisplayState(
      std::vector<SearchEngineType> search_engines,
      country_codes::CountryId country_id,
      std::optional<int> selected_engine_index = std::nullopt);
  ChoiceScreenDisplayState(const ChoiceScreenDisplayState& other);
  ~ChoiceScreenDisplayState();

  base::Value::Dict ToDict() const;
  static std::optional<ChoiceScreenDisplayState> FromDict(
      const base::Value::Dict& dict);

  // `SearchEngineType`s of the search engines displayed on the choice screen,
  // listed in an order matching their display order.
  // Note that the screen shows items from a list specific for each EEA
  // country, and these items are randomized before they are presented.
  const std::vector<SearchEngineType> search_engines;

  // Index of the selected search engine. Obviously can't be populated until
  // the choice has been made, so instances describing purely the state at the
  // time of the display won't have a value, while the ones describing it at
  // the moment of the choice will have it populated.
  std::optional<int> selected_engine_index;

  // The country used when generating the list. It should be the country
  // used to determine the set of search engines to show for the current
  // profile.
  const country_codes::CountryId country_id;
};

// Contains basic information about the search engine choice screen, notably
// the list of actual search engines to show, and other metadata associated
// with how it was determined.
class ChoiceScreenData {
 public:
  ChoiceScreenData(TemplateURL::OwnedTemplateURLVector owned_template_urls,
                   country_codes::CountryId country_id,
                   const SearchTermsData& search_terms_data);

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

  ~ChoiceScreenData();

  const TemplateURL::OwnedTemplateURLVector& search_engines() const {
    return search_engines_;
  }

  const ChoiceScreenDisplayState& display_state() const {
    return display_state_;
  }

 private:
  const TemplateURL::OwnedTemplateURLVector search_engines_;

  const ChoiceScreenDisplayState display_state_;
};

// Records the specified choice screen condition at profile initialization.
void RecordChoiceScreenProfileInitCondition(
    SearchEngineChoiceScreenConditions event);

// Records the specified choice screen condition for relevant navigations.
void RecordChoiceScreenNavigationCondition(
    SearchEngineChoiceScreenConditions condition);

// Records the specified choice screen event.
void RecordChoiceScreenEvent(SearchEngineChoiceScreenEvents event);

// Records the type of the default search engine that was chosen by the user
// in the search engine choice screen or in the settings page.
void RecordChoiceScreenDefaultSearchProviderType(
    SearchEngineType engine_type,
    ChoiceMadeLocation choice_location);

// Records the index of the search engine that was chosen by the user as it was
// displayed on the choice screen.
void RecordChoiceScreenSelectedIndex(int selected_engine_index);

// Records the positions of search engines in a choice screen. Intended to be
// recorded when a choice happens, so that we emit it at most once per choice
// "scope". For more info, please see
// http://go/chrome-choice-screen-positions-histogram-design (Google-internal).
// Don't call this directly. Instead, go through
// `SearchEngineChoiceService::MaybeRecordChoiceScreenDisplayState()`.
void RecordChoiceScreenPositions(
    const std::vector<SearchEngineType>& displayed_search_engines);

// Records whether `RecordChoiceScreenPositions()` had to be skipped due to
// a mismatch between the Variations/UMA country and the profile/choice
// country. If `has_mismatch` is `true`, we record that it was "skipped", or
// that it was "not skipped" otherwise.
void RecordChoiceScreenPositionsCountryMismatch(bool has_mismatch);

// For debugging purposes, record the ID of the current default search engine
// that does not exist in the prepopulated search providers data.
void RecordUnexpectedSearchProvider(const TemplateURLData& data);

// Clears the search engine choice prefs, such as the timestamp and the Chrome
// version, to ensure the choice screen is shown again.
void WipeSearchEngineChoicePrefs(PrefService& profile_prefs,
                                 SearchEngineChoiceWipeReason reason);

struct ChoiceCompletionMetadata {
  enum class ParseError {
    kAbsent,
    kMissingVersion,
    kInvalidVersion,
    kMissingTimestamp,
    kNullTimestamp,
  };

  base::Time timestamp;
  base::Version version;
};

base::expected<ChoiceCompletionMetadata, ChoiceCompletionMetadata::ParseError>
GetChoiceCompletionMetadata(const PrefService& prefs);

void SetChoiceCompletionMetadata(PrefService& prefs,
                                 ChoiceCompletionMetadata metadata);

// Returns the timestamp of search engine choice screen. No value if no choice
// has been made.
std::optional<base::Time> GetChoiceScreenCompletionTimestamp(
    PrefService& prefs);

void ClearSearchEngineChoiceInvalidation(PrefService& prefs);

bool IsSearchEngineChoiceInvalid(PrefService& prefs);

#if !BUILDFLAG(IS_ANDROID)
// Returns the engine marketing snippet string resource id or -1 if the snippet
// was not found.
// The function definition is generated in `generated_marketing_snippets.cc`.
// `engine_keyword` is the search engine keyword.
int GetMarketingSnippetResourceId(const std::u16string& engine_keyword);

// Returns the marketing snippet string or the fallback string if the search
// engine didn't provide its own.
std::u16string GetMarketingSnippetString(
    const TemplateURLData& template_url_data);

#endif  // !BUILDFLAG(IS_ANDROID)

}  // namespace search_engines

#endif  // COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_UTILS_H_