Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / extension_keybinding_registry.h
blob5714bfb065bb6de85abc37f82866b582717ff86d
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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_
8 #include <list>
9 #include <map>
10 #include <string>
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"
20 namespace content {
21 class BrowserContext;
24 namespace ui {
25 class Accelerator;
28 namespace extensions {
30 class ActiveTabPermissionGranter;
31 class Extension;
32 class ExtensionRegistry;
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
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;
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);
58 ~ExtensionKeybindingRegistry() override;
60 // Enables/Disables general shortcut handling in Chrome.
61 void SetShortcutHandlingSuspended(bool suspended);
62 bool shortcut_handling_suspended() const {
63 return shortcut_handling_suspended_;
66 // Execute the command bound to |accelerator| and provided by the extension
67 // with |extension_id|, if it exists.
68 void ExecuteCommand(const std::string& extension_id,
69 const ui::Accelerator& accelerator);
71 // Check whether the specified |accelerator| has been registered.
72 bool IsAcceleratorRegistered(const ui::Accelerator& accelerator) const;
74 protected:
75 // Add extension keybindings for the events defined by the |extension|.
76 // |command_name| is optional, but if not blank then only the command
77 // specified will be added.
78 virtual void AddExtensionKeybindings(
79 const Extension* extension,
80 const std::string& command_name) = 0;
81 // Remove extension bindings for |extension|. |command_name| is optional,
82 // but if not blank then only the command specified will be removed.
83 void RemoveExtensionKeybinding(
84 const Extension* extension,
85 const std::string& command_name);
86 // Overridden by platform specific implementations to provide additional
87 // unregistration (which varies between platforms).
88 virtual void RemoveExtensionKeybindingImpl(
89 const ui::Accelerator& accelerator,
90 const std::string& command_name) = 0;
92 // Called when shortcut handling is suspended or resumed.
93 virtual void OnShortcutHandlingSuspended(bool suspended) {}
95 // Make sure all extensions registered have keybindings added.
96 void Init();
98 // Whether to ignore this command. Only browserAction commands and pageAction
99 // commands are currently ignored, since they are handled elsewhere.
100 bool ShouldIgnoreCommand(const std::string& command) const;
102 // Fire event targets which the specified |accelerator| is binding with.
103 // Returns true if we can find the appropriate event targets.
104 bool NotifyEventTargets(const ui::Accelerator& accelerator);
106 // Notifies appropriate parties that a command has been executed.
107 void CommandExecuted(const std::string& extension_id,
108 const std::string& command);
110 // Add event target (extension_id, command name) to the target list of
111 // |accelerator|. Note that only media keys can have more than one event
112 // target.
113 void AddEventTarget(const ui::Accelerator& accelerator,
114 const std::string& extension_id,
115 const std::string& command_name);
117 // Get the first event target by the given |accelerator|. For a valid
118 // accelerator it should have only one event target, except for media keys.
119 // Returns true if we can find it, |extension_id| and |command_name| will be
120 // set to the right target; otherwise, false is returned and |extension_id|,
121 // |command_name| are unchanged.
122 bool GetFirstTarget(const ui::Accelerator& accelerator,
123 std::string* extension_id,
124 std::string* command_name) const;
126 // Returns true if the |event_targets_| is empty; otherwise returns false.
127 bool IsEventTargetsEmpty() const;
129 // Returns the BrowserContext for this registry.
130 content::BrowserContext* browser_context() const { return browser_context_; }
132 private:
133 // Overridden from content::NotificationObserver:
134 void Observe(int type,
135 const content::NotificationSource& source,
136 const content::NotificationDetails& details) override;
138 // ExtensionRegistryObserver implementation.
139 void OnExtensionLoaded(content::BrowserContext* browser_context,
140 const Extension* extension) override;
141 void OnExtensionUnloaded(content::BrowserContext* browser_context,
142 const Extension* extension,
143 UnloadedExtensionInfo::Reason reason) override;
145 // Returns true if the |extension| matches our extension filter.
146 bool ExtensionMatchesFilter(const extensions::Extension* extension);
148 // Execute commands for |accelerator|. If |extension_id| is empty, execute all
149 // commands bound to |accelerator|, otherwise execute only commands bound by
150 // the corresponding extension. Returns true if at least one command was
151 // executed.
152 bool ExecuteCommands(const ui::Accelerator& accelerator,
153 const std::string& extension_id);
155 // The content notification registrar for listening to extension events.
156 content::NotificationRegistrar registrar_;
158 content::BrowserContext* browser_context_;
160 // What extensions to register keybindings for.
161 ExtensionFilter extension_filter_;
163 // Weak pointer to our delegate. Not owned by us. Must outlive this class.
164 Delegate* delegate_;
166 // Maps an accelerator to a list of string pairs (extension id, command name)
167 // for commands that have been registered. This keeps track of the targets for
168 // the keybinding event (which named command to call in which extension). On
169 // GTK this map contains registration for pageAction and browserAction
170 // commands, whereas on other platforms it does not. Note that normal
171 // accelerator (which isn't media keys) has only one target, while the media
172 // keys can have more than one.
173 typedef std::list<std::pair<std::string, std::string> > TargetList;
174 typedef std::map<ui::Accelerator, TargetList> EventTargets;
175 EventTargets event_targets_;
177 // Listen to extension load, unloaded notifications.
178 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
179 extension_registry_observer_;
181 // Keeps track of whether shortcut handling is currently suspended. Shortcuts
182 // are suspended briefly while capturing which shortcut to assign to an
183 // extension command in the Config UI. If handling isn't suspended while
184 // capturing then trying to assign Ctrl+F to a command would instead result
185 // in the Find box opening.
186 bool shortcut_handling_suspended_;
188 DISALLOW_COPY_AND_ASSIGN(ExtensionKeybindingRegistry);
191 } // namespace extensions
193 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_