15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef EXTENSIONS_BROWSER_EXTENSION_REGISTRY_H_
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define EXTENSIONS_BROWSER_EXTENSION_REGISTRY_H_
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/compiler_specific.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/ref_counted.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/observer_list.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/uninstall_reason.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BrowserContext;
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Extension;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ExtensionRegistryObserver;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ExtensionRegistry holds sets of the installed extensions for a given
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserContext. An incognito browser context and its master browser context
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// share a single registry.
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ExtensionRegistry : public KeyedService {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Flags to pass to GetExtensionById() to select which sets to look in.
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enum IncludeFlag {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NONE        = 0,
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ENABLED     = 1 << 0,
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DISABLED    = 1 << 1,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TERMINATED  = 1 << 2,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BLACKLISTED = 1 << 3,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EVERYTHING = (1 << 4) - 1,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  explicit ExtensionRegistry(content::BrowserContext* browser_context);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ExtensionRegistry();
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns the instance for the given |browser_context|.
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static ExtensionRegistry* Get(content::BrowserContext* browser_context);
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::BrowserContext* browser_context() const { return browser_context_; }
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: These sets are *eventually* mututally exclusive, but an extension can
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // appear in two sets for short periods of time.
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& enabled_extensions() const {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return enabled_extensions_;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& disabled_extensions() const {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return disabled_extensions_;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& terminated_extensions() const {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return terminated_extensions_;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& blacklisted_extensions() const {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return blacklisted_extensions_;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Returns a set of all installed, disabled, blacklisted, and terminated
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // extensions.
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<ExtensionSet> GenerateInstalledExtensionsSet() const;
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The usual observer interface.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddObserver(ExtensionRegistryObserver* observer);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void RemoveObserver(ExtensionRegistryObserver* observer);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Invokes the observer method OnExtensionLoaded(). The extension must be
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // enabled at the time of the call.
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void TriggerOnLoaded(const Extension* extension);
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Invokes the observer method OnExtensionUnloaded(). The extension must not
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // be enabled at the time of the call.
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void TriggerOnUnloaded(const Extension* extension,
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         UnloadedExtensionInfo::Reason reason);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If this is a fresh install then |is_update| is false and there must not be
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // any installed extension with |extension|'s ID. If this is an update then
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |is_update| is true and must be an installed extension with |extension|'s
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ID, and |old_name| must be non-empty.
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If true, |from_ephemeral| indicates that the extension was previously
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // installed ephemerally and has been promoted to a regular installed
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // extension. |is_update| should also be true.
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void TriggerOnWillBeInstalled(const Extension* extension,
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                bool is_update,
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                bool from_ephemeral,
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                const std::string& old_name);
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Invokes the observer method OnExtensionInstalled(). The extension must be
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // contained in one of the registry's extension sets.
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TriggerOnInstalled(const Extension* extension,
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          bool is_update);
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Invokes the observer method OnExtensionUninstalled(). The extension must
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // not be any installed extension with |extension|'s ID.
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void TriggerOnUninstalled(const Extension* extension, UninstallReason reason);
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Find an extension by ID using |include_mask| to pick the sets to search:
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  * enabled_extensions()     --> ExtensionRegistry::ENABLED
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  * disabled_extensions()    --> ExtensionRegistry::DISABLED
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  * terminated_extensions()  --> ExtensionRegistry::TERMINATED
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  * blacklisted_extensions() --> ExtensionRegistry::BLACKLISTED
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns NULL if the extension is not found in the selected sets.
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Extension* GetExtensionById(const std::string& id,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    int include_mask) const;
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Adds the specified extension to the enabled set. The registry becomes an
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // owner. Any previous extension with the same ID is removed.
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns true if there is no previous extension.
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: You probably want to use ExtensionService instead of calling this
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // method directly.
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AddEnabled(const scoped_refptr<const Extension>& extension);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Removes the specified extension from the enabled set.
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns true if the set contained the specified extension.
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: You probably want to use ExtensionService instead of calling this
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // method directly.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RemoveEnabled(const std::string& id);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // As above, but for the disabled set.
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AddDisabled(const scoped_refptr<const Extension>& extension);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RemoveDisabled(const std::string& id);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // As above, but for the terminated set.
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AddTerminated(const scoped_refptr<const Extension>& extension);
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RemoveTerminated(const std::string& id);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // As above, but for the blacklisted set.
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AddBlacklisted(const scoped_refptr<const Extension>& extension);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool RemoveBlacklisted(const std::string& id);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Removes all extensions from all sets.
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ClearAll();
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Sets a callback to run when the disabled extension set is modified.
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(jamescook): This is too specific for a generic registry; find some
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // other way to do this.
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetDisabledModificationCallback(
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const ExtensionSet::ModificationCallback& callback);
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // KeyedService implementation:
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Shutdown() OVERRIDE;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extensions that are installed, enabled and not terminated.
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionSet enabled_extensions_;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extensions that are installed and disabled.
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionSet disabled_extensions_;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extensions that are installed and terminated.
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionSet terminated_extensions_;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extensions that are installed and blacklisted. Generally these shouldn't be
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // considered as installed by the extension platform: we only keep them around
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // so that if extensions are blacklisted by mistake they can easily be
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // un-blacklisted.
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionSet blacklisted_extensions_;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ObserverList<ExtensionRegistryObserver> observers_;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::BrowserContext* const browser_context_;
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionRegistry);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace extensions
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // EXTENSIONS_BROWSER_EXTENSION_REGISTRY_H_
173