Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_keybinding_registry.h
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_KEYBINDING_REGISTRY_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_
7
8 #include <list>
9 #include <map>
10 #include <string>
11
12 #include "base/compiler_specific.h"
13 #include "base/scoped_observer.h"
14 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_observer.h"
16 #include "content/public/browser/notification_registrar.h"
17 #include "content/public/browser/notification_source.h"
18 #include "extensions/browser/extension_registry_observer.h"
19
20 namespace content {
21 class BrowserContext;
22 }
23
24 namespace ui {
25 class Accelerator;
26 }
27
28 namespace extensions {
29
30 class ActiveTabPermissionGranter;
31 class Extension;
32 class ExtensionRegistry;
33
34 // The ExtensionKeybindingRegistry is a class that handles the cross-platform
35 // logic for keyboard accelerators. See platform-specific implementations for
36 // implementation details for each platform.
37 class ExtensionKeybindingRegistry : public content::NotificationObserver,
38                                     public ExtensionRegistryObserver {
39  public:
40   enum ExtensionFilter {
41     ALL_EXTENSIONS,
42     PLATFORM_APPS_ONLY
43   };
44
45   class Delegate {
46    public:
47     // Gets the ActiveTabPermissionGranter for the active tab, if any.
48     // If there is no active tab then returns NULL.
49     virtual ActiveTabPermissionGranter* GetActiveTabPermissionGranter() = 0;
50   };
51
52   // If |extension_filter| is not ALL_EXTENSIONS, only keybindings by
53   // by extensions that match the filter will be registered.
54   ExtensionKeybindingRegistry(content::BrowserContext* context,
55                               ExtensionFilter extension_filter,
56                               Delegate* delegate);
57
58   virtual ~ExtensionKeybindingRegistry();
59
60   // Enables/Disables general shortcut handling in Chrome. Implemented in
61   // platform-specific ExtensionKeybindingsRegistry* files.
62   static void SetShortcutHandlingSuspended(bool suspended);
63
64   // Execute the command bound to |accelerator| and provided by the extension
65   // with |extension_id|, if it exists.
66   void ExecuteCommand(const std::string& extension_id,
67                       const ui::Accelerator& accelerator);
68
69  protected:
70   // Add extension keybinding for the events defined by the |extension|.
71   // |command_name| is optional, but if not blank then only the command
72   // specified will be added.
73   virtual void AddExtensionKeybinding(
74       const Extension* extension,
75       const std::string& command_name) = 0;
76   // Remove extension bindings for |extension|. |command_name| is optional,
77   // but if not blank then only the command specified will be removed.
78   void RemoveExtensionKeybinding(
79       const Extension* extension,
80       const std::string& command_name);
81   // Overridden by platform specific implementations to provide additional
82   // unregistration (which varies between platforms).
83   virtual void RemoveExtensionKeybindingImpl(
84       const ui::Accelerator& accelerator,
85       const std::string& command_name) = 0;
86
87   // Make sure all extensions registered have keybindings added.
88   void Init();
89
90   // Whether to ignore this command. Only browserAction commands and pageAction
91   // commands are currently ignored, since they are handled elsewhere.
92   bool ShouldIgnoreCommand(const std::string& command) const;
93
94   // Fire event targets which the specified |accelerator| is binding with.
95   // Returns true if we can find the appropriate event targets.
96   bool NotifyEventTargets(const ui::Accelerator& accelerator);
97
98   // Notifies appropriate parties that a command has been executed.
99   void CommandExecuted(const std::string& extension_id,
100                        const std::string& command);
101
102   // Check whether the specified |accelerator| has been registered.
103   bool IsAcceleratorRegistered(const ui::Accelerator& accelerator) const;
104
105   // Add event target (extension_id, command name) to the target list of
106   // |accelerator|. Note that only media keys can have more than one event
107   // target.
108   void AddEventTarget(const ui::Accelerator& accelerator,
109                       const std::string& extension_id,
110                       const std::string& command_name);
111
112   // Get the first event target by the given |accelerator|. For a valid
113   // accelerator it should have only one event target, except for media keys.
114   // Returns true if we can find it, |extension_id| and |command_name| will be
115   // set to the right target; otherwise, false is returned and |extension_id|,
116   // |command_name| are unchanged.
117   bool GetFirstTarget(const ui::Accelerator& accelerator,
118                       std::string* extension_id,
119                       std::string* command_name) const;
120
121   // Returns true if the |event_targets_| is empty; otherwise returns false.
122   bool IsEventTargetsEmpty() const;
123
124   // Returns the BrowserContext for this registry.
125   content::BrowserContext* browser_context() const { return browser_context_; }
126
127  private:
128   // Overridden from content::NotificationObserver:
129   virtual void Observe(int type,
130                        const content::NotificationSource& source,
131                        const content::NotificationDetails& details) OVERRIDE;
132
133   // ExtensionRegistryObserver implementation.
134   virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
135                                  const Extension* extension) OVERRIDE;
136   virtual void OnExtensionUnloaded(
137       content::BrowserContext* browser_context,
138       const Extension* extension,
139       UnloadedExtensionInfo::Reason reason) OVERRIDE;
140
141   // Returns true if the |extension| matches our extension filter.
142   bool ExtensionMatchesFilter(const extensions::Extension* extension);
143
144   // Execute commands for |accelerator|. If |extension_id| is empty, execute all
145   // commands bound to |accelerator|, otherwise execute only commands bound by
146   // the corresponding extension. Returns true if at least one command was
147   // executed.
148   bool ExecuteCommands(const ui::Accelerator& accelerator,
149                        const std::string& extension_id);
150
151   // The content notification registrar for listening to extension events.
152   content::NotificationRegistrar registrar_;
153
154   content::BrowserContext* browser_context_;
155
156   // What extensions to register keybindings for.
157   ExtensionFilter extension_filter_;
158
159   // Weak pointer to our delegate. Not owned by us. Must outlive this class.
160   Delegate* delegate_;
161
162   // Maps an accelerator to a list of string pairs (extension id, command name)
163   // for commands that have been registered. This keeps track of the targets for
164   // the keybinding event (which named command to call in which extension). On
165   // GTK this map contains registration for pageAction and browserAction
166   // commands, whereas on other platforms it does not. Note that normal
167   // accelerator (which isn't media keys) has only one target, while the media
168   // keys can have more than one.
169   typedef std::list<std::pair<std::string, std::string> > TargetList;
170   typedef std::map<ui::Accelerator, TargetList> EventTargets;
171   EventTargets event_targets_;
172
173   // Listen to extension load, unloaded notifications.
174   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
175       extension_registry_observer_;
176
177   DISALLOW_COPY_AND_ASSIGN(ExtensionKeybindingRegistry);
178 };
179
180 }  // namespace extensions
181
182 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_