Index: chrome/common/extensions/command.cc |
diff --git a/chrome/common/extensions/command.cc b/chrome/common/extensions/command.cc |
index fffc55ef29dcd8a33363a4d73bbf5c81206a9616..be46c20be8e43170b935be4b740d23cf593e4573 100644 |
--- a/chrome/common/extensions/command.cc |
+++ b/chrome/common/extensions/command.cc |
@@ -29,10 +29,25 @@ static const char kMissing[] = "Missing"; |
static const char kCommandKeyNotSupported[] = |
"Command key is not supported. Note: Ctrl means Command on Mac"; |
+bool IsNamedCommand(const std::string& command_name) { |
+ return command_name != values::kPageActionCommandEvent && |
+ command_name != values::kBrowserActionCommandEvent && |
+ command_name != values::kScriptBadgeCommandEvent; |
+} |
+ |
+bool DoesRequireModifier(const std::string& accelerator) { |
+ return accelerator != values::kKeyMediaNextTrack && |
+ accelerator != values::kKeyMediaPlayPause && |
+ accelerator != values::kKeyMediaPrevTrack && |
+ accelerator != values::kKeyMediaStop; |
+} |
+ |
ui::Accelerator ParseImpl(const std::string& accelerator, |
const std::string& platform_key, |
int index, |
+ bool should_parse_media_keys, |
string16* error) { |
+ error->clear(); |
if (platform_key != values::kKeybindingPlatformWin && |
platform_key != values::kKeybindingPlatformMac && |
platform_key != values::kKeybindingPlatformChromeOs && |
@@ -47,7 +62,9 @@ ui::Accelerator ParseImpl(const std::string& accelerator, |
std::vector<std::string> tokens; |
base::SplitString(accelerator, '+', &tokens); |
- if (tokens.size() < 2 || tokens.size() > 3) { |
+ if (tokens.size() == 0 || |
+ (tokens.size() == 1 && DoesRequireModifier(accelerator)) || |
+ tokens.size() > 3) { |
*error = ErrorUtils::FormatErrorMessageUTF16( |
errors::kInvalidKeyBinding, |
base::IntToString(index), |
@@ -99,7 +116,11 @@ ui::Accelerator ParseImpl(const std::string& accelerator, |
tokens[i] == values::kKeyEnd || |
tokens[i] == values::kKeyPgUp || |
tokens[i] == values::kKeyPgDwn || |
- tokens[i] == values::kKeyTab) { |
+ tokens[i] == values::kKeyTab || |
+ tokens[i] == values::kKeyMediaNextTrack || |
+ tokens[i] == values::kKeyMediaPlayPause || |
+ tokens[i] == values::kKeyMediaPrevTrack || |
+ tokens[i] == values::kKeyMediaStop) { |
if (key != ui::VKEY_UNKNOWN) { |
// Multiple key assignments. |
key = ui::VKEY_UNKNOWN; |
@@ -132,6 +153,18 @@ ui::Accelerator ParseImpl(const std::string& accelerator, |
key = ui::VKEY_NEXT; |
} else if (tokens[i] == values::kKeyTab) { |
key = ui::VKEY_TAB; |
+ } else if (tokens[i] == values::kKeyMediaNextTrack && |
+ should_parse_media_keys) { |
+ key = ui::VKEY_MEDIA_NEXT_TRACK; |
+ } else if (tokens[i] == values::kKeyMediaPlayPause && |
+ should_parse_media_keys) { |
+ key = ui::VKEY_MEDIA_PLAY_PAUSE; |
+ } else if (tokens[i] == values::kKeyMediaPrevTrack && |
+ should_parse_media_keys) { |
+ key = ui::VKEY_MEDIA_PREV_TRACK; |
+ } else if (tokens[i] == values::kKeyMediaStop && |
+ should_parse_media_keys) { |
+ key = ui::VKEY_MEDIA_STOP; |
} else if (tokens[i].size() == 1 && |
tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') { |
key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A')); |
@@ -151,6 +184,7 @@ ui::Accelerator ParseImpl(const std::string& accelerator, |
return ui::Accelerator(); |
} |
} |
+ |
bool command = (modifiers & ui::EF_COMMAND_DOWN) != 0; |
bool ctrl = (modifiers & ui::EF_CONTROL_DOWN) != 0; |
bool alt = (modifiers & ui::EF_ALT_DOWN) != 0; |
@@ -172,6 +206,19 @@ ui::Accelerator ParseImpl(const std::string& accelerator, |
return ui::Accelerator(); |
} |
+ if ((key == ui::VKEY_MEDIA_NEXT_TRACK || |
+ key == ui::VKEY_MEDIA_PREV_TRACK || |
+ key == ui::VKEY_MEDIA_PLAY_PAUSE || |
+ key == ui::VKEY_MEDIA_STOP) && |
+ (shift || ctrl || alt || command)) { |
+ *error = ErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBindingMediaKeyWithModifier, |
+ base::IntToString(index), |
+ platform_key, |
+ accelerator); |
+ return ui::Accelerator(); |
+ } |
+ |
return ui::Accelerator(key, modifiers); |
} |
@@ -214,7 +261,8 @@ Command::Command(const std::string& command_name, |
: command_name_(command_name), |
description_(description) { |
string16 error; |
- accelerator_ = ParseImpl(accelerator, CommandPlatform(), 0, &error); |
+ accelerator_ = ParseImpl(accelerator, CommandPlatform(), 0, |
+ IsNamedCommand(command_name), &error); |
} |
Command::~Command() {} |
@@ -235,11 +283,12 @@ std::string Command::CommandPlatform() { |
} |
// static |
-ui::Accelerator Command::StringToAccelerator(const std::string& accelerator) { |
+ui::Accelerator Command::StringToAccelerator(const std::string& accelerator, |
+ const std::string& command_name) { |
string16 error; |
- Command command; |
ui::Accelerator parsed = |
- ParseImpl(accelerator, Command::CommandPlatform(), 0, &error); |
+ ParseImpl(accelerator, Command::CommandPlatform(), 0, |
+ IsNamedCommand(command_name), &error); |
return parsed; |
} |
@@ -312,6 +361,18 @@ std::string Command::AcceleratorToString(const ui::Accelerator& accelerator) { |
case ui::VKEY_TAB: |
shortcut += values::kKeyTab; |
break; |
+ case ui::VKEY_MEDIA_NEXT_TRACK: |
+ shortcut += values::kKeyMediaNextTrack; |
+ break; |
+ case ui::VKEY_MEDIA_PLAY_PAUSE: |
+ shortcut += values::kKeyMediaPlayPause; |
+ break; |
+ case ui::VKEY_MEDIA_PREV_TRACK: |
+ shortcut += values::kKeyMediaPrevTrack; |
+ break; |
+ case ui::VKEY_MEDIA_STOP: |
+ shortcut += values::kKeyMediaStop; |
+ break; |
default: |
return ""; |
} |
@@ -326,9 +387,7 @@ bool Command::Parse(const base::DictionaryValue* command, |
DCHECK(!command_name.empty()); |
string16 description; |
- if (command_name != values::kPageActionCommandEvent && |
- command_name != values::kBrowserActionCommandEvent && |
- command_name != values::kScriptBadgeCommandEvent) { |
+ if (IsNamedCommand(command_name)) { |
if (!command->GetString(keys::kDescription, &description) || |
description.empty()) { |
*error = ErrorUtils::FormatErrorMessageUTF16( |
@@ -419,13 +478,16 @@ bool Command::Parse(const base::DictionaryValue* command, |
if (!iter->second.empty()) { |
// Note that we pass iter->first to pretend we are on a platform we're not |
// on. |
- accelerator = ParseImpl(iter->second, iter->first, index, error); |
+ accelerator = ParseImpl(iter->second, iter->first, index, |
+ IsNamedCommand(command_name), error); |
if (accelerator.key_code() == ui::VKEY_UNKNOWN) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidKeyBinding, |
- base::IntToString(index), |
- iter->first, |
- iter->second); |
+ if (error->empty()) { |
+ *error = ErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidKeyBinding, |
+ base::IntToString(index), |
+ iter->first, |
+ iter->second); |
+ } |
return false; |
} |
} |