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 "chrome/browser/extensions/api/profile_keyed_api_factory.h"
12 #include "chrome/common/extensions/command.h"
13 #include "chrome/common/extensions/extension.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"
22 class DictionaryValue;
29 namespace user_prefs {
30 class PrefRegistrySyncable;
33 namespace extensions {
35 // This service keeps track of preferences related to extension commands
36 // (assigning initial keybindings on install and removing them on deletion
37 // and answers questions related to which commands are active.
38 class CommandService : public ProfileKeyedAPI,
39 public content::NotificationObserver {
41 // An enum specifying whether to fetch all extension commands or only active
48 // An enum specifying whether the command is global in scope or not. Global
49 // commands -- unlike regular commands -- have a global keyboard hook
50 // associated with them (and therefore work when Chrome doesn't have focus).
52 REGULAR, // Regular (non-globally scoped) command.
53 GLOBAL, // Global command (works when Chrome doesn't have focus)
54 ANY_SCOPE, // All commands, regardless of scope (used when querying).
57 // Register prefs for keybinding.
58 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
60 // Constructs a CommandService object for the given profile.
61 explicit CommandService(Profile* profile);
62 virtual ~CommandService();
64 // ProfileKeyedAPI implementation.
65 static ProfileKeyedAPIFactory<CommandService>* GetFactoryInstance();
67 // Convenience method to get the CommandService for a profile.
68 static CommandService* Get(Profile* profile);
70 // Gets the command (if any) for the browser action of an extension given
71 // its |extension_id|. The function consults the master list to see if
72 // the command is active. Returns false if the extension has no browser
73 // action. Returns false if the command is not active and |type| requested
74 // is ACTIVE_ONLY. |command| contains the command found and |active| (if not
75 // NULL) contains whether |command| is active.
76 bool GetBrowserActionCommand(const std::string& extension_id,
78 extensions::Command* command,
81 // Gets the command (if any) for the page action of an extension given
82 // its |extension_id|. The function consults the master list to see if
83 // the command is active. Returns false if the extension has no page
84 // action. Returns false if the command is not active and |type| requested
85 // is ACTIVE_ONLY. |command| contains the command found and |active| (if not
86 // NULL) contains whether |command| is active.
87 bool GetPageActionCommand(const std::string& extension_id,
89 extensions::Command* command,
92 // Gets the command (if any) for the script badge of an extension given
93 // its |extension_id|. The function consults the master list to see if
94 // the command is active. Returns false if the extension has no script
95 // badge. Returns false if the command is not active and |type| requested
96 // is ACTIVE_ONLY. |command| contains the command found and |active| (if not
97 // NULL) contains whether |command| is active.
98 bool GetScriptBadgeCommand(const std::string& extension_id,
100 extensions::Command* command,
103 // Gets the active command (if any) for the named commands of an extension
104 // given its |extension_id|. The function consults the master list to see if
105 // the command is active. Returns an empty map if the extension has no
106 // named commands of the right |scope| or no such active named commands when
107 // |type| requested is ACTIVE_ONLY.
108 bool GetNamedCommands(const std::string& extension_id,
111 extensions::CommandMap* command_map);
113 // Records a keybinding |accelerator| as active for an extension with id
114 // |extension_id| and command with the name |command_name|. If
115 // |allow_overrides| is false, the keybinding must be free for the change to
116 // be recorded (as determined by the master list in |user_prefs|). If
117 // |allow_overwrites| is true, any previously recorded keybinding for this
118 // |accelerator| will be overwritten. If |global| is true, the command will
119 // be registered as a global command (be active even when Chrome does not have
120 // focus. Returns true if the change was successfully recorded.
121 bool AddKeybindingPref(const ui::Accelerator& accelerator,
122 std::string extension_id,
123 std::string command_name,
124 bool allow_overrides,
127 // Removes all keybindings for a given extension by its |extension_id|.
128 // |command_name| is optional and if specified, causes only the command with
129 // the name |command_name| to be removed.
130 void RemoveKeybindingPrefs(const std::string& extension_id,
131 const std::string& command_name);
133 // Update the keybinding prefs (for a command with a matching |extension_id|
134 // and |command_name|) to |keystroke|. If the command had another key assigned
135 // that key assignment will be removed.
136 void UpdateKeybindingPrefs(const std::string& extension_id,
137 const std::string& command_name,
138 const std::string& keystroke);
140 // Set the scope of the keybinding. If |global| is true, the keybinding works
141 // even when Chrome does not have focus. If the scope requested is already
142 // set, the function returns false, otherwise true.
143 bool SetScope(const std::string& extension_id,
144 const std::string& command_name,
147 // Finds the command with the name |command_name| within an extension with id
148 // |extension_id| . Returns an empty Command object (with keycode
149 // VKEY_UNKNOWN) if the command is not found.
150 Command FindCommandByName(const std::string& extension_id,
151 const std::string& command);
153 // Overridden from content::NotificationObserver.
154 virtual void Observe(int type,
155 const content::NotificationSource& source,
156 const content::NotificationDetails& details) OVERRIDE;
159 friend class ProfileKeyedAPIFactory<CommandService>;
161 // ProfileKeyedAPI implementation.
162 static const char* service_name() {
163 return "CommandService";
165 static const bool kServiceRedirectedInIncognito = true;
167 // An enum specifying the types of icons that can have a command.
168 enum ExtensionActionType {
174 // Assigns initial keybinding for a given |extension|'s page action, browser
175 // action and named commands. In each case, if the suggested keybinding is
176 // free, it will be taken by this extension. If not, that keybinding request
177 // is ignored. |user_pref| is the PrefService used to record the new
178 // keybinding assignment.
179 void AssignInitialKeybindings(const extensions::Extension* extension);
181 bool GetExtensionActionCommand(const std::string& extension_id,
182 QueryType query_type,
183 extensions::Command* command,
185 ExtensionActionType action_type);
187 // The content notification registrar for listening to extension events.
188 content::NotificationRegistrar registrar_;
190 // A weak pointer to the profile we are associated with. Not owned by us.
193 DISALLOW_COPY_AND_ASSIGN(CommandService);
197 void ProfileKeyedAPIFactory<CommandService>::DeclareFactoryDependencies();
199 } // namespace extensions
201 #endif // CHROME_BROWSER_EXTENSIONS_API_COMMANDS_COMMAND_SERVICE_H_