File: search_engine_choice_dialog_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 (209 lines) | stat: -rw-r--r-- 9,139 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
// 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 CHROME_BROWSER_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_DIALOG_SERVICE_H_
#define CHROME_BROWSER_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_DIALOG_SERVICE_H_

#include <string>

#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_service.h"
#include "components/search_engines/template_url_data.h"

class Browser;
class TemplateURLService;

namespace search_engines {

class ChoiceScreenData;
enum class SearchEngineChoiceScreenConditions;

// Profile specific data related to the search engine choice.
// `timestamp` is the search engine choice timestamp that's saved in the
// `kDefaultSearchProviderChoiceScreenCompletionTimestamp` pref.
// `chrome_version` is the Chrome version when the user made the choice.
// `default_search_engine` is the profile's default search engine.
struct ChoiceData {
  int64_t timestamp = 0;
  std::string chrome_version;
  TemplateURLData default_search_engine;
};

}  // namespace search_engines

// Service handling the Search Engine Choice dialog.
class SearchEngineChoiceDialogService : public KeyedService {
 public:
  // Specifies the view in which the choice screen UI is rendered.
  enum class EntryPoint {
    kProfileCreation = 0,
    kFirstRunExperience,
    kDialog,
  };

  SearchEngineChoiceDialogService(
      Profile& profile,
      search_engines::SearchEngineChoiceService& search_engine_choice_service,
      TemplateURLService& template_url_service);
  ~SearchEngineChoiceDialogService() override;

  // Informs the service that a Search Engine Choice dialog is being opened
  // for `browser`, providing a `close_dialog_callback` so that the dialog
  // can be closed when the choice is made, even from another browser
  // associated with this profile.
  //
  // Returns whether the caller should proceed with adding a dialog to
  // `browser`. When `false` is returned, the dialog will not be registered and
  // the caller should not proceed with showing the dialog.
  virtual bool RegisterDialog(Browser& browser,
                              base::OnceClosure close_dialog_callback);

  // This function is called when the user makes a search engine choice. It
  // closes the dialogs that are open on other browser windows that
  // have the same profile as the one on which the choice was made and sets the
  // corresponding preferences.
  // `prepopulate_id` is the `prepopulate_id` of the search engine found in
  // `components/search_engines/template_url_data.h`. It will always be > 0.
  // `save_guest_mode_selection` will save the guest mode selection so that the
  // users are not prompted at every guest session launch.
  // `entry_point` is the view in which the UI is rendered. Virtual to be able
  // to mock in tests.
  virtual void NotifyChoiceMade(int prepopulate_id,
                                bool save_guest_mode_selection,
                                EntryPoint entry_point);

  // Informs the service that the learn more link was clicked. This is used to
  // record histograms. `entry_point` is the view in which the UI is rendered.
  void NotifyLearnMoreLinkClicked(EntryPoint entry_point);

  // Informs the service that the "More" button was clicked. This is used to
  // record histograms. `entry_point` is the view in which the UI is rendered.
  void NotifyMoreButtonClicked(EntryPoint entry_point);

  // Returns the eligibility status for newly triggering a choice screen dialog.
  //
  // If calling this ahead of requesting to show the dialog, prefer to call
  // `SearchEngineChoiceTabHelper::MaybeShowDialog()` instead. It will check a
  // few more things and ensure we log the event correctly.
  search_engines::SearchEngineChoiceScreenConditions ComputeDialogConditions(
      Browser& browser) const;

  // Returns whether the dialog should be displayed over the passed URL.
  bool IsUrlSuitableForDialog(GURL url);

  // Returns whether a Search Engine Choice dialog is currently open or not for
  // `browser`.
  bool IsShowingDialog(Browser& browser) const;

  // Returns whether the Search Engine Choice dialog is either shown or
  // pending to be shown.
  bool HasPendingDialog(Browser& browser) const;

