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_API_COMMANDS_COMMAND_SERVICE_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_COMMANDS_COMMAND_SERVICE_H_
10 #include "base/basictypes.h"
11 #include "base/scoped_observer.h"
12 #include "chrome/common/extensions/command.h"
13 #include "extensions/browser/browser_context_keyed_api_factory.h"
14 #include "extensions/browser/extension_registry_observer.h"
15 #include "extensions/common/extension.h"
20 class DictionaryValue
;
31 namespace user_prefs
{
32 class PrefRegistrySyncable
;
35 namespace extensions
{
36 class ExtensionRegistry
;
38 // This service keeps track of preferences related to extension commands
39 // (assigning initial keybindings on install and removing them on deletion
40 // and answers questions related to which commands are active.
41 class CommandService
: public BrowserContextKeyedAPI
,
42 public ExtensionRegistryObserver
{
44 // An enum specifying which extension commands to fetch. There are effectively
45 // four options: all, active, suggested, and inactive. Only the first three
46 // appear in the enum since there hasn't been a need for 'inactive' yet.
48 // 'Inactive' means no key is bound. It might be because 1) a key wasn't
49 // specified (suggested) or 2) it was not granted (key already taken).
51 // SUGGESTED covers developer-assigned keys that may or may not have been
52 // granted. Reasons for not granting include permission denied/key already
55 // ACTIVE means developer-assigned keys that were granted or user-assigned
58 // ALL is all of the above.
65 // An enum specifying whether the command is global in scope or not. Global
66 // commands -- unlike regular commands -- have a global keyboard hook
67 // associated with them (and therefore work when Chrome doesn't have focus).
69 REGULAR
, // Regular (non-globally scoped) command.
70 GLOBAL
, // Global command (works when Chrome doesn't have focus)
71 ANY_SCOPE
, // All commands, regardless of scope (used when querying).
74 // An enum specifying the types of commands that can be used by an extension.
75 enum ExtensionCommandType
{
81 // Register prefs for keybinding.
82 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
84 // Constructs a CommandService object for the given profile.
85 explicit CommandService(content::BrowserContext
* context
);
86 ~CommandService() override
;
88 // BrowserContextKeyedAPI implementation.
89 static BrowserContextKeyedAPIFactory
<CommandService
>* GetFactoryInstance();
91 // Convenience method to get the CommandService for a profile.
92 static CommandService
* Get(content::BrowserContext
* context
);
94 // Returns true if |extension| is permitted to and does remove the bookmark
96 static bool RemovesBookmarkShortcut(const Extension
* extension
);
98 // Returns true if |extension| is permitted to and does remove the bookmark
99 // open pages shortcut key.
100 static bool RemovesBookmarkOpenPagesShortcut(const Extension
* extension
);
102 // Gets the command (if any) for the browser action of an extension given
103 // its |extension_id|. The function consults the master list to see if
104 // the command is active. Returns false if the extension has no browser
105 // action. Returns false if the command is not active and |type| requested
106 // is ACTIVE. |command| contains the command found and |active| (if not
107 // NULL) contains whether |command| is active.
108 bool GetBrowserActionCommand(const std::string
& extension_id
,
113 // Gets the command (if any) for the page action of an extension given
114 // its |extension_id|. The function consults the master list to see if
115 // the command is active. Returns false if the extension has no page
116 // action. Returns false if the command is not active and |type| requested
117 // is ACTIVE. |command| contains the command found and |active| (if not
118 // NULL) contains whether |command| is active.
119 bool GetPageActionCommand(const std::string
& extension_id
,
124 // Gets the active named commands (if any) for the extension with
125 // |extension_id|. The function consults the master list to see if the
126 // commands are active. Returns an empty map if the extension has no named
127 // commands of the right |scope| or no such active named commands when |type|
128 // requested is ACTIVE.
129 bool GetNamedCommands(const std::string
& extension_id
,
132 CommandMap
* command_map
) const;
134 // Records a keybinding |accelerator| as active for an extension with id
135 // |extension_id| and command with the name |command_name|. If
136 // |allow_overrides| is false, the keybinding must be free for the change to
137 // be recorded (as determined by the master list in |user_prefs|). If
138 // |allow_overwrites| is true, any previously recorded keybinding for this
139 // |accelerator| will be overwritten. If |global| is true, the command will
140 // be registered as a global command (be active even when Chrome does not have
141 // focus. Returns true if the change was successfully recorded.
142 bool AddKeybindingPref(const ui::Accelerator
& accelerator
,
143 std::string extension_id
,
144 std::string command_name
,
145 bool allow_overrides
,
148 // Removes all keybindings for a given extension by its |extension_id|.
149 // |command_name| is optional and if specified, causes only the command with
150 // the name |command_name| to be removed.
151 void RemoveKeybindingPrefs(const std::string
& extension_id
,
152 const std::string
& command_name
);
154 // Update the keybinding prefs (for a command with a matching |extension_id|
155 // and |command_name|) to |keystroke|. If the command had another key assigned
156 // that key assignment will be removed.
157 void UpdateKeybindingPrefs(const std::string
& extension_id
,
158 const std::string
& command_name
,
159 const std::string
& keystroke
);
161 // Set the scope of the keybinding. If |global| is true, the keybinding works
162 // even when Chrome does not have focus. If the scope requested is already
163 // set, the function returns false, otherwise true.
164 bool SetScope(const std::string
& extension_id
,
165 const std::string
& command_name
,
168 // Finds the command with the name |command_name| within an extension with id
169 // |extension_id| . Returns an empty Command object (with keycode
170 // VKEY_UNKNOWN) if the command is not found.
171 Command
FindCommandByName(const std::string
& extension_id
,
172 const std::string
& command
) const;
174 // If the extension with |extension_id| suggests the assignment of a command
175 // to |accelerator|, returns true and assigns the command to *|command|. Also
176 // assigns the type to *|command_type| if non-null.
177 bool GetSuggestedExtensionCommand(const std::string
& extension_id
,
178 const ui::Accelerator
& accelerator
,
180 ExtensionCommandType
* command_type
) const;
182 // Returns true if |extension| requests to override the bookmark shortcut key
183 // and should be allowed to do so.
184 bool RequestsBookmarkShortcutOverride(const Extension
* extension
) const;
187 friend class BrowserContextKeyedAPIFactory
<CommandService
>;
189 // BrowserContextKeyedAPI implementation.
190 static const char* service_name() {
191 return "CommandService";
193 static const bool kServiceRedirectedInIncognito
= true;
195 // ExtensionRegistryObserver.
196 void OnExtensionWillBeInstalled(content::BrowserContext
* browser_context
,
197 const Extension
* extension
,
200 const std::string
& old_name
) override
;
201 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
202 const Extension
* extension
,
203 extensions::UninstallReason reason
) override
;
205 // Updates keybindings for a given |extension|'s page action, browser action
206 // and named commands. Assigns new keybindings and removes relinquished
207 // keybindings if not changed by the user. In the case of adding keybindings,
208 // if the suggested keybinding is free, it will be taken by this extension. If
209 // not, the keybinding request is ignored.
210 void UpdateKeybindings(const Extension
* extension
);
212 // On update, removes keybindings that the extension previously suggested but
213 // now no longer does, as long as the user has not modified them.
214 void RemoveRelinquishedKeybindings(const Extension
* extension
);
216 // Assigns keybindings that the extension suggests, as long as they are not
218 void AssignKeybindings(const Extension
* extension
);
220 // Checks if |extension| is permitted to automatically assign the
221 // |accelerator| key.
222 bool CanAutoAssign(const Command
&command
,
223 const Extension
* extension
);
225 // Updates the record of |extension|'s most recent suggested command shortcut
226 // keys in the preferences.
227 void UpdateExtensionSuggestedCommandPrefs(const Extension
* extension
);
229 // Remove suggested key command prefs that apply to commands that have been
231 void RemoveDefunctExtensionSuggestedCommandPrefs(const Extension
* extension
);
233 // Returns true if the user modified a command's shortcut key from the
234 // |extension|-suggested value.
235 bool IsCommandShortcutUserModified(const Extension
* extension
,
236 const std::string
& command_name
);
238 // Returns true if the extension is changing the binding of |command_name| on
240 bool IsKeybindingChanging(const Extension
* extension
,
241 const std::string
& command_name
);
243 // Returns |extension|'s previous suggested key for |command_name| in the
244 // preferences, or the empty string if none.
245 std::string
GetSuggestedKeyPref(const Extension
* extension
,
246 const std::string
& command_name
);
248 bool GetExtensionActionCommand(const std::string
& extension_id
,
249 QueryType query_type
,
252 ExtensionCommandType action_type
) const;
254 // A weak pointer to the profile we are associated with. Not owned by us.
257 ScopedObserver
<ExtensionRegistry
, ExtensionRegistryObserver
>
258 extension_registry_observer_
;
260 DISALLOW_COPY_AND_ASSIGN(CommandService
);
265 BrowserContextKeyedAPIFactory
<CommandService
>::DeclareFactoryDependencies();
267 } // namespace extensions
269 #endif // CHROME_BROWSER_EXTENSIONS_API_COMMANDS_COMMAND_SERVICE_H_