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 CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_MANAGER_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_MANAGER_H_
7
8#include <map>
9#include <string>
10
11#include "base/scoped_observer.h"
12#include "chrome/common/extensions/api/extension_action/action_info.h"
13#include "components/keyed_service/core/keyed_service.h"
14#include "extensions/browser/extension_registry_observer.h"
15
16class ExtensionAction;
17class Profile;
18
19namespace extensions {
20
21class Extension;
22class ExtensionRegistry;
23
24// Owns the ExtensionActions associated with each extension.  These actions live
25// while an extension is loaded and are destroyed on unload.
26class ExtensionActionManager : public KeyedService,
27                               public ExtensionRegistryObserver {
28 public:
29  explicit ExtensionActionManager(Profile* profile);
30  virtual ~ExtensionActionManager();
31
32  // Returns this profile's ExtensionActionManager.  One instance is
33  // shared between a profile and its incognito version.
34  static ExtensionActionManager* Get(content::BrowserContext* browser_context);
35
36  // Retrieves the page action, browser action, or system indicator for
37  // |extension|.
38  // If the result is not NULL, it remains valid until the extension is
39  // unloaded.
40  ExtensionAction* GetPageAction(const Extension& extension) const;
41  ExtensionAction* GetBrowserAction(const Extension& extension) const;
42  ExtensionAction* GetSystemIndicator(const Extension& extension) const;
43
44  // Returns either the PageAction or BrowserAction for |extension|, or NULL if
45  // none exists. Since an extension can only declare one of Browser|PageAction,
46  // this is okay to use anywhere you need a generic "ExtensionAction".
47  // Since SystemIndicators are used differently and don't follow this
48  // rule of mutual exclusion, they are not checked or returned.
49  ExtensionAction* GetExtensionAction(const Extension& extension) const;
50
51  // Gets the best fit ExtensionAction for the given |extension|. This takes
52  // into account |extension|'s browser or page actions, if any, along with its
53  // name and any declared icons.
54  scoped_ptr<ExtensionAction> GetBestFitAction(
55      const Extension& extension, ActionInfo::Type type) const;
56
57 private:
58  // Implement ExtensionRegistryObserver.
59  virtual void OnExtensionUnloaded(content::BrowserContext* browser_context,
60                                   const Extension* extension,
61                                   UnloadedExtensionInfo::Reason reason)
62      OVERRIDE;
63
64  Profile* profile_;
65
66  // Listen to extension unloaded notifications.
67  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
68      extension_registry_observer_;
69
70  // Keyed by Extension ID.  These maps are populated lazily when their
71  // ExtensionAction is first requested, and the entries are removed when the
72  // extension is unloaded.  Not every extension has a page action or browser
73  // action.
74  typedef std::map<std::string, linked_ptr<ExtensionAction> > ExtIdToActionMap;
75  mutable ExtIdToActionMap page_actions_;
76  mutable ExtIdToActionMap browser_actions_;
77  mutable ExtIdToActionMap system_indicators_;
78};
79
80}  // namespace extensions
81
82#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_MANAGER_H_
83