File: browser_switcher_service.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; 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 (217 lines) | stat: -rw-r--r-- 7,271 bytes parent folder | download | duplicates (5)
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
// 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 CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_
#define CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_

#include <memory>
#include <string>

#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"

class BrowserSwitchHandler;
class Profile;

namespace browser_switcher {

class AlternativeBrowserDriver;
class BrowserSwitcherSitelist;
class ParsedXml;

// A definition of a source for an XML sitelist: a URL + what to do once it's
// downloaded.
struct RulesetSource {
  RulesetSource(std::string pref_name_,
                GURL url_,
                bool contains_inverted_rules,
                base::OnceCallback<void(ParsedXml xml)> parsed_callback_);
  RulesetSource(RulesetSource&&);
  ~RulesetSource();

  // Pref-name that should trigger a re-download when changed.
  std::string pref_name;
  // URL to download the ruleset from.
  GURL url;
  // If true, all the rules are inverted before being passed to the
  // callback. This is used for greylists.
  bool contains_inverted_rules;
  // What to do once the URL download + parsing is complete (or failed).
  base::OnceCallback<void(ParsedXml xml)> parsed_callback;

  std::unique_ptr<network::SimpleURLLoader> url_loader;
};

class BrowserSwitcherService;

class XmlDownloader {
 public:
  XmlDownloader(Profile* profile,
                BrowserSwitcherService* service,
                base::TimeDelta first_fetch_delay,
                base::RepeatingCallback<void()> all_done_callback);
  virtual ~XmlDownloader();

  base::Time last_refresh_time() const;
  base::Time next_refresh_time() const;

 private:
  // Returns true if any of the sources requires downloads. This is used to
  // avoid scheduling download tasks unnecessarily.
  bool HasValidSources() const;

  // Downloads the XML for every source, and calls ParseXml() for each source
  // once we have the response.
  void FetchXml();

  // Parses the XML for a source, and calls DoneParsing() on the UI thread when
  // done.
  void ParseXml(RulesetSource* source, std::unique_ptr<std::string> bytes);

  // Runs hooks on the source, and runs |all_done_callback| and
  // ScheduleRefresh() if this is the last source.
  void DoneParsing(RulesetSource* source, ParsedXml xml);

  // Schedules a call to Refresh() after |delay|.
  void ScheduleRefresh(base::TimeDelta delay);

  // Calls FetchXml() to refresh the sitelists.
  void Refresh();

  network::mojom::URLLoaderFactory* GetURLLoaderFactoryForURL(const GURL& url);

  mojo::Remote<network::mojom::URLLoaderFactory> file_url_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> other_url_factory_;

  // This |BrowserSwitcherService| owns this object.
  raw_ptr<BrowserSwitcherService> service_;

  std::vector<RulesetSource> sources_;

  base::RepeatingCallback<void()> all_done_callback_;

  // Number of |RulesetSource|s that have finished processing. Used to
  // trigger the callback once they've all been parsed.
  unsigned int counter_ = 0;

  base::Time last_refresh_time_;
  base::Time next_refresh_time_;

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

// Manages per-profile resources for BrowserSwitcher.
class BrowserSwitcherService : public KeyedService {
 private:
  using AllRulesetsParsedCallbackSignature = void(BrowserSwitcherService*);
  using AllRulesetsParsedCallback =
      base::RepeatingCallback<AllRulesetsParsedCallbackSignature>;

 public:
  BrowserSwitcherService() = delete;

  explicit BrowserSwitcherService(Profile* profile);

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

  ~BrowserSwitcherService() override;

  virtual void Init();

  // KeyedService:
  void Shutdown() override;

  AlternativeBrowserDriver* driver();
  BrowserSwitcherSitelist* sitelist();
  BrowserSwitcherPrefs& prefs();
  Profile* profile();

  base::TimeDelta fetch_delay();
  base::TimeDelta refresh_delay();

  void SetDriverForTesting(std::unique_ptr<AlternativeBrowserDriver> driver);
  void SetSitelistForTesting(std::unique_ptr<BrowserSwitcherSitelist> sitelist);

  static void SetFetchDelayForTesting(base::TimeDelta delay);
  static void SetRefreshDelayForTesting(base::TimeDelta delay);

  // Return a platform-specific list of URLs to download, and what to do with
  // each of them once their XML has been parsed.
  virtual std::vector<RulesetSource> GetRulesetSources();

  // Loads the rules from prefs, for the 1 minute period before the download
  // happens.
  virtual void LoadRulesFromPrefs();

  // Called after all XML rulesets finished downloading, and the rules are
  // applied. The XML is downloaded asynchronously, so browser tests use this
  // event to check that they applied correctly.
  void OnAllRulesetsLoadedForTesting(base::OnceCallback<void()> callback);

 protected:
  virtual void OnAllRulesetsParsed();
  virtual void OnBrowserSwitcherPrefsChanged(
      BrowserSwitcherPrefs* prefs,
      const std::vector<std::string>& changed_prefs);

  static base::TimeDelta fetch_delay_;
  static base::TimeDelta refresh_delay_;

 private:
  // chrome://browser-switch/internals has access to some
  // implementation-specific methods to query this object's state, listen for
  // events and trigger a re-download immediately.
  friend class ::BrowserSwitchHandler;

  void OnExternalSitelistParsed(ParsedXml xml);
  void OnExternalGreylistParsed(ParsedXml xml);

  // Load cached rules from the PrefStore, then re-download the sitelists after
  // |delay|.
  void StartDownload(base::TimeDelta delay);

  XmlDownloader* sitelist_downloader();

  // Triggers a sitelist refresh immediately. Used by
  // chrome://browser-switch/internals.
  void DownloadNow();

  // Registers a callback that triggers after the sitelists are done downloading
  // and all rules are applied.
  base::CallbackListSubscription RegisterAllRulesetsParsedCallback(
      AllRulesetsParsedCallback callback);

  std::unique_ptr<XmlDownloader> sitelist_downloader_;

  raw_ptr<Profile> profile_;
  BrowserSwitcherPrefs prefs_;
  base::CallbackListSubscription prefs_subscription_;

  // CallbackList for OnAllRulesetsParsed() listeners.
  base::RepeatingCallbackList<AllRulesetsParsedCallbackSignature>
      callback_list_;

  base::OnceCallback<void()> all_rulesets_loaded_callback_for_testing_;

  // Per-profile helpers.
  std::unique_ptr<AlternativeBrowserDriver> driver_;
  std::unique_ptr<BrowserSwitcherSitelist> sitelist_;

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

}  // namespace browser_switcher

#endif  // CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_