Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(513)

Side by Side Diff: chrome/browser/extensions/api/commands/command_service.cc

Issue 64273008: [Windows] Finish global and non-global media keys support on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: gclient sync. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/command_service.h" 5 #include "chrome/browser/extensions/api/commands/command_service.h"
6 6
7 #include <vector>
8
7 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
8 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/strings/string_split.h"
9 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/api/commands/commands.h" 15 #include "chrome/browser/extensions/api/commands/commands.h"
13 #include "chrome/browser/extensions/extension_commands_global_registry.h" 16 #include "chrome/browser/extensions/extension_commands_global_registry.h"
14 #include "chrome/browser/extensions/extension_function_registry.h" 17 #include "chrome/browser/extensions/extension_function_registry.h"
15 #include "chrome/browser/extensions/extension_keybinding_registry.h" 18 #include "chrome/browser/extensions/extension_keybinding_registry.h"
16 #include "chrome/browser/extensions/extension_service.h" 19 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_system.h" 20 #include "chrome/browser/extensions/extension_system.h"
18 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/accelerator_utils.h" 22 #include "chrome/browser/ui/accelerator_utils.h"
20 #include "chrome/common/extensions/api/commands/commands_handler.h" 23 #include "chrome/common/extensions/api/commands/commands_handler.h"
21 #include "chrome/common/pref_names.h" 24 #include "chrome/common/pref_names.h"
22 #include "components/user_prefs/pref_registry_syncable.h" 25 #include "components/user_prefs/pref_registry_syncable.h"
23 #include "content/public/browser/notification_details.h" 26 #include "content/public/browser/notification_details.h"
24 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
25 #include "extensions/common/feature_switch.h" 28 #include "extensions/common/feature_switch.h"
29 #include "extensions/common/manifest_constants.h"
26 30
27 using extensions::Extension; 31 using extensions::Extension;
28 using extensions::ExtensionPrefs; 32 using extensions::ExtensionPrefs;
29 33
30 namespace { 34 namespace {
31 35
32 const char kExtension[] = "extension"; 36 const char kExtension[] = "extension";
33 const char kCommandName[] = "command_name"; 37 const char kCommandName[] = "command_name";
34 const char kGlobal[] = "global"; 38 const char kGlobal[] = "global";
35 39
36 // A preference that indicates that the initial keybindings for the given 40 // A preference that indicates that the initial keybindings for the given
37 // extension have been set. 41 // extension have been set.
38 const char kInitialBindingsHaveBeenAssigned[] = "initial_keybindings_set"; 42 const char kInitialBindingsHaveBeenAssigned[] = "initial_keybindings_set";
39 43
40 std::string GetPlatformKeybindingKeyForAccelerator( 44 std::string GetPlatformKeybindingKeyForAccelerator(
41 const ui::Accelerator& accelerator) { 45 const ui::Accelerator& accelerator, const std::string extension_id) {
42 return extensions::Command::CommandPlatform() + ":" + 46 std::string key = extensions::Command::CommandPlatform() + ":" +
43 extensions::Command::AcceleratorToString(accelerator); 47 extensions::Command::AcceleratorToString(accelerator);
48
49 // Media keys have a 1-to-many relationship with targets, unlike regular
50 // shortcut (1-to-1 relationship). That means two or more extensions can
51 // register for the same media key so the extension ID needs to be added to
52 // the key to make sure the key is unique.
53 if (extensions::CommandService::IsMediaKey(accelerator))
54 key += ":" + extension_id;
55
56 return key;
44 } 57 }
45 58
46 void SetInitialBindingsHaveBeenAssigned( 59 void SetInitialBindingsHaveBeenAssigned(
47 ExtensionPrefs* prefs, const std::string& extension_id) { 60 ExtensionPrefs* prefs, const std::string& extension_id) {
48 prefs->UpdateExtensionPref(extension_id, kInitialBindingsHaveBeenAssigned, 61 prefs->UpdateExtensionPref(extension_id, kInitialBindingsHaveBeenAssigned,
49 new base::FundamentalValue(true)); 62 new base::FundamentalValue(true));
50 } 63 }
51 64
52 bool InitialBindingsHaveBeenAssigned( 65 bool InitialBindingsHaveBeenAssigned(
53 const ExtensionPrefs* prefs, const std::string& extension_id) { 66 const ExtensionPrefs* prefs, const std::string& extension_id) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // static 116 // static
104 ProfileKeyedAPIFactory<CommandService>* CommandService::GetFactoryInstance() { 117 ProfileKeyedAPIFactory<CommandService>* CommandService::GetFactoryInstance() {
105 return &g_factory.Get(); 118 return &g_factory.Get();
106 } 119 }
107 120
108 // static 121 // static
109 CommandService* CommandService::Get(Profile* profile) { 122 CommandService* CommandService::Get(Profile* profile) {
110 return ProfileKeyedAPIFactory<CommandService>::GetForProfile(profile); 123 return ProfileKeyedAPIFactory<CommandService>::GetForProfile(profile);
111 } 124 }
112 125
126 // static
127 bool CommandService::IsMediaKey(const ui::Accelerator& accelerator) {
128 if (accelerator.modifiers() != 0)
129 return false;
130
131 return (accelerator.key_code() == ui::VKEY_MEDIA_NEXT_TRACK ||
132 accelerator.key_code() == ui::VKEY_MEDIA_PREV_TRACK ||
133 accelerator.key_code() == ui::VKEY_MEDIA_PLAY_PAUSE ||
134 accelerator.key_code() == ui::VKEY_MEDIA_STOP);
135 }
136
113 bool CommandService::GetBrowserActionCommand( 137 bool CommandService::GetBrowserActionCommand(
114 const std::string& extension_id, 138 const std::string& extension_id,
115 QueryType type, 139 QueryType type,
116 extensions::Command* command, 140 extensions::Command* command,
117 bool* active) { 141 bool* active) {
118 return GetExtensionActionCommand( 142 return GetExtensionActionCommand(
119 extension_id, type, command, active, BROWSER_ACTION); 143 extension_id, type, command, active, BROWSER_ACTION);
120 } 144 }
121 145
122 bool CommandService::GetPageActionCommand( 146 bool CommandService::GetPageActionCommand(
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 205
182 bool CommandService::AddKeybindingPref( 206 bool CommandService::AddKeybindingPref(
183 const ui::Accelerator& accelerator, 207 const ui::Accelerator& accelerator,
184 std::string extension_id, 208 std::string extension_id,
185 std::string command_name, 209 std::string command_name,
186 bool allow_overrides, 210 bool allow_overrides,
187 bool global) { 211 bool global) {
188 if (accelerator.key_code() == ui::VKEY_UNKNOWN) 212 if (accelerator.key_code() == ui::VKEY_UNKNOWN)
189 return false; 213 return false;
190 214
215 // Media Keys are allowed to be used by named command only.
216 DCHECK(!IsMediaKey(accelerator) ||
217 (command_name != manifest_values::kPageActionCommandEvent &&
218 command_name != manifest_values::kBrowserActionCommandEvent &&
219 command_name != manifest_values::kScriptBadgeCommandEvent));
220
191 DictionaryPrefUpdate updater(profile_->GetPrefs(), 221 DictionaryPrefUpdate updater(profile_->GetPrefs(),
192 prefs::kExtensionCommands); 222 prefs::kExtensionCommands);
193 base::DictionaryValue* bindings = updater.Get(); 223 base::DictionaryValue* bindings = updater.Get();
194 224
195 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator); 225 std::string key = GetPlatformKeybindingKeyForAccelerator(accelerator,
226 extension_id);
196 227
197 if (!allow_overrides && bindings->HasKey(key)) 228 if (!allow_overrides && bindings->HasKey(key))
198 return false; // Already taken. 229 return false; // Already taken.
199 230
200 base::DictionaryValue* keybinding = new base::DictionaryValue(); 231 base::DictionaryValue* keybinding = new base::DictionaryValue();
201 keybinding->SetString(kExtension, extension_id); 232 keybinding->SetString(kExtension, extension_id);
202 keybinding->SetString(kCommandName, command_name); 233 keybinding->SetString(kCommandName, command_name);
203 keybinding->SetBoolean(kGlobal, global); 234 keybinding->SetBoolean(kGlobal, global);
204 235
205 bindings->Set(key, keybinding); 236 bindings->Set(key, keybinding);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 if (extension != extension_id) 310 if (extension != extension_id)
280 continue; 311 continue;
281 std::string command_name; 312 std::string command_name;
282 item->GetString(kCommandName, &command_name); 313 item->GetString(kCommandName, &command_name);
283 if (command != command_name) 314 if (command != command_name)
284 continue; 315 continue;
285 bool global = false; 316 bool global = false;
286 if (FeatureSwitch::global_commands()->IsEnabled()) 317 if (FeatureSwitch::global_commands()->IsEnabled())
287 item->GetBoolean(kGlobal, &global); 318 item->GetBoolean(kGlobal, &global);
288 319
320 // Format stored in Preferences is: "Platform:Shortcut[:ExtensionId]".
289 std::string shortcut = it.key(); 321 std::string shortcut = it.key();
290 if (StartsWithASCII(shortcut, Command::CommandPlatform() + ":", true)) 322 if (StartsWithASCII(shortcut, Command::CommandPlatform() + ":", true)) {
291 shortcut = shortcut.substr(Command::CommandPlatform().length() + 1); 323 std::vector<std::string> tokens;
324 base::SplitString(shortcut, ':', &tokens);
325 CHECK(tokens.size() >= 2);
326 shortcut = tokens[1];
327 }
292 328
293 return Command(command_name, string16(), shortcut, global); 329 return Command(command_name, string16(), shortcut, global);
294 } 330 }
295 331
296 return Command(); 332 return Command();
297 } 333 }
298 334
299 void CommandService::AssignInitialKeybindings(const Extension* extension) { 335 void CommandService::AssignInitialKeybindings(const Extension* extension) {
300 const extensions::CommandMap* commands = 336 const extensions::CommandMap* commands =
301 CommandsInfo::GetNamedCommands(extension); 337 CommandsInfo::GetNamedCommands(extension);
302 if (!commands) 338 if (!commands)
303 return; 339 return;
304 340
305 ExtensionService* extension_service = 341 ExtensionService* extension_service =
306 ExtensionSystem::Get(profile_)->extension_service(); 342 ExtensionSystem::Get(profile_)->extension_service();
307 ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); 343 ExtensionPrefs* extension_prefs = extension_service->extension_prefs();
308 if (InitialBindingsHaveBeenAssigned(extension_prefs, extension->id())) 344 if (InitialBindingsHaveBeenAssigned(extension_prefs, extension->id()))
309 return; 345 return;
310 SetInitialBindingsHaveBeenAssigned(extension_prefs, extension->id()); 346 SetInitialBindingsHaveBeenAssigned(extension_prefs, extension->id());
311 347
312 extensions::CommandMap::const_iterator iter = commands->begin(); 348 extensions::CommandMap::const_iterator iter = commands->begin();
313 for (; iter != commands->end(); ++iter) { 349 for (; iter != commands->end(); ++iter) {
314 if (!chrome::IsChromeAccelerator( 350 // Make sure registered Chrome shortcuts cannot be automatically assigned
315 iter->second.accelerator(), profile_) && 351 // (overwritten) by extension developers. Media keys are an exception here.
316 IsWhitelistedGlobalShortcut(iter->second)) { 352 if ((!chrome::IsChromeAccelerator(iter->second.accelerator(), profile_) &&
353 IsWhitelistedGlobalShortcut(iter->second)) ||
354 extensions::CommandService::IsMediaKey(iter->second.accelerator())) {
317 AddKeybindingPref(iter->second.accelerator(), 355 AddKeybindingPref(iter->second.accelerator(),
318 extension->id(), 356 extension->id(),
319 iter->second.command_name(), 357 iter->second.command_name(),
320 false, // Overwriting not allowed. 358 false, // Overwriting not allowed.
321 iter->second.global()); 359 iter->second.global());
322 } 360 }
323 } 361 }
324 362
325 const extensions::Command* browser_action_command = 363 const extensions::Command* browser_action_command =
326 CommandsInfo::GetBrowserActionCommand(extension); 364 CommandsInfo::GetBrowserActionCommand(extension);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 495
458 return true; 496 return true;
459 } 497 }
460 498
461 template <> 499 template <>
462 void ProfileKeyedAPIFactory<CommandService>::DeclareFactoryDependencies() { 500 void ProfileKeyedAPIFactory<CommandService>::DeclareFactoryDependencies() {
463 DependsOn(ExtensionCommandsGlobalRegistry::GetFactoryInstance()); 501 DependsOn(ExtensionCommandsGlobalRegistry::GetFactoryInstance());
464 } 502 }
465 503
466 } // namespace extensions 504 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698