  // Checks whether we need to display the Privacy Sandbox dialog
  // in context of the Search Engine Choice.
  // The Privacy Sandbox dialog should be delayed to the next Chrome run if the
  // Search Engine Choice dialog will be or has been displayed in the current
  // run.
  // The Privacy Sandbox dialog should be displayed directly when the
  // browser gets launched in the case where the search engine choice was made
  // in the FRE.
  bool CanSuppressPrivacySandboxPromo() const;

  // Returns the list of search engines.
  // The search engine details returned by this function will be the canonical
  // ones and will not be affected by changes in search engine details from the
  // settings page.
  // Virtual to be able to mock in tests.
  virtual TemplateURL::TemplateURLVector GetSearchEngines();

  // Disables the display of the Search Engine Choice dialog for testing. When
  // `dialog_disabled` is true, `CanShowDialog` will return false.
  // NOTE: This is set to true in InProcessBrowserTest::SetUp, disabling the
  // dialog for those tests. If you set this outside of that context, you should
  // ensure it is reset at the end of your test.
  static void SetDialogDisabledForTests(bool dialog_disabled);

  // Returns a copy of the `ChoiceData` specific to `profile`.
  static search_engines::ChoiceData GetChoiceDataFromProfile(Profile& profile);

  // Updates `profile` with the values from `choice_data`.
  static void UpdateProfileFromChoiceData(
      Profile& profile,
      const search_engines::ChoiceData& choice_data);

 private:
  friend class SearchEngineChoiceDialogServiceFactory;

  // Keeps track of browsers that are known to be showing the choice dialog
  // to make sure that we can keep new browsers blocked until a choice is made
  // and unblock all of them when it is done.
  class BrowserRegistry : public BrowserListObserver {
   public:
    explicit BrowserRegistry(SearchEngineChoiceDialogService& service);
    ~BrowserRegistry() override;

    // Returns whether the provided browser requested to open a dialog. Note
    // that the dialog might have since been closed.
    bool IsRegistered(Browser& browser) const;

    // Returns whether a the provided browser is currently marked as having an
    // open dialog.
    bool HasOpenDialog(Browser& browser) const;

    // Registers that the browser wants to show a dialog. Returns whether the
    // registration is accepted. If `false` is returned, the browser should
    // abandon showing the dialog.
    bool RegisterBrowser(Browser& browser,
                         base::OnceClosure close_dialog_callback);
    void CloseAllDialogs();

    // BrowserListObserver implementation:
    void OnBrowserRemoved(Browser* browser) override;

   private:
    raw_ref<SearchEngineChoiceDialogService>
        search_engine_choice_dialog_service_;

    // A map of Browser windows which have registered with the service to show a
    // Search Engine Choice dialog, associated with a callback that will close
    // the browser's dialog.
    // The callback might be null, indicating that the browser showed a dialog
    // in the past, but that is has since been closed.
    base::flat_map<raw_ref<Browser>, base::OnceClosure> registered_browsers_;

    base::ScopedObservation<BrowserList, BrowserListObserver> observation_{
        this};
  };

  // To know whether the choice was made during the Profile Picker or not.
  bool choice_made_in_profile_picker_ = false;

  // Caches data backing the choice screens, shared across all of the choice
  // screens dialogs shown by this profile.
  // It gets lazily populated the first time something tries to get it.
  std::unique_ptr<search_engines::ChoiceScreenData> choice_screen_data_;

  // The `KeyedService` lifetime is expected to exceed the profile's.
  const raw_ref<Profile> profile_;
  const raw_ref<search_engines::SearchEngineChoiceService>
      search_engine_choice_service_;
  const raw_ref<TemplateURLService> template_url_service_;

  // Maintains the registration of browser dialogs for this profile.
  // TODO(crbug.com/347223092): Investigate whether it should be destroyed as a
  // way to more strictly prevent any re-registration once a choice is made.
  BrowserRegistry browser_registry_{*this};

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

#endif  // CHROME_BROWSER_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_DIALOG_SERVICE_H_