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_
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"
28 namespace extensions
{
30 class ActiveTabPermissionGranter
;
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
{
40 enum ExtensionFilter
{
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
,
58 ~ExtensionKeybindingRegistry() override
;
60 // Enables/Disables general shortcut handling in Chrome. Implemented in
61 // platform-specific ExtensionKeybindingsRegistry* files.
62 static void SetShortcutHandlingSuspended(bool suspended
);
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
);
69 // Check whether the specified |accelerator| has been registered.
70 bool IsAcceleratorRegistered(const ui::Accelerator
& accelerator
) const;
73 // Add extension keybinding for the events defined by the |extension|.
74 // |command_name| is optional, but if not blank then only the command
75 // specified will be added.
76 virtual void AddExtensionKeybinding(
77 const Extension
* extension
,
78 const std::string
& command_name
) = 0;
79 // Remove extension bindings for |extension|. |command_name| is optional,
80 // but if not blank then only the command specified will be removed.
81 void RemoveExtensionKeybinding(
82 const Extension
* extension
,
83 const std::string
& command_name
);
84 // Overridden by platform specific implementations to provide additional
85 // unregistration (which varies between platforms).
86 virtual void RemoveExtensionKeybindingImpl(
87 const ui::Accelerator
& accelerator
,
88 const std::string
& command_name
) = 0;
90 // Make sure all extensions registered have keybindings added.
93 // Whether to ignore this command. Only browserAction commands and pageAction
94 // commands are currently ignored, since they are handled elsewhere.
95 bool ShouldIgnoreCommand(const std::string
& command
) const;
97 // Fire event targets which the specified |accelerator| is binding with.
98 // Returns true if we can find the appropriate event targets.
99 bool NotifyEventTargets(const ui::Accelerator
& accelerator
);
101 // Notifies appropriate parties that a command has been executed.
102 void CommandExecuted(const std::string
& extension_id
,
103 const std::string
& command
);
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
108 void AddEventTarget(const ui::Accelerator
& accelerator
,
109 const std::string
& extension_id
,
110 const std::string
& command_name
);
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;
121 // Returns true if the |event_targets_| is empty; otherwise returns false.
122 bool IsEventTargetsEmpty() const;
124 // Returns the BrowserContext for this registry.
125 content::BrowserContext
* browser_context() const { return browser_context_
; }
128 // Overridden from content::NotificationObserver:
129 void Observe(int type
,
130 const content::NotificationSource
& source
,
131 const content::NotificationDetails
& details
) override
;
133 // ExtensionRegistryObserver implementation.
134 void OnExtensionLoaded(content::BrowserContext
* browser_context
,
135 const Extension
* extension
) override
;
136 void OnExtensionUnloaded(content::BrowserContext
* browser_context
,
137 const Extension
* extension
,
138 UnloadedExtensionInfo::Reason reason
) override
;
140 // Returns true if the |extension| matches our extension filter.
141 bool ExtensionMatchesFilter(const extensions::Extension
* extension
);
143 // Execute commands for |accelerator|. If |extension_id| is empty, execute all
144 // commands bound to |accelerator|, otherwise execute only commands bound by
145 // the corresponding extension. Returns true if at least one command was
147 bool ExecuteCommands(const ui::Accelerator
& accelerator
,
148 const std::string
& extension_id
);
150 // The content notification registrar for listening to extension events.
151 content::NotificationRegistrar registrar_
;
153 content::BrowserContext
* browser_context_
;
155 // What extensions to register keybindings for.
156 ExtensionFilter extension_filter_
;
158 // Weak pointer to our delegate. Not owned by us. Must outlive this class.
161 // Maps an accelerator to a list of string pairs (extension id, command name)
162 // for commands that have been registered. This keeps track of the targets for
163 // the keybinding event (which named command to call in which extension). On
164 // GTK this map contains registration for pageAction and browserAction
165 // commands, whereas on other platforms it does not. Note that normal
166 // accelerator (which isn't media keys) has only one target, while the media
167 // keys can have more than one.
168 typedef std::list
<std::pair
<std::string
, std::string
> > TargetList
;
169 typedef std::map
<ui::Accelerator
, TargetList
> EventTargets
;
170 EventTargets event_targets_
;
172 // Listen to extension load, unloaded notifications.
173 ScopedObserver
<ExtensionRegistry
, ExtensionRegistryObserver
>
174 extension_registry_observer_
;
176 DISALLOW_COPY_AND_ASSIGN(ExtensionKeybindingRegistry
);
179 } // namespace extensions
181 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_