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
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
#define EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
#include <map>
#include <string>
#include <tuple>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "extensions/browser/api/declarative/rules_cache_delegate.h"
#include "extensions/browser/api/declarative/rules_registry.h"
#include "extensions/browser/api/web_request/web_request_event_router_factory.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/rules_registry_ids.h"
namespace content {
class BrowserContext;
}
namespace extensions {
class ContentRulesRegistry;
}
namespace extensions {
// This class owns all RulesRegistries implementations of an ExtensionService.
// This class lives on the UI thread.
class RulesRegistryService : public BrowserContextKeyedAPI,
public ExtensionRegistryObserver,
public RulesCacheDelegate::Observer {
public:
struct RulesRegistryKey {
std::string event_name;
int rules_registry_id;
RulesRegistryKey(const std::string& event_name, int rules_registry_id)
: event_name(event_name), rules_registry_id(rules_registry_id) {}
bool operator<(const RulesRegistryKey& other) const {
return std::tie(event_name, rules_registry_id) <
std::tie(other.event_name, other.rules_registry_id);
}
};
class Observer {
public:
// Called when any of the `cache_delegates_` have rule updates.
virtual void OnUpdateRules() = 0;
protected:
virtual ~Observer() {}
};
explicit RulesRegistryService(content::BrowserContext* context);
RulesRegistryService(const RulesRegistryService&) = delete;
RulesRegistryService& operator=(const RulesRegistryService&) = delete;
~RulesRegistryService() override;
// Unregisters refptrs to concrete RulesRegistries at other objects that were
// created by us so that the RulesRegistries can be released.
void Shutdown() override;
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<RulesRegistryService>*
GetFactoryInstance();
// Convenience method to get the RulesRegistryService for a context. If a
// RulesRegistryService does not already exist for `context`, one will be
// created and returned.
static RulesRegistryService* Get(content::BrowserContext* context);
// The same as Get(), except that if a RulesRegistryService does not already
// exist for `context`, nullptr is returned.
static RulesRegistryService* GetIfExists(content::BrowserContext* context);
int GetNextRulesRegistryID();
// Registers a RulesRegistry and wraps it in an InitializingRulesRegistry.
void RegisterRulesRegistry(scoped_refptr<RulesRegistry> rule_registry);
// Returns the RulesRegistry for `event_name` and `rules_registry_id`.
// Attempts to create and register the rules registry if necessary. Might
// return null if no corresponding rules registry was registered.
scoped_refptr<RulesRegistry> GetRulesRegistry(int rules_registry_id,
const std::string& event_name);
// Remove all rules registries of the given rules_registry_id.
void RemoveRulesRegistriesByID(int rules_registry_id);
// Accessors for each type of rules registry.
ContentRulesRegistry* content_rules_registry() const {
CHECK(content_rules_registry_);
return content_rules_registry_;
}
// Indicates whether any registry has rules registered.
bool HasAnyRegisteredRules() const;
// Adds or removes an observer.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// For testing.
void SimulateExtensionUninstalled(const Extension* extension);
// For testing. Returns true if `rule_registries_` has the RulesRegistry for
// `event_name` and `rules_registry_id`.
bool HasRulesRegistryForTesting(int rules_registry_id,
const std::string& event_name);
private:
friend class BrowserContextKeyedAPIFactory<RulesRegistryService>;
scoped_refptr<RulesRegistry> RegisterWebRequestRulesRegistry(
int rules_registry_id,
RulesCacheDelegate::Type cache_delegate_type);
// Registers the default RulesRegistries used in Chromium.
void EnsureDefaultRulesRegistriesRegistered();
// Maps <event name, rules registry ID> to RuleRegistries that handle these
// events.
typedef std::map<RulesRegistryKey, scoped_refptr<RulesRegistry> >
RulesRegistryMap;
// ExtensionRegistryObserver implementation.
void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) override;
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionReason reason) override;
void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension,
extensions::UninstallReason reason) override;
// RulesCacheDelegate::Observer implementation.
void OnUpdateRules() override;
// Iterates over all registries, and calls `notification_callback` on them
// with `extension` as the argument. If a registry lives on a different
// thread, the call is posted to that thread, so no guarantee of synchronous
// processing.
void NotifyRegistriesHelper(
void (RulesRegistry::*notification_callback)(const Extension*),
const Extension* extension);
// BrowserContextKeyedAPI implementation.
static const char* service_name() {
return "RulesRegistryService";
}
static const bool kServiceHasOwnInstanceInIncognito = true;
static const bool kServiceIsNULLWhileTesting = true;
int current_rules_registry_id_ = rules_registry_ids::kDefaultRulesRegistryID;
RulesRegistryMap rule_registries_;
// We own the parts of the registries which need to run on the UI thread.
std::vector<std::unique_ptr<RulesCacheDelegate>> cache_delegates_;
// Weak pointer into rule_registries_ to make it easier to handle content rule
// conditions.
raw_ptr<ContentRulesRegistry, AcrossTasksDanglingUntriaged>
content_rules_registry_ = nullptr;
// Listen to extension load, unloaded notification.
base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observation_{this};
raw_ptr<content::BrowserContext> browser_context_;
base::ObserverList<Observer>::Unchecked observers_;
};
template <>
struct BrowserContextFactoryDependencies<RulesRegistryService> {
static void DeclareFactoryDependencies(
BrowserContextKeyedAPIFactory<RulesRegistryService>* factory) {
factory->DependsOn(
ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
factory->DependsOn(WebRequestEventRouterFactory::GetInstance());
}
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
|