1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
6#define EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/callback_forward.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_vector.h"
15#include "base/scoped_observer.h"
16#include "content/public/browser/notification_observer.h"
17#include "content/public/browser/notification_registrar.h"
18#include "extensions/browser/api/declarative/rules_registry.h"
19#include "extensions/browser/browser_context_keyed_api_factory.h"
20#include "extensions/browser/extension_registry_observer.h"
21
22namespace content {
23class BrowserContext;
24class NotificationSource;
25}
26
27namespace extensions {
28class ContentRulesRegistry;
29class ExtensionRegistry;
30class RulesRegistryStorageDelegate;
31}
32
33namespace extensions {
34
35// This class owns all RulesRegistries implementations of an ExtensionService.
36// This class lives on the UI thread.
37class RulesRegistryService : public BrowserContextKeyedAPI,
38                             public content::NotificationObserver,
39                             public ExtensionRegistryObserver {
40 public:
41  typedef RulesRegistry::WebViewKey WebViewKey;
42  struct RulesRegistryKey {
43    std::string event_name;
44    WebViewKey webview_key;
45    RulesRegistryKey(const std::string event_name,
46                     const WebViewKey& webview_key)
47        : event_name(event_name),
48          webview_key(webview_key) {}
49    bool operator<(const RulesRegistryKey& other) const {
50      return (event_name < other.event_name) ||
51          ((event_name == other.event_name) &&
52          (webview_key < other.webview_key));
53    }
54  };
55
56  explicit RulesRegistryService(content::BrowserContext* context);
57  virtual ~RulesRegistryService();
58
59  // Unregisters refptrs to concrete RulesRegistries at other objects that were
60  // created by us so that the RulesRegistries can be released.
61  virtual void Shutdown() OVERRIDE;
62
63  // BrowserContextKeyedAPI implementation.
64  static BrowserContextKeyedAPIFactory<RulesRegistryService>*
65      GetFactoryInstance();
66
67  // Convenience method to get the RulesRegistryService for a context.
68  static RulesRegistryService* Get(content::BrowserContext* context);
69
70  // Registers the default RulesRegistries used in Chromium.
71  void EnsureDefaultRulesRegistriesRegistered(const WebViewKey& webview_key);
72
73  // Registers a RulesRegistry and wraps it in an InitializingRulesRegistry.
74  void RegisterRulesRegistry(scoped_refptr<RulesRegistry> rule_registry);
75
76  // Returns the RulesRegistry for |event_name| and |webview_key| or NULL if no
77  // such registry has been registered. Default rules registries (such as the
78  // WebRequest rules registry) will be created on first access.
79  scoped_refptr<RulesRegistry> GetRulesRegistry(const WebViewKey& webview_key,
80                                                const std::string& event_name);
81
82  // Accessors for each type of rules registry.
83  ContentRulesRegistry* content_rules_registry() const {
84    CHECK(content_rules_registry_);
85    return content_rules_registry_;
86  }
87
88  // Removes all rules registries of a given webview embedder process ID.
89  void RemoveWebViewRulesRegistries(int process_id);
90
91  // For testing.
92  void SimulateExtensionUninstalled(const std::string& extension_id);
93
94 private:
95  friend class BrowserContextKeyedAPIFactory<RulesRegistryService>;
96
97  // Maps <event name, webview key> to RuleRegistries that handle these
98  // events.
99  typedef std::map<RulesRegistryKey, scoped_refptr<RulesRegistry> >
100      RulesRegistryMap;
101
102  // Implementation of content::NotificationObserver.
103  virtual void Observe(int type,
104                       const content::NotificationSource& source,
105                       const content::NotificationDetails& details) OVERRIDE;
106
107  // ExtensionRegistryObserver implementation.
108  virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
109                                 const Extension* extension) OVERRIDE;
110  virtual void OnExtensionUnloaded(
111      content::BrowserContext* browser_context,
112      const Extension* extension,
113      UnloadedExtensionInfo::Reason reason) OVERRIDE;
114  virtual void OnExtensionUninstalled(
115      content::BrowserContext* browser_context,
116      const Extension* extension,
117      extensions::UninstallReason reason) OVERRIDE;
118
119  // Iterates over all registries, and calls |notification_callback| on them
120  // with |extension_id| as the argument. If a registry lives on a different
121  // thread, the call is posted to that thread, so no guarantee of synchronous
122  // processing.
123  void NotifyRegistriesHelper(
124      void (RulesRegistry::*notification_callback)(const std::string&),
125      const std::string& extension_id);
126
127  // BrowserContextKeyedAPI implementation.
128  static const char* service_name() {
129    return "RulesRegistryService";
130  }
131  static const bool kServiceHasOwnInstanceInIncognito = true;
132  static const bool kServiceIsNULLWhileTesting = true;
133
134  RulesRegistryMap rule_registries_;
135
136  // We own the parts of the registries which need to run on the UI thread.
137  ScopedVector<RulesCacheDelegate> cache_delegates_;
138
139  // Weak pointer into rule_registries_ to make it easier to handle content rule
140  // conditions.
141  ContentRulesRegistry* content_rules_registry_;
142
143  content::NotificationRegistrar registrar_;
144
145  // Listen to extension load, unloaded notification.
146  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
147      extension_registry_observer_;
148
149  content::BrowserContext* browser_context_;
150
151  DISALLOW_COPY_AND_ASSIGN(RulesRegistryService);
152};
153
154}  // namespace extensions
155
156#endif  // EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_REGISTRY_SERVICE_H__
157