OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/commands/extension_command_service.h" | 5 #include "chrome/browser/extensions/api/commands/command_service.h" |
6 | 6 |
7 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
8 #include "chrome/browser/extensions/extension_keybinding_registry.h" | 8 #include "chrome/browser/extensions/extension_keybinding_registry.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/extensions/extension_system.h" | 10 #include "chrome/browser/extensions/extension_system.h" |
11 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 11 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/common/chrome_notification_types.h" | 13 #include "chrome/common/chrome_notification_types.h" |
14 #include "chrome/common/pref_names.h" | 14 #include "chrome/common/pref_names.h" |
15 #include "content/public/browser/notification_service.h" | 15 #include "content/public/browser/notification_service.h" |
16 | 16 |
17 using extensions::Extension; | 17 using extensions::Extension; |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 const char kExtension[] = "extension"; | 21 const char kExtension[] = "extension"; |
22 const char kCommandName[] = "command_name"; | 22 const char kCommandName[] = "command_name"; |
23 | 23 |
24 std::string GetPlatformKeybindingKeyForAccelerator( | 24 std::string GetPlatformKeybindingKeyForAccelerator( |
25 const ui::Accelerator& accelerator) { | 25 const ui::Accelerator& accelerator) { |
26 return extensions::Command::CommandPlatform() + ":" + | 26 return extensions::Command::CommandPlatform() + ":" + |
27 UTF16ToUTF8(accelerator.GetShortcutText()); | 27 UTF16ToUTF8(accelerator.GetShortcutText()); |
28 } | 28 } |
29 | 29 |
30 } // namespace | 30 } // namespace |
31 | 31 |
32 namespace extensions { | 32 namespace extensions { |
33 | 33 |
34 // static | 34 // static |
35 void ExtensionCommandService::RegisterUserPrefs( | 35 void CommandService::RegisterUserPrefs( |
36 PrefService* user_prefs) { | 36 PrefService* user_prefs) { |
37 user_prefs->RegisterDictionaryPref(prefs::kExtensionKeybindings, | 37 user_prefs->RegisterDictionaryPref(prefs::kExtensionKeybindings, |
38 PrefService::SYNCABLE_PREF); | 38 PrefService::SYNCABLE_PREF); |
39 } | 39 } |
40 | 40 |
41 ExtensionCommandService::ExtensionCommandService( | 41 CommandService::CommandService(Profile* profile) |
42 Profile* profile) | |
43 : profile_(profile) { | 42 : profile_(profile) { |
44 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, | 43 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, |
45 content::Source<Profile>(profile)); | 44 content::Source<Profile>(profile)); |
46 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 45 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
47 content::Source<Profile>(profile)); | 46 content::Source<Profile>(profile)); |
48 } | 47 } |
49 | 48 |
50 ExtensionCommandService::~ExtensionCommandService() { | 49 CommandService::~CommandService() { |
51 } | 50 } |
52 | 51 |
53 const extensions::Command* | 52 const extensions::Command* CommandService::GetBrowserActionCommand( |
54 ExtensionCommandService::GetBrowserActionCommand( | 53 const std::string& extension_id, QueryType type) { |
55 const std::string& extension_id, QueryType type) { | |
56 const ExtensionSet* extensions = | 54 const ExtensionSet* extensions = |
57 ExtensionSystem::Get(profile_)->extension_service()->extensions(); | 55 ExtensionSystem::Get(profile_)->extension_service()->extensions(); |
58 const Extension* extension = extensions->GetByID(extension_id); | 56 const Extension* extension = extensions->GetByID(extension_id); |
59 CHECK(extension); | 57 CHECK(extension); |
60 | 58 |
61 const extensions::Command* command = extension->browser_action_command(); | 59 const extensions::Command* command = extension->browser_action_command(); |
62 if (!command) | 60 if (!command) |
63 return NULL; | 61 return NULL; |
64 if (type == ACTIVE_ONLY && | 62 if (type == ACTIVE_ONLY && |
65 !IsKeybindingActive(command->accelerator(), | 63 !IsKeybindingActive(command->accelerator(), |
66 extension_id, | 64 extension_id, |
67 command->command_name())) { | 65 command->command_name())) { |
68 return NULL; | 66 return NULL; |
69 } | 67 } |
70 | 68 |
71 return command; | 69 return command; |
72 } | 70 } |
73 | 71 |
74 const extensions::Command* ExtensionCommandService::GetPageActionCommand( | 72 const extensions::Command* CommandService::GetPageActionCommand( |
75 const std::string& extension_id, QueryType type) { | 73 const std::string& extension_id, QueryType type) { |
76 const ExtensionSet* extensions = | 74 const ExtensionSet* extensions = |
77 ExtensionSystem::Get(profile_)->extension_service()->extensions(); | 75 ExtensionSystem::Get(profile_)->extension_service()->extensions(); |
78 const Extension* extension = extensions->GetByID(extension_id); | 76 const Extension* extension = extensions->GetByID(extension_id); |
79 CHECK(extension); | 77 CHECK(extension); |
80 | 78 |
81 const extensions::Command* command = extension->page_action_command(); | 79 const extensions::Command* command = extension->page_action_command(); |
82 if (!command) | 80 if (!command) |
83 return NULL; | 81 return NULL; |
84 if (type == ACTIVE_ONLY && | 82 if (type == ACTIVE_ONLY && |
85 !IsKeybindingActive(command->accelerator(), | 83 !IsKeybindingActive(command->accelerator(), |
86 extension_id, | 84 extension_id, |
87 command->command_name())) { | 85 command->command_name())) { |
88 return NULL; | 86 return NULL; |
89 } | 87 } |
90 | 88 |
91 return command; | 89 return command; |
92 } | 90 } |
93 | 91 |
94 extensions::CommandMap ExtensionCommandService::GetNamedCommands( | 92 extensions::CommandMap CommandService::GetNamedCommands( |
95 const std::string& extension_id, QueryType type) { | 93 const std::string& extension_id, QueryType type) { |
96 const ExtensionSet* extensions = | 94 const ExtensionSet* extensions = |
97 ExtensionSystem::Get(profile_)->extension_service()->extensions(); | 95 ExtensionSystem::Get(profile_)->extension_service()->extensions(); |
98 const Extension* extension = extensions->GetByID(extension_id); | 96 const Extension* extension = extensions->GetByID(extension_id); |
99 CHECK(extension); | 97 CHECK(extension); |
100 | 98 |
101 extensions::CommandMap result; | 99 extensions::CommandMap result; |
102 const extensions::CommandMap& commands = extension->named_commands(); | 100 const extensions::CommandMap& commands = extension->named_commands(); |
103 if (commands.empty()) | 101 if (commands.empty()) |
104 return result; | 102 return result; |
105 | 103 |
106 extensions::CommandMap::const_iterator iter = commands.begin(); | 104 extensions::CommandMap::const_iterator iter = commands.begin(); |
107 for (; iter != commands.end(); ++iter) { | 105 for (; iter != commands.end(); ++iter) { |
108 if (type == ACTIVE_ONLY && | 106 if (type == ACTIVE_ONLY && |
109 !IsKeybindingActive(iter->second.accelerator(), | 107 !IsKeybindingActive(iter->second.accelerator(), |
110 extension_id, | 108 extension_id, |
111 iter->second.command_name())) { | 109 iter->second.command_name())) { |
112 continue; | 110 continue; |
113 } | 111 } |
114 | 112 |
115 result[iter->second.command_name()] = iter->second; | 113 result[iter->second.command_name()] = iter->second; |
116 } | 114 } |
117 | 115 |
118 return result; | 116 return result; |
119 } | 117 } |
120 | 118 |
121 bool ExtensionCommandService::IsKeybindingActive( | 119 bool CommandService::IsKeybindingActive( |
122 const ui::Accelerator& accelerator, | 120 const ui::Accelerator& accelerator, |
123 const std::string& extension_id, | 121 const std::string& extension_id, |
124 const std::string& command_name) const { | 122 const std::string& command_name) const { |
125 CHECK(!extension_id.empty()); | 123 CHECK(!extension_id.empty()); |
126 CHECK(!command_name.empty()); | 124 CHECK(!command_name.empty()); |
127 | 125 |
128 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator); | 126 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator); |
129 const DictionaryValue* bindings = | 127 const DictionaryValue* bindings = |
130 profile_->GetPrefs()->GetDictionary(prefs::kExtensionKeybindings); | 128 profile_->GetPrefs()->GetDictionary(prefs::kExtensionKeybindings); |
131 if (!bindings->HasKey(key)) | 129 if (!bindings->HasKey(key)) |
132 return false; | 130 return false; |
133 | 131 |
134 DictionaryValue* value = NULL; | 132 DictionaryValue* value = NULL; |
135 if (!bindings->GetDictionary(key, &value)) | 133 if (!bindings->GetDictionary(key, &value)) |
136 return false; | 134 return false; |
137 | 135 |
138 std::string id; | 136 std::string id; |
139 if (!value->GetString(kExtension, &id) || id != extension_id) | 137 if (!value->GetString(kExtension, &id) || id != extension_id) |
140 return false; // Not active for this extension. | 138 return false; // Not active for this extension. |
141 | 139 |
142 std::string command; | 140 std::string command; |
143 if (!value->GetString(kCommandName, &command) || command != command_name) | 141 if (!value->GetString(kCommandName, &command) || command != command_name) |
144 return false; // Not active for this command. | 142 return false; // Not active for this command. |
145 | 143 |
146 return true; // We found a match, this one is active. | 144 return true; // We found a match, this one is active. |
147 } | 145 } |
148 | 146 |
149 bool ExtensionCommandService::AddKeybindingPref( | 147 bool CommandService::AddKeybindingPref( |
150 const ui::Accelerator& accelerator, | 148 const ui::Accelerator& accelerator, |
151 std::string extension_id, | 149 std::string extension_id, |
152 std::string command_name, | 150 std::string command_name, |
153 bool allow_overrides) { | 151 bool allow_overrides) { |
154 DictionaryPrefUpdate updater(profile_->GetPrefs(), | 152 DictionaryPrefUpdate updater(profile_->GetPrefs(), |
155 prefs::kExtensionKeybindings); | 153 prefs::kExtensionKeybindings); |
156 DictionaryValue* bindings = updater.Get(); | 154 DictionaryValue* bindings = updater.Get(); |
157 | 155 |
158 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator); | 156 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator); |
159 if (bindings->HasKey(key) && !allow_overrides) | 157 if (bindings->HasKey(key) && !allow_overrides) |
160 return false; // Already taken. | 158 return false; // Already taken. |
161 | 159 |
162 DictionaryValue* keybinding = new DictionaryValue(); | 160 DictionaryValue* keybinding = new DictionaryValue(); |
163 keybinding->SetString(kExtension, extension_id); | 161 keybinding->SetString(kExtension, extension_id); |
164 keybinding->SetString(kCommandName, command_name); | 162 keybinding->SetString(kCommandName, command_name); |
165 | 163 |
166 bindings->Set(key, keybinding); | 164 bindings->Set(key, keybinding); |
167 return true; | 165 return true; |
168 } | 166 } |
169 | 167 |
170 void ExtensionCommandService::Observe( | 168 void CommandService::Observe( |
171 int type, | 169 int type, |
172 const content::NotificationSource& source, | 170 const content::NotificationSource& source, |
173 const content::NotificationDetails& details) { | 171 const content::NotificationDetails& details) { |
174 switch (type) { | 172 switch (type) { |
175 case chrome::NOTIFICATION_EXTENSION_INSTALLED: | 173 case chrome::NOTIFICATION_EXTENSION_INSTALLED: |
176 AssignInitialKeybindings( | 174 AssignInitialKeybindings( |
177 content::Details<const Extension>(details).ptr()); | 175 content::Details<const Extension>(details).ptr()); |
178 break; | 176 break; |
179 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: | 177 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: |
180 RemoveKeybindingPrefs(*content::Details<std::string>(details).ptr()); | 178 RemoveKeybindingPrefs(*content::Details<std::string>(details).ptr()); |
181 break; | 179 break; |
182 default: | 180 default: |
183 NOTREACHED(); | 181 NOTREACHED(); |
184 break; | 182 break; |
185 } | 183 } |
186 } | 184 } |
187 | 185 |
188 void ExtensionCommandService::AssignInitialKeybindings( | 186 void CommandService::AssignInitialKeybindings(const Extension* extension) { |
189 const Extension* extension) { | |
190 const extensions::CommandMap& commands = extension->named_commands(); | 187 const extensions::CommandMap& commands = extension->named_commands(); |
191 extensions::CommandMap::const_iterator iter = commands.begin(); | 188 extensions::CommandMap::const_iterator iter = commands.begin(); |
192 for (; iter != commands.end(); ++iter) { | 189 for (; iter != commands.end(); ++iter) { |
193 AddKeybindingPref(iter->second.accelerator(), | 190 AddKeybindingPref(iter->second.accelerator(), |
194 extension->id(), | 191 extension->id(), |
195 iter->second.command_name(), | 192 iter->second.command_name(), |
196 false); // Overwriting not allowed. | 193 false); // Overwriting not allowed. |
197 } | 194 } |
198 | 195 |
199 const extensions::Command* browser_action_command = | 196 const extensions::Command* browser_action_command = |
200 extension->browser_action_command(); | 197 extension->browser_action_command(); |
201 if (browser_action_command) { | 198 if (browser_action_command) { |
202 AddKeybindingPref(browser_action_command->accelerator(), | 199 AddKeybindingPref(browser_action_command->accelerator(), |
203 extension->id(), | 200 extension->id(), |
204 browser_action_command->command_name(), | 201 browser_action_command->command_name(), |
205 false); // Overwriting not allowed. | 202 false); // Overwriting not allowed. |
206 } | 203 } |
207 | 204 |
208 const extensions::Command* page_action_command = | 205 const extensions::Command* page_action_command = |
209 extension->page_action_command(); | 206 extension->page_action_command(); |
210 if (page_action_command) { | 207 if (page_action_command) { |
211 AddKeybindingPref(page_action_command->accelerator(), | 208 AddKeybindingPref(page_action_command->accelerator(), |
212 extension->id(), | 209 extension->id(), |
213 page_action_command->command_name(), | 210 page_action_command->command_name(), |
214 false); // Overwriting not allowed. | 211 false); // Overwriting not allowed. |
215 } | 212 } |
216 } | 213 } |
217 | 214 |
218 void ExtensionCommandService::RemoveKeybindingPrefs(std::string extension_id) { | 215 void CommandService::RemoveKeybindingPrefs(std::string extension_id) { |
219 DictionaryPrefUpdate updater(profile_->GetPrefs(), | 216 DictionaryPrefUpdate updater(profile_->GetPrefs(), |
220 prefs::kExtensionKeybindings); | 217 prefs::kExtensionKeybindings); |
221 DictionaryValue* bindings = updater.Get(); | 218 DictionaryValue* bindings = updater.Get(); |
222 | 219 |
223 typedef std::vector<std::string> KeysToRemove; | 220 typedef std::vector<std::string> KeysToRemove; |
224 KeysToRemove keys_to_remove; | 221 KeysToRemove keys_to_remove; |
225 for (DictionaryValue::key_iterator it = bindings->begin_keys(); | 222 for (DictionaryValue::key_iterator it = bindings->begin_keys(); |
226 it != bindings->end_keys(); ++it) { | 223 it != bindings->end_keys(); ++it) { |
227 std::string key = *it; | 224 std::string key = *it; |
228 DictionaryValue* item = NULL; | 225 DictionaryValue* item = NULL; |
229 bindings->GetDictionary(key, &item); | 226 bindings->GetDictionary(key, &item); |
230 | 227 |
231 std::string extension; | 228 std::string extension; |
232 item->GetString(kExtension, &extension); | 229 item->GetString(kExtension, &extension); |
233 if (extension == extension_id) | 230 if (extension == extension_id) |
234 keys_to_remove.push_back(key); | 231 keys_to_remove.push_back(key); |
235 } | 232 } |
236 | 233 |
237 for (KeysToRemove::const_iterator it = keys_to_remove.begin(); | 234 for (KeysToRemove::const_iterator it = keys_to_remove.begin(); |
238 it != keys_to_remove.end(); ++it) { | 235 it != keys_to_remove.end(); ++it) { |
239 bindings->Remove(*it, NULL); | 236 bindings->Remove(*it, NULL); |
240 } | 237 } |
241 } | 238 } |
242 | 239 |
243 } // namespace extensions | 240 } // namespace extensions |
OLD | NEW |