Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / commands / command_service.h
blobcda73eeca63566a0f8b3f36a3384c9485fbd8b96
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_
8 #include <string>
10 #include "base/basictypes.h"
11 #include "base/observer_list.h"
12 #include "base/scoped_observer.h"
13 #include "chrome/common/extensions/command.h"
14 #include "extensions/browser/browser_context_keyed_api_factory.h"
15 #include "extensions/browser/extension_registry_observer.h"
16 #include "extensions/common/extension.h"
18 class Profile;
20 namespace base {
21 class DictionaryValue;
24 namespace content {
25 class BrowserContext;
28 namespace ui {
29 class Accelerator;
32 namespace user_prefs {
33 class PrefRegistrySyncable;
36 namespace extensions {
37 class ExtensionRegistry;
39 // This service keeps track of preferences related to extension commands
40 // (assigning initial keybindings on install and removing them on deletion
41 // and answers questions related to which commands are active.
42 class CommandService : public BrowserContextKeyedAPI,
43 public ExtensionRegistryObserver {
44 public:
45 // An enum specifying which extension commands to fetch. There are effectively
46 // four options: all, active, suggested, and inactive. Only the first three
47 // appear in the enum since there hasn't been a need for 'inactive' yet.
49 // 'Inactive' means no key is bound. It might be because 1) a key wasn't
50 // specified (suggested) or 2) it was not granted (key already taken).
52 // SUGGESTED covers developer-assigned keys that may or may not have been
53 // granted. Reasons for not granting include permission denied/key already
54 // taken.
56 // ACTIVE means developer-assigned keys that were granted or user-assigned
57 // keys.
59 // ALL is all of the above.
60 enum QueryType {
61 ALL,
62 ACTIVE,
63 SUGGESTED,
66 // An enum specifying whether the command is global in scope or not. Global
67 // commands -- unlike regular commands -- have a global keyboard hook
68 // associated with them (and therefore work when Chrome doesn't have focus).
69 enum CommandScope {
70 REGULAR, // Regular (non-globally scoped) command.
71 GLOBAL, // Global command (works when Chrome doesn't have focus)
72 ANY_SCOPE, // All commands, regardless of scope (used when querying).
75 // An enum specifying the types of commands that can be used by an extension.
76 enum ExtensionCommandType {
77 NAMED,
78 BROWSER_ACTION,
79 PAGE_ACTION
82 class Observer {
83 public:
84 // Called when an extension command is added.
85 virtual void OnExtensionCommandAdded(const std::string& extension_id,
86 const Command& command) {}
88 // Called when an extension command is removed.
89 virtual void OnExtensionCommandRemoved(const std::string& extension_id,
90 const Command& command) {}
91 protected:
92 virtual ~Observer() {}
95 // Register prefs for keybinding.
96 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
98 // Constructs a CommandService object for the given profile.
99 explicit CommandService(content::BrowserContext* context);
100 ~CommandService() override;
102 // BrowserContextKeyedAPI implementation.
103 static BrowserContextKeyedAPIFactory<CommandService>* GetFactoryInstance();
105 // Convenience method to get the CommandService for a profile.
106 static CommandService* Get(content::BrowserContext* context);
108 // Returns true if |extension| is permitted to and does remove the bookmark
109 // shortcut key.
110 static bool RemovesBookmarkShortcut(const Extension* extension);
112 // Returns true if |extension| is permitted to and does remove the bookmark
113 // open pages shortcut key.
114 static bool RemovesBookmarkOpenPagesShortcut(const Extension* extension);
116 // Gets the command (if any) for the browser action of an extension given
117 // its |extension_id|. The function consults the master list to see if
118 // the command is active. Returns false if the extension has no browser
119 // action. Returns false if the command is not active and |type| requested
120 // is ACTIVE. |command| contains the command found and |active| (if not
121 // NULL) contains whether |command| is active.
122 bool GetBrowserActionCommand(const std::string& extension_id,
123 QueryType type,
124 Command* command,
125 bool* active) const;
127 // Gets the command (if any) for the page action of an extension given
128 // its |extension_id|. The function consults the master list to see if
129 // the command is active. Returns false if the extension has no page
130 // action. Returns false if the command is not active and |type| requested
131 // is ACTIVE. |command| contains the command found and |active| (if not
132 // NULL) contains whether |command| is active.
133 bool GetPageActionCommand(const std::string& extension_id,
134 QueryType type,
135 Command* command,
136 bool* active) const;
138 // Gets the active named commands (if any) for the extension with
139 // |extension_id|. The function consults the master list to see if the
140 // commands are active. Returns an empty map if the extension has no named
141 // commands of the right |scope| or no such active named commands when |type|
142 // requested is ACTIVE.
143 bool GetNamedCommands(const std::string& extension_id,
144 QueryType type,
145 CommandScope scope,
146 CommandMap* command_map) const;
148 // Records a keybinding |accelerator| as active for an extension with id
149 // |extension_id| and command with the name |command_name|. If
150 // |allow_overrides| is false, the keybinding must be free for the change to
151 // be recorded (as determined by the master list in |user_prefs|). If
152 // |allow_overwrites| is true, any previously recorded keybinding for this
153 // |accelerator| will be overwritten. If |global| is true, the command will
154 // be registered as a global command (be active even when Chrome does not have
155 // focus. Returns true if the change was successfully recorded.
156 bool AddKeybindingPref(const ui::Accelerator& accelerator,
157 const std::string& extension_id,
158 const std::string& command_name,
159 bool allow_overrides,
160 bool global);
162 // Removes all keybindings for a given extension by its |extension_id|.
163 // |command_name| is optional and if specified, causes only the command with
164 // the name |command_name| to be removed.
165 void RemoveKeybindingPrefs(const std::string& extension_id,
166 const std::string& command_name);
168 // Update the keybinding prefs (for a command with a matching |extension_id|
169 // and |command_name|) to |keystroke|. If the command had another key assigned
170 // that key assignment will be removed.
171 void UpdateKeybindingPrefs(const std::string& extension_id,
172 const std::string& command_name,
173 const std::string& keystroke);
175 // Set the scope of the keybinding. If |global| is true, the keybinding works
176 // even when Chrome does not have focus. If the scope requested is already
177 // set, the function returns false, otherwise true.
178 bool SetScope(const std::string& extension_id,
179 const std::string& command_name,
180 bool global);
182 // Finds the command with the name |command_name| within an extension with id
183 // |extension_id| . Returns an empty Command object (with keycode
184 // VKEY_UNKNOWN) if the command is not found.
185 Command FindCommandByName(const std::string& extension_id,
186 const std::string& command) const;
188 // If the extension with |extension_id| suggests the assignment of a command
189 // to |accelerator|, returns true and assigns the command to *|command|. Also
190 // assigns the type to *|command_type| if non-null.
191 bool GetSuggestedExtensionCommand(const std::string& extension_id,
192 const ui::Accelerator& accelerator,
193 Command* command,
194 ExtensionCommandType* command_type) const;
196 // Returns true if |extension| requests to override the bookmark shortcut key
197 // and should be allowed to do so.
198 bool RequestsBookmarkShortcutOverride(const Extension* extension) const;
200 void AddObserver(Observer* observer);
201 void RemoveObserver(Observer* observer);
203 private:
204 friend class BrowserContextKeyedAPIFactory<CommandService>;
206 // BrowserContextKeyedAPI implementation.
207 static const char* service_name() {
208 return "CommandService";
210 static const bool kServiceRedirectedInIncognito = true;
212 // ExtensionRegistryObserver.
213 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
214 const Extension* extension,
215 bool is_update,
216 bool from_ephemeral,
217 const std::string& old_name) override;
218 void OnExtensionUninstalled(content::BrowserContext* browser_context,
219 const Extension* extension,
220 extensions::UninstallReason reason) override;
222 // Updates keybindings for a given |extension|'s page action, browser action
223 // and named commands. Assigns new keybindings and removes relinquished
224 // keybindings if not changed by the user. In the case of adding keybindings,
225 // if the suggested keybinding is free, it will be taken by this extension. If
226 // not, the keybinding request is ignored.
227 void UpdateKeybindings(const Extension* extension);
229 // On update, removes keybindings that the extension previously suggested but
230 // now no longer does, as long as the user has not modified them.
231 void RemoveRelinquishedKeybindings(const Extension* extension);
233 // Assigns keybindings that the extension suggests, as long as they are not
234 // already assigned.
235 void AssignKeybindings(const Extension* extension);
237 // Checks if |extension| is permitted to automatically assign the
238 // |accelerator| key.
239 bool CanAutoAssign(const Command &command,
240 const Extension* extension);
242 // Updates the record of |extension|'s most recent suggested command shortcut
243 // keys in the preferences.
244 void UpdateExtensionSuggestedCommandPrefs(const Extension* extension);
246 // Remove suggested key command prefs that apply to commands that have been
247 // removed.
248 void RemoveDefunctExtensionSuggestedCommandPrefs(const Extension* extension);
250 // Returns true if the user modified a command's shortcut key from the
251 // |extension|-suggested value.
252 bool IsCommandShortcutUserModified(const Extension* extension,
253 const std::string& command_name);
255 // Returns true if the extension is changing the binding of |command_name| on
256 // install.
257 bool IsKeybindingChanging(const Extension* extension,
258 const std::string& command_name);
260 // Returns |extension|'s previous suggested key for |command_name| in the
261 // preferences, or the empty string if none.
262 std::string GetSuggestedKeyPref(const Extension* extension,
263 const std::string& command_name);
265 bool GetExtensionActionCommand(const std::string& extension_id,
266 QueryType query_type,
267 Command* command,
268 bool* active,
269 ExtensionCommandType action_type) const;
271 // A weak pointer to the profile we are associated with. Not owned by us.
272 Profile* profile_;
274 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
275 extension_registry_observer_;
277 base::ObserverList<Observer> observers_;
279 DISALLOW_COPY_AND_ASSIGN(CommandService);
282 template <>
283 void
284 BrowserContextKeyedAPIFactory<CommandService>::DeclareFactoryDependencies();
286 } // namespace extensions
288 #endif // CHROME_BROWSER_EXTENSIONS_API_COMMANDS_COMMAND_SERVICE_H_