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
|
// 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_PREFS_H_
#define CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_PREFS_H_
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "base/callback_list.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/policy/core/common/policy_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "url/gurl.h"
namespace user_prefs {
class PrefRegistrySyncable;
} // namespace user_prefs
class PrefService;
class Profile;
namespace browser_switcher {
// This type pre-computes some strings from the URL's parts, so we don't have
// to pay the cost of constructing those strings multiple times. i.e., the same
// NoCopyUrl can be passed to multiple calls of Rule::Matches().
class NoCopyUrl {
public:
explicit NoCopyUrl(const GURL& original);
NoCopyUrl(const NoCopyUrl&) = delete;
const GURL& original() const { return *original_; }
std::string_view host_and_port() const { return host_and_port_; }
std::string_view spec() const { return original_->spec(); }
std::string_view spec_without_port() const { return spec_without_port_; }
private:
const raw_ref<const GURL> original_;
// If there is a port number, then this is "<host>:<port>". Otherwise, this is
// just the host.
std::string host_and_port_;
// Same as |original_.spec()|, but with the port removed.
std::string spec_without_port_;
};
// A named pair type, for rules that haven't been pre-processed and
// canonicalized (e.g., just loaded from prefs or policies).
struct RawRuleSet {
RawRuleSet();
RawRuleSet(std::vector<std::string>&& sitelist,
std::vector<std::string>&& greylist);
RawRuleSet(RawRuleSet&&);
~RawRuleSet();
RawRuleSet& operator=(RawRuleSet&&);
std::vector<std::string> sitelist;
std::vector<std::string> greylist;
};
// A single "rule" from a sitelist or greylist, after pre-processing and
// canonicalization.
class Rule {
public:
explicit Rule(std::string_view original_rule);
virtual ~Rule() = default;
// Returns true if |no_copy_url| matches this rule. Ignores the value of
// |inverted_|.
virtual bool Matches(const NoCopyUrl& no_copy_url) const = 0;
// Returns true if the rule is valid. If this returns false, the rule will be
// removed from the final list of canonicalized rules.
virtual bool IsValid() const = 0;
// Converts the rule to a human-readable string, for display on
// chrome://browser-switch/internals and serializing to cache.dat.
virtual std::string ToString() const = 0;
int priority() const { return priority_; }
bool inverted() const { return inverted_; }
private:
// The "priority" of this rule for making decisions. This should be the length
// of the original string this rule was parsed from. When 2 rules conflict,
// the one with higher priority always wins.
int priority_;
// Whether this rule is inverted or not. Inverted rules change the decision
// from "open in alternative browser" to "don't open in alternative browser".
bool inverted_;
};
// A named pair type, for pre-processed and canonicalized rules.
struct RuleSet {
RuleSet();
RuleSet(RuleSet&&);
~RuleSet();
std::vector<std::unique_ptr<Rule>> sitelist;
std::vector<std::unique_ptr<Rule>> greylist;
};
// Values for the BrowserSwitcherParsingMode policy. Make sure they match the
// values in policy_templates.json.
enum class ParsingMode {
kDefault = 0,
kIESiteListMode = 1,
kMaxValue = kIESiteListMode, // Always keep up-to-date.
};
// Contains the current state of the prefs related to LBS. For sensitive prefs,
// only respects managed prefs. Also does some type conversions and
// transformations on the prefs (e.g. expanding preset values for
// AlternativeBrowserPath).
class BrowserSwitcherPrefs : public KeyedService,
public policy::PolicyService::Observer {
private:
using PrefsChangedSignature = void(BrowserSwitcherPrefs*,
const std::vector<std::string>&);
public:
using PrefsChangedCallback = base::RepeatingCallback<PrefsChangedSignature>;
BrowserSwitcherPrefs() = delete;
explicit BrowserSwitcherPrefs(Profile* profile);
BrowserSwitcherPrefs(const BrowserSwitcherPrefs&) = delete;
BrowserSwitcherPrefs& operator=(const BrowserSwitcherPrefs&) = delete;
~BrowserSwitcherPrefs() override;
// KeyedService:
void Shutdown() override;
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Returns true if the BrowserSwitcher feature is enabled via policy.
bool IsEnabled() const;
// Returns the path to the alternative browser to launch, before
// substitutions. If the pref is not managed, returns the empty string.
const std::string& GetAlternativeBrowserPath() const;
// Returns the arguments to pass to the alternative browser, before
// substitutions. If the pref is not managed, returns the empty string.
const std::vector<std::string>& GetAlternativeBrowserParameters() const;
// Returns true if Chrome should keep at least one tab open after switching.
bool KeepLastTab() const;
// Returns the delay before switching, in milliseconds.
int GetDelay() const;
ParsingMode GetParsingMode() const;
// Returns the sitelist + greylist configured directly through Chrome
// policies. If the pref is not managed, returns an empty vector.
const RuleSet& GetRules() const;
// Retrieves or stores the locally cached external sitelist from the
// PrefStore.
RawRuleSet GetCachedExternalSitelist() const;
void SetCachedExternalSitelist(const RawRuleSet& sitelist);
// Retrieves or stores the locally cached external greylist from the
// PrefStore.
RawRuleSet GetCachedExternalGreylist() const;
void SetCachedExternalGreylist(const RawRuleSet& greylist);
#if BUILDFLAG(IS_WIN)
// Retrieves or stores the locally cached IEEM sitelist from the PrefStore.
RawRuleSet GetCachedIeemSitelist() const;
void SetCachedIeemSitelist(const RawRuleSet& sitelist);
#endif
// Returns the URL to download for an external XML sitelist. If the pref is
// not managed, returns an invalid URL.
GURL GetExternalSitelistUrl() const;
// Returns the URL to download for an external XML greylist. If the pref is
// not managed, returns an invalid URL.
GURL GetExternalGreylistUrl() const;
#if BUILDFLAG(IS_WIN)
// Returns true if Chrome should download and apply the XML sitelist from
// IEEM's SiteList policy. If the pref is not managed, returns false.
bool UseIeSitelist() const;
// Returns the path to the Chrome executable to launch when switching from IE,
// before substitutions.
const base::FilePath& GetChromePath() const;
// Returns the arguments to pass to Chrome when switching from IE, before
// substitutions.
const std::vector<std::string>& GetChromeParameters() const;
#endif
// policy::PolicyService::Observer
void OnPolicyUpdated(const policy::PolicyNamespace& ns,
const policy::PolicyMap& previous,
const policy::PolicyMap& current) override;
base::CallbackListSubscription RegisterPrefsChangedCallback(
PrefsChangedCallback cb);
protected:
// For internal use and testing.
BrowserSwitcherPrefs(PrefService* prefs,
policy::PolicyService* policy_service);
private:
void RunCallbacksIfDirty();
void MarkDirty(const std::string& pref_name);
// Hooks for PrefChangeRegistrar.
void AlternativeBrowserPathChanged();
void AlternativeBrowserParametersChanged();
void ParsingModeChanged();
void UrlListChanged();
void GreylistChanged();
#if BUILDFLAG(IS_WIN)
void ChromePathChanged();
void ChromeParametersChanged();
#endif
const raw_ptr<policy::PolicyService> policy_service_;
const raw_ptr<PrefService> prefs_;
// We need 2 change registrars because we can't bind 2 observers to the same
// pref on the same registrar.
// Listens on *some* prefs, to apply a filter to them
// (e.g. convert Value::List => vector<string>).
PrefChangeRegistrar filtering_change_registrar_;
// Listens on *all* BrowserSwitcher prefs, to notify observers when prefs
// change as a result of a policy refresh.
PrefChangeRegistrar notifying_change_registrar_;
// Type-converted and/or expanded pref values, updated by the
// PrefChangeRegistrar hooks.
std::string alt_browser_path_;
std::vector<std::string> alt_browser_params_;
ParsingMode parsing_mode_ = ParsingMode::kDefault;
#if BUILDFLAG(IS_WIN)
base::FilePath chrome_path_;
std::vector<std::string> chrome_params_;
#endif
// Rules from the BrowserSwitcherUrlList and BrowserSwitcherGreylist policies.
//
// Other rules are parsed from XML, and stored in BrowserSwitcherSitelist
// instead of here.
RuleSet rules_;
// List of prefs (pref names) that changed since the last policy refresh.
std::vector<std::string> dirty_prefs_;
base::RepeatingCallbackList<PrefsChangedSignature> callback_list_;
base::WeakPtrFactory<BrowserSwitcherPrefs> weak_ptr_factory_{this};
};
namespace prefs {
extern const char kEnabled[];
extern const char kDelay[];
extern const char kAlternativeBrowserPath[];
extern const char kAlternativeBrowserParameters[];
extern const char kKeepLastTab[];
extern const char kParsingMode[];
extern const char kUrlList[];
extern const char kUrlGreylist[];
extern const char kExternalSitelistUrl[];
extern const char kCachedExternalSitelist[];
extern const char kCachedExternalSitelistGreylist[];
extern const char kExternalGreylistUrl[];
extern const char kCachedExternalGreylist[];
#if BUILDFLAG(IS_WIN)
extern const char kUseIeSitelist[];
extern const char kCachedIeSitelist[];
extern const char kCachedIeSitelistGreylist[];
extern const char kChromePath[];
extern const char kChromeParameters[];
#endif
} // namespace prefs
} // namespace browser_switcher
#endif // CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_PREFS_H_
|