1// Copyright 2013 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_EXTENSION_REGISTRY_H_
6#define EXTENSIONS_BROWSER_EXTENSION_REGISTRY_H_
7
8#include <string>
9
10#include "base/compiler_specific.h"
11#include "base/memory/ref_counted.h"
12#include "base/observer_list.h"
13#include "components/keyed_service/core/keyed_service.h"
14#include "extensions/browser/uninstall_reason.h"
15#include "extensions/common/extension_set.h"
16
17namespace content {
18class BrowserContext;
19}
20
21namespace extensions {
22class Extension;
23class ExtensionRegistryObserver;
24
25// ExtensionRegistry holds sets of the installed extensions for a given
26// BrowserContext. An incognito browser context and its master browser context
27// share a single registry.
28class ExtensionRegistry : public KeyedService {
29 public:
30  // Flags to pass to GetExtensionById() to select which sets to look in.
31  enum IncludeFlag {
32    NONE        = 0,
33    ENABLED     = 1 << 0,
34    DISABLED    = 1 << 1,
35    TERMINATED  = 1 << 2,
36    BLACKLISTED = 1 << 3,
37    EVERYTHING = (1 << 4) - 1,
38  };
39
40  explicit ExtensionRegistry(content::BrowserContext* browser_context);
41  virtual ~ExtensionRegistry();
42
43  // Returns the instance for the given |browser_context|.
44  static ExtensionRegistry* Get(content::BrowserContext* browser_context);
45
46  content::BrowserContext* browser_context() const { return browser_context_; }
47
48  // NOTE: These sets are *eventually* mututally exclusive, but an extension can
49  // appear in two sets for short periods of time.
50  const ExtensionSet& enabled_extensions() const {
51    return enabled_extensions_;
52  }
53  const ExtensionSet& disabled_extensions() const {
54    return disabled_extensions_;
55  }
56  const ExtensionSet& terminated_extensions() const {
57    return terminated_extensions_;
58  }
59  const ExtensionSet& blacklisted_extensions() const {
60    return blacklisted_extensions_;
61  }
62
63  // Returns a set of all installed, disabled, blacklisted, and terminated
64  // extensions.
65  scoped_ptr<ExtensionSet> GenerateInstalledExtensionsSet() const;
66
67  // The usual observer interface.
68  void AddObserver(ExtensionRegistryObserver* observer);
69  void RemoveObserver(ExtensionRegistryObserver* observer);
70
71  // Invokes the observer method OnExtensionLoaded(). The extension must be
72  // enabled at the time of the call.
73  void TriggerOnLoaded(const Extension* extension);
74
75  // Invokes the observer method OnExtensionUnloaded(). The extension must not
76  // be enabled at the time of the call.
77  void TriggerOnUnloaded(const Extension* extension,
78                         UnloadedExtensionInfo::Reason reason);
79
80  // If this is a fresh install then |is_update| is false and there must not be
81  // any installed extension with |extension|'s ID. If this is an update then
82  // |is_update| is true and must be an installed extension with |extension|'s
83  // ID, and |old_name| must be non-empty.
84  // If true, |from_ephemeral| indicates that the extension was previously
85  // installed ephemerally and has been promoted to a regular installed
86  // extension. |is_update| should also be true.
87  void TriggerOnWillBeInstalled(const Extension* extension,
88                                bool is_update,
89                                bool from_ephemeral,
90                                const std::string& old_name);
91
92  // Invokes the observer method OnExtensionInstalled(). The extension must be
93  // contained in one of the registry's extension sets.
94  void TriggerOnInstalled(const Extension* extension,
95                          bool is_update);
96
97  // Invokes the observer method OnExtensionUninstalled(). The extension must
98  // not be any installed extension with |extension|'s ID.
99  void TriggerOnUninstalled(const Extension* extension, UninstallReason reason);
100
101  // Find an extension by ID using |include_mask| to pick the sets to search:
102  //  * enabled_extensions()     --> ExtensionRegistry::ENABLED
103  //  * disabled_extensions()    --> ExtensionRegistry::DISABLED
104  //  * terminated_extensions()  --> ExtensionRegistry::TERMINATED
105  //  * blacklisted_extensions() --> ExtensionRegistry::BLACKLISTED
106  // Returns NULL if the extension is not found in the selected sets.
107  const Extension* GetExtensionById(const std::string& id,
108                                    int include_mask) const;
109
110  // Adds the specified extension to the enabled set. The registry becomes an
111  // owner. Any previous extension with the same ID is removed.
112  // Returns true if there is no previous extension.
113  // NOTE: You probably want to use ExtensionService instead of calling this
114  // method directly.
115  bool AddEnabled(const scoped_refptr<const Extension>& extension);
116
117  // Removes the specified extension from the enabled set.
118  // Returns true if the set contained the specified extension.
119  // NOTE: You probably want to use ExtensionService instead of calling this
120  // method directly.
121  bool RemoveEnabled(const std::string& id);
122
123  // As above, but for the disabled set.
124  bool AddDisabled(const scoped_refptr<const Extension>& extension);
125  bool RemoveDisabled(const std::string& id);
126
127  // As above, but for the terminated set.
128  bool AddTerminated(const scoped_refptr<const Extension>& extension);
129  bool RemoveTerminated(const std::string& id);
130
131  // As above, but for the blacklisted set.
132  bool AddBlacklisted(const scoped_refptr<const Extension>& extension);
133  bool RemoveBlacklisted(const std::string& id);
134
135  // Removes all extensions from all sets.
136  void ClearAll();
137
138  // Sets a callback to run when the disabled extension set is modified.
139  // TODO(jamescook): This is too specific for a generic registry; find some
140  // other way to do this.
141  void SetDisabledModificationCallback(
142      const ExtensionSet::ModificationCallback& callback);
143
144  // KeyedService implementation:
145  virtual void Shutdown() OVERRIDE;
146
147 private:
148  // Extensions that are installed, enabled and not terminated.
149  ExtensionSet enabled_extensions_;
150
151  // Extensions that are installed and disabled.
152  ExtensionSet disabled_extensions_;
153
154  // Extensions that are installed and terminated.
155  ExtensionSet terminated_extensions_;
156
157  // Extensions that are installed and blacklisted. Generally these shouldn't be
158  // considered as installed by the extension platform: we only keep them around
159  // so that if extensions are blacklisted by mistake they can easily be
160  // un-blacklisted.
161  ExtensionSet blacklisted_extensions_;
162
163  ObserverList<ExtensionRegistryObserver> observers_;
164
165  content::BrowserContext* const browser_context_;
166
167  DISALLOW_COPY_AND_ASSIGN(ExtensionRegistry);
168};
169
170}  // namespace extensions
171
172#endif  // EXTENSIONS_BROWSER_EXTENSION_REGISTRY_H_
173