File: search_engine_choice_service.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,905 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
// 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_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_SERVICE_H_
#define COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_SERVICE_H_

#include <optional>

#include "base/debug/stack_trace.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "components/country_codes/country_codes.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_utils.h"

namespace policy {
class PolicyService;
}
namespace variations {
class VariationsService;
}
namespace regional_capabilities {
class RegionalCapabilitiesService;
}
namespace TemplateURLPrepopulateData {
class Resolver;
}

class PrefRegistrySimple;
class PrefService;
class TemplateURLService;

namespace search_engines {

// `KeyedService` for managing the state related to Search Engine Choice (mostly
// for the country information).
class SearchEngineChoiceService : public KeyedService {
 public:
  class Observer : public base::CheckedObserver {
   public:
    virtual void OnSavedGuestSearchChanged() = 0;
  };

  // Interface allowing SearchEngineChoiceService to have access to
  // dependencies from higher level layers or that's can't be passed in
  // at construction time, for example due to incompatible lifecycles.
  class Client {
   public:
    virtual ~Client();

    // Returns the Variations (Finch) country ID for this current run, or an
    // invalid country ID if it's not available.
    virtual country_codes::CountryId GetVariationsCountry() = 0;

    // Returns whether this profile type is compatible with the
    // Guest-specific default search engine propagation.
    virtual bool IsProfileEligibleForDseGuestPropagation() = 0;

    // Returns whether Chrome detected in this current run that its data has
    // been transferred / restored to a new device.
    //
    // In practice, this function is not reliable on desktop. That's because
    // "detected in current session" happens asynchronously, so it's possible
    // to call this function and get a "false" value in a session where it will
    // end up returning true at some point. And in the next session, "detected
    // in current session" would be false too. It's possible to miss an actual
    // true value due to timing of calls to this function.
    virtual bool IsDeviceRestoreDetectedInCurrentSession() = 0;

    // Returns whether the search engine choice described in `choice_metadata`
    // predates the Chrome data having been transferred or restored to this
    // device.
    virtual bool DoesChoicePredateDeviceRestore(
        const ChoiceCompletionMetadata& choice_metadata) = 0;

   protected:
    // Helper for subclass to have the possibility to share some of the
    // implementation of `GetVariationsCountry()`.
    static country_codes::CountryId GetVariationsLatestCountry(
        variations::VariationsService* variations_service);
  };

  SearchEngineChoiceService(
      std::unique_ptr<Client> client,
      PrefService& profile_prefs,
      PrefService* local_state,
      regional_capabilities::RegionalCapabilitiesService& regional_capabilities,
      TemplateURLPrepopulateData::Resolver& prepopulate_data_resolver);
  ~SearchEngineChoiceService() override;

  // Returns the choice screen eligibility condition most relevant for the
  // profile associated with `profile_prefs` and `template_url_service`. Only
  // checks dynamic conditions, that can change from one call to the other
  // during a profile's lifetime. Should be checked right before showing a
  // choice screen.
  SearchEngineChoiceScreenConditions GetDynamicChoiceScreenConditions(
      const TemplateURLService& template_url_service);

  // Returns the choice screen eligibility condition most relevant for the
  // profile described by `profile_properties`. Only checks static conditions,
  // such that if a non-eligible condition is returned, it would take at least a
  // restart for the state to change. So this state can be checked and cached
  // ahead of showing a choice screen.
  // TODO(b/318801987): Remove `is_regular_profile` after fixing tests.
  SearchEngineChoiceScreenConditions GetStaticChoiceScreenConditions(
      const policy::PolicyService& policy_service,
      bool is_regular_profile,
      const TemplateURLService& template_url_service);

  // Returns key information needed to show a search engine choice screen, like
  // the template URLs for the engines to show. See
  // `search_engines::ChoiceScreenData` for more details.
  std::unique_ptr<search_engines::ChoiceScreenData> GetChoiceScreenData(
      const SearchTermsData& search_terms_data);

  // Records that the choice was made by settings the timestamp if applicable.
  // Records the location from which the choice was made and the search engine
  // that was chosen.
  // The function should be called after the default search engine has been set.
  void RecordChoiceMade(ChoiceMadeLocation choice_location,
                        TemplateURLService* template_url_service);

  // Records metrics about what was displayed on the choice screen for this
  // profile, as captured by `display_state`.
  // `is_from_cached_state` being `true` indicates that this is not the first
  // time the method has been called for this profile, and that we are now
  // calling it with some `display_state` that was cached from a previous
  // attempt due to a mismatch between the Variations country and the one
  // associated with the profile. Some metrics can be logged right away, while
  // some others are logged only when the countries match.
  // Note that due to various constraints, this might end up being a no-op and
  // not record anything.
  void MaybeRecordChoiceScreenDisplayState(
      const ChoiceScreenDisplayState& display_state,
      bool is_from_cached_state = false);

  // Clear state e.g. when a guest session is closed.
  void ResetState();

  // Clears the country id cache to be able to change countries multiple times
  // in tests.
  // TODO(crbug.com/328040066): Move to `//components/regional_capabilities`.
  void ClearCountryIdCacheForTesting();

  // Returns a reference to the `SearchEngineChoiceService::Client` owned and
  // used by this service.
  Client& GetClientForTesting();

  // Returns whether the profile is eligible for the default search engine to be
  // used across all guest sessions.
  bool IsDsePropagationAllowedForGuest() const;

  // Returns the previously chosen default search engine configured to be
  // propagated to new guest sessions. Returns nullopt if the profile is
  // not eligible for DSE propagation or no DSE choice was previously stored.
  std::optional<int> GetSavedSearchEngineBetweenGuestSessions() const;

  // Save the `prepopulated_id` of the chosen search engine to be used for all
  // guest sessions. Pass nullopt to reset the search engine choice.
  void SetSavedSearchEngineBetweenGuestSessions(
      std::optional<int> prepopulated_id);

  void AddObserver(Observer* obs) { observers_.AddObserver(obs); }

  void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); }

  // Register Local state preferences in `registry`.
  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);

 private:
  // Checks if the search engine choice should be invalidated, based on pref
  // inconsistencies, command line args, or experiment parameters. Returns a
  // wipe reason if the choice should be cleared, or nullopt otherwise.
  std::optional<SearchEngineChoiceWipeReason> CheckPrefsForWipeReason();

  void ProcessPendingChoiceScreenDisplayState();

  std::unique_ptr<Client> client_;
  const raw_ref<PrefService> profile_prefs_;
  const raw_ptr<PrefService> local_state_;
  const raw_ref<regional_capabilities::RegionalCapabilitiesService>
      regional_capabilities_service_;
  const raw_ref<TemplateURLPrepopulateData::Resolver>
      prepopulate_data_resolver_;
  base::ObserverList<Observer> observers_;

  // Used to ensure that the value returned from `GetCountryId` never changes
  // in runtime (different runs can still return different values, though).
  std::optional<int> country_id_cache_;

  // Used to track caller of `MaybeRecordChoiceScreenDisplayState()` to debug
  // some unmet expectations, see b/344899110.
  std::unique_ptr<base::debug::StackTrace> display_state_record_caller_;

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

void MarkSearchEngineChoiceCompletedForTesting(PrefService& prefs);

}  // namespace search_engines

#endif  // COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_SERVICE_H_