Commit 281f5ffb authored by David Tseng's avatar David Tseng Committed by Commit Bot

Add accessibilityPrivate.sendSyntheticKeyEvent

Bug: 796861
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I54973fff39522225398d490877c2d03690dfd71f
Reviewed-on: https://chromium-review.googlesource.com/889040
Commit-Queue: Ilya Sherman <isherman@chromium.org>
Reviewed-by: default avatarIlya Sherman <isherman@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534192}
parent f5983858
...@@ -2,5 +2,6 @@ specific_include_rules = { ...@@ -2,5 +2,6 @@ specific_include_rules = {
"accessibility_extension_api\.cc": [ "accessibility_extension_api\.cc": [
# TODO(mash): Replace with mojo API. http://crbug.com/594887 # TODO(mash): Replace with mojo API. http://crbug.com/594887
"+ash/accessibility/accessibility_focus_ring_controller.h", "+ash/accessibility/accessibility_focus_ring_controller.h",
"+ash/shell.h",
], ],
} }
...@@ -31,8 +31,11 @@ ...@@ -31,8 +31,11 @@
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "ash/accessibility/accessibility_focus_ring_controller.h" #include "ash/accessibility/accessibility_focus_ring_controller.h"
#include "ash/shell.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event_sink.h"
using ash::AccessibilityFocusRingController; using ash::AccessibilityFocusRingController;
#endif #endif
...@@ -42,6 +45,7 @@ namespace accessibility_private = extensions::api::accessibility_private; ...@@ -42,6 +45,7 @@ namespace accessibility_private = extensions::api::accessibility_private;
namespace { namespace {
const char kErrorNotSupported[] = "This API is not supported on this platform."; const char kErrorNotSupported[] = "This API is not supported on this platform.";
} // namespace } // namespace
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
...@@ -219,4 +223,40 @@ AccessibilityPrivateSetNativeChromeVoxArcSupportForCurrentAppFunction::Run() { ...@@ -219,4 +223,40 @@ AccessibilityPrivateSetNativeChromeVoxArcSupportForCurrentAppFunction::Run() {
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
ExtensionFunction::ResponseAction
AccessibilityPrivateSendSyntheticKeyEventFunction::Run() {
std::unique_ptr<accessibility_private::SendSyntheticKeyEvent::Params> params =
accessibility_private::SendSyntheticKeyEvent::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(params);
accessibility_private::SyntheticKeyboardEvent* key_data = &params->key_event;
int modifiers = 0;
if (key_data->modifiers.get()) {
if (key_data->modifiers->ctrl)
modifiers |= ui::EF_CONTROL_DOWN;
if (key_data->modifiers->alt)
modifiers |= ui::EF_ALT_DOWN;
if (key_data->modifiers->search)
modifiers |= ui::EF_COMMAND_DOWN;
if (key_data->modifiers->shift)
modifiers |= ui::EF_SHIFT_DOWN;
}
ui::KeyEvent synthetic_key_event(
key_data->type ==
accessibility_private::SYNTHETIC_KEYBOARD_EVENT_TYPE_KEYUP
? ui::ET_KEY_RELEASED
: ui::ET_KEY_PRESSED,
static_cast<ui::KeyboardCode>(key_data->key_code),
static_cast<ui::DomCode>(0), modifiers);
// Only keyboard events, so dispatching to primary window suffices.
ui::EventSink* sink =
ash::Shell::GetPrimaryRootWindow()->GetHost()->event_sink();
if (sink->OnEventFromSource(&synthetic_key_event).dispatcher_destroyed)
return RespondNow(Error("Unable to dispatch key "));
return RespondNow(NoArguments());
}
#endif // defined (OS_CHROMEOS) #endif // defined (OS_CHROMEOS)
...@@ -79,6 +79,15 @@ class AccessibilityPrivateSetNativeChromeVoxArcSupportForCurrentAppFunction ...@@ -79,6 +79,15 @@ class AccessibilityPrivateSetNativeChromeVoxArcSupportForCurrentAppFunction
"accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp", "accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp",
ACCESSIBILITY_PRIVATE_SETNATIVECHROMEVOXARCSUPPORTFORCURRENTAPP) ACCESSIBILITY_PRIVATE_SETNATIVECHROMEVOXARCSUPPORTFORCURRENTAPP)
}; };
// API function that injects key events.
class AccessibilityPrivateSendSyntheticKeyEventFunction
: public UIThreadExtensionFunction {
~AccessibilityPrivateSendSyntheticKeyEventFunction() override {}
ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.sendSyntheticKeyEvent",
ACCESSIBILITY_PRIVATE_SENDSYNTHETICKEYEVENT)
};
#endif // defined (OS_CHROMEOS) #endif // defined (OS_CHROMEOS)
#endif // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EXTENSION_API_H_ #endif // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EXTENSION_API_H_
...@@ -89,7 +89,6 @@ ...@@ -89,7 +89,6 @@
#include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_manager.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -155,23 +154,6 @@ class ChromeVoxPanelWidgetObserver : public views::WidgetObserver { ...@@ -155,23 +154,6 @@ class ChromeVoxPanelWidgetObserver : public views::WidgetObserver {
DISALLOW_COPY_AND_ASSIGN(ChromeVoxPanelWidgetObserver); DISALLOW_COPY_AND_ASSIGN(ChromeVoxPanelWidgetObserver);
}; };
class ScopedKeyboardStateSetter {
public:
ScopedKeyboardStateSetter() : is_enabled_(keyboard::IsKeyboardEnabled()) {
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_ENABLED);
}
~ScopedKeyboardStateSetter() {
if (!is_enabled_)
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_DISABLED);
}
private:
bool is_enabled_;
DISALLOW_COPY_AND_ASSIGN(ScopedKeyboardStateSetter);
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// AccessibilityStatusEventDetails // AccessibilityStatusEventDetails
...@@ -1452,8 +1434,6 @@ void AccessibilityManager::PostLoadChromeVox() { ...@@ -1452,8 +1434,6 @@ void AccessibilityManager::PostLoadChromeVox() {
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableAudioFocus); ::switches::kEnableAudioFocus);
} }
keyboard_state_setter_.reset(new ScopedKeyboardStateSetter());
} }
void AccessibilityManager::PostUnloadChromeVox() { void AccessibilityManager::PostUnloadChromeVox() {
...@@ -1472,8 +1452,6 @@ void AccessibilityManager::PostUnloadChromeVox() { ...@@ -1472,8 +1452,6 @@ void AccessibilityManager::PostUnloadChromeVox() {
// In case the user darkened the screen, undarken it now. // In case the user darkened the screen, undarken it now.
SetDarkenScreen(false); SetDarkenScreen(false);
keyboard_state_setter_.reset();
} }
void AccessibilityManager::PostSwitchChromeVoxProfile() { void AccessibilityManager::PostSwitchChromeVoxProfile() {
......
...@@ -39,7 +39,6 @@ namespace chromeos { ...@@ -39,7 +39,6 @@ namespace chromeos {
class AccessibilityExtensionLoader; class AccessibilityExtensionLoader;
class AccessibilityHighlightManager; class AccessibilityHighlightManager;
class ScopedKeyboardStateSetter;
class SwitchAccessEventHandler; class SwitchAccessEventHandler;
enum AccessibilityNotificationType { enum AccessibilityNotificationType {
...@@ -439,8 +438,6 @@ class AccessibilityManager ...@@ -439,8 +438,6 @@ class AccessibilityManager
std::unique_ptr<chromeos::SwitchAccessEventHandler> std::unique_ptr<chromeos::SwitchAccessEventHandler>
switch_access_event_handler_; switch_access_event_handler_;
std::unique_ptr<ScopedKeyboardStateSetter> keyboard_state_setter_;
// Ash's mojom::AccessibilityController used to SetDarkenScreen. // Ash's mojom::AccessibilityController used to SetDarkenScreen.
ash::mojom::AccessibilityControllerPtr accessibility_controller_; ash::mojom::AccessibilityControllerPtr accessibility_controller_;
......
...@@ -426,18 +426,18 @@ cvox.BrailleInputHandler.prototype = { ...@@ -426,18 +426,18 @@ cvox.BrailleInputHandler.prototype = {
if (!goog.isDef(numericCode)) if (!goog.isDef(numericCode))
throw Error('Unknown key code in event: ' + JSON.stringify(event)); throw Error('Unknown key code in event: ' + JSON.stringify(event));
var keyEvent = { var keyEvent = {
type: 'keydown', type: chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN,
keyCode: numericCode, keyCode: numericCode,
keyName: keyName, modifiers: {
charValue: cvox.BrailleKeyEvent.keyCodeToCharValue(keyName), shift: !!event.shiftKey,
// See chrome/common/extensions/api/virtual_keyboard_private.json for ctrl: !!event.ctrlKey,
// these constants. alt: !!event.altKey
modifiers: (event.shiftKey ? 2 : 0) | (event.ctrlKey ? 4 : 0) | }
(event.altKey ? 8 : 0)
}; };
chrome.virtualKeyboardPrivate.sendKeyEvent(keyEvent); chrome.accessibilityPrivate.sendSyntheticKeyEvent(keyEvent);
keyEvent.type = 'keyup'; keyEvent.type =
chrome.virtualKeyboardPrivate.sendKeyEvent(keyEvent); chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP;
chrome.accessibilityPrivate.sendSyntheticKeyEvent(keyEvent);
}); });
} }
}; };
......
...@@ -11,6 +11,8 @@ GEN_INCLUDE(['../testing/fake_objects.js']); ...@@ -11,6 +11,8 @@ GEN_INCLUDE(['../testing/fake_objects.js']);
var chrome = {}; var chrome = {};
/** Fake chrome.runtime object. */ /** Fake chrome.runtime object. */
chrome.runtime = {}; chrome.runtime = {};
/** Fake chrome.accessibilityPrivate object. */
chrome.accessibilityPrivate = {};
/** Fake chrome.virtualKeyboardPrivate object. */ /** Fake chrome.virtualKeyboardPrivate object. */
chrome.virtualKeyboardPrivate = {}; chrome.virtualKeyboardPrivate = {};
...@@ -498,8 +500,7 @@ CvoxBrailleInputHandlerUnitTest.prototype = { ...@@ -498,8 +500,7 @@ CvoxBrailleInputHandlerUnitTest.prototype = {
}, },
storeKeyEvent: function(event, opt_callback) { storeKeyEvent: function(event, opt_callback) {
var storedCopy = {keyCode: event.keyCode, keyName: event.keyName, var storedCopy = {keyCode: event.keyCode};
charValue: event.charValue};
if (event.type == 'keydown') { if (event.type == 'keydown') {
this.keyEvents.push(storedCopy); this.keyEvents.push(storedCopy);
} else { } else {
...@@ -519,8 +520,11 @@ CvoxBrailleInputHandlerUnitTest.prototype = { ...@@ -519,8 +520,11 @@ CvoxBrailleInputHandlerUnitTest.prototype = {
chrome.virtualKeyboardPrivate.getKeyboardConfig = function(callback) { chrome.virtualKeyboardPrivate.getKeyboardConfig = function(callback) {
callback({ a11ymode: true }); callback({ a11ymode: true });
}; };
chrome.virtualKeyboardPrivate.sendKeyEvent = chrome.accessibilityPrivate.sendSyntheticKeyEvent =
this.storeKeyEvent.bind(this); this.storeKeyEvent.bind(this);
chrome.accessibilityPrivate.SyntheticKeyboardEventType = {};
chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN = 'keydown';
chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP = 'keyup';
this.translatorManager = new FakeTranslatorManager(); this.translatorManager = new FakeTranslatorManager();
this.inputHandler = new cvox.BrailleInputHandler(this.translatorManager); this.inputHandler = new cvox.BrailleInputHandler(this.translatorManager);
this.inputHandler.init(); this.inputHandler.init();
...@@ -686,7 +690,7 @@ TEST_F('CvoxBrailleInputHandlerUnitTest', 'Backspace', function() { ...@@ -686,7 +690,7 @@ TEST_F('CvoxBrailleInputHandlerUnitTest', 'Backspace', function() {
// Now, backspace should be handled as usual, synthetizing key events. // Now, backspace should be handled as usual, synthetizing key events.
assertEquals(0, this.keyEvents.length); assertEquals(0, this.keyEvents.length);
this.sendKeyEvent('Backspace'); this.sendKeyEvent('Backspace');
assertEqualsJSON([{keyCode: 8, keyName: 'Backspace', charValue: 8}], assertEqualsJSON([{keyCode: 8}],
this.keyEvents); this.keyEvents);
}); });
...@@ -695,7 +699,7 @@ TEST_F('CvoxBrailleInputHandlerUnitTest', 'KeysImeNotActive', function() { ...@@ -695,7 +699,7 @@ TEST_F('CvoxBrailleInputHandlerUnitTest', 'KeysImeNotActive', function() {
var editor = this.createEditor(); var editor = this.createEditor();
this.sendKeyEvent('Enter'); this.sendKeyEvent('Enter');
this.sendKeyEvent('ArrowUp'); this.sendKeyEvent('ArrowUp');
assertEqualsJSON([{keyCode: 13, keyName: 'Enter', charValue: 0x0A}, assertEqualsJSON([{keyCode: 13},
{keyCode: 38, keyName: 'ArrowUp', charValue: 0x41}], {keyCode: 38}],
this.keyEvents); this.keyEvents);
}); });
...@@ -51,9 +51,9 @@ BackgroundTest.prototype = { ...@@ -51,9 +51,9 @@ BackgroundTest.prototype = {
}; };
}, },
press: function(keyCode, keyName, modifiers) { press: function(keyCode, modifiers) {
return function() { return function() {
BackgroundKeyboardHandler.sendKeyPress(keyCode, keyName, modifiers); BackgroundKeyboardHandler.sendKeyPress(keyCode, modifiers);
}; };
}, },
...@@ -1293,12 +1293,12 @@ TEST_F('BackgroundTest', 'NativeFind', function() { ...@@ -1293,12 +1293,12 @@ TEST_F('BackgroundTest', 'NativeFind', function() {
<a href="#">grape</a> <a href="#">grape</a>
<a href="#">pineapple</a> <a href="#">pineapple</a>
*/}, function(root) { */}, function(root) {
mockFeedback.call(press(70, 'F', Mod.CONTROL)) mockFeedback.call(press(70, {ctrl: true}))
.expectSpeech('Find', 'Edit text') .expectSpeech('Find', 'Edit text')
.call(press(71, 'G')) .call(press(71))
.expectSpeech('grape', 'Link') .expectSpeech('grape', 'Link')
.call(press(8, 'Backspace')) .call(press(8))
.call(press(76, 'L')) .call(press(76))
.expectSpeech('pineapple', 'Link') .expectSpeech('pineapple', 'Link')
.replay(); .replay();
}); });
......
...@@ -11,7 +11,6 @@ goog.provide('BrailleCommandHandler'); ...@@ -11,7 +11,6 @@ goog.provide('BrailleCommandHandler');
goog.require('BackgroundKeyboardHandler'); goog.require('BackgroundKeyboardHandler');
goog.scope(function() { goog.scope(function() {
var Mod = constants.ModifierFlag;
var StateType = chrome.automation.StateType; var StateType = chrome.automation.StateType;
/** /**
...@@ -107,34 +106,34 @@ BrailleCommandHandler.onEditCommand = function(command) { ...@@ -107,34 +106,34 @@ BrailleCommandHandler.onEditCommand = function(command) {
var isMultiline = AutomationPredicate.multiline(current.start.node); var isMultiline = AutomationPredicate.multiline(current.start.node);
switch (command) { switch (command) {
case 'previousCharacter': case 'previousCharacter':
BackgroundKeyboardHandler.sendKeyPress(37, 'ArrowLeft'); BackgroundKeyboardHandler.sendKeyPress(37);
break; break;
case 'nextCharacter': case 'nextCharacter':
BackgroundKeyboardHandler.sendKeyPress(39, 'ArrowRight'); BackgroundKeyboardHandler.sendKeyPress(39);
break; break;
case 'previousWord': case 'previousWord':
BackgroundKeyboardHandler.sendKeyPress(37, 'ArrowLeft', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(37, {ctrl: true});
break; break;
case 'nextWord': case 'nextWord':
BackgroundKeyboardHandler.sendKeyPress(39, 'ArrowRight', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(39, {ctrl: true});
break; break;
case 'previousObject': case 'previousObject':
case 'previousLine': case 'previousLine':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(38, 'ArrowUp'); BackgroundKeyboardHandler.sendKeyPress(38);
break; break;
case 'nextObject': case 'nextObject':
case 'nextLine': case 'nextLine':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(40, 'ArrowDown'); BackgroundKeyboardHandler.sendKeyPress(40);
break; break;
case 'previousGroup': case 'previousGroup':
BackgroundKeyboardHandler.sendKeyPress(38, 'ArrowUp', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(38, {ctrl: true});
break; break;
case 'nextGroup': case 'nextGroup':
BackgroundKeyboardHandler.sendKeyPress(40, 'ArrowDown', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(40, {ctrl: true});
break; break;
default: default:
return true; return true;
......
...@@ -18,7 +18,6 @@ goog.scope(function() { ...@@ -18,7 +18,6 @@ goog.scope(function() {
var AutomationEvent = chrome.automation.AutomationEvent; var AutomationEvent = chrome.automation.AutomationEvent;
var AutomationNode = chrome.automation.AutomationNode; var AutomationNode = chrome.automation.AutomationNode;
var Dir = constants.Dir; var Dir = constants.Dir;
var Mod = constants.ModifierFlag;
var EventType = chrome.automation.EventType; var EventType = chrome.automation.EventType;
var RoleType = chrome.automation.RoleType; var RoleType = chrome.automation.RoleType;
var StateType = chrome.automation.StateType; var StateType = chrome.automation.StateType;
...@@ -929,44 +928,42 @@ CommandHandler.onEditCommand_ = function(command) { ...@@ -929,44 +928,42 @@ CommandHandler.onEditCommand_ = function(command) {
var isMultiline = AutomationPredicate.multiline(current.start.node); var isMultiline = AutomationPredicate.multiline(current.start.node);
switch (command) { switch (command) {
case 'previousCharacter': case 'previousCharacter':
BackgroundKeyboardHandler.sendKeyPress(36, 'Home', Mod.SHIFT); BackgroundKeyboardHandler.sendKeyPress(36, {shift: true});
break; break;
case 'nextCharacter': case 'nextCharacter':
BackgroundKeyboardHandler.sendKeyPress(35, 'End', Mod.SHIFT); BackgroundKeyboardHandler.sendKeyPress(35, {shift: true});
break; break;
case 'previousWord': case 'previousWord':
BackgroundKeyboardHandler.sendKeyPress( BackgroundKeyboardHandler.sendKeyPress(36, {shift: true, ctrl: true});
36, 'Home', Mod.SHIFT | Mod.CONTROL);
break; break;
case 'nextWord': case 'nextWord':
BackgroundKeyboardHandler.sendKeyPress( BackgroundKeyboardHandler.sendKeyPress(35, {shift: true, ctrl: true});
35, 'End', Mod.SHIFT | Mod.CONTROL);
break; break;
case 'previousObject': case 'previousObject':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(36, 'Home'); BackgroundKeyboardHandler.sendKeyPress(36);
break; break;
case 'nextObject': case 'nextObject':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(35, 'End'); BackgroundKeyboardHandler.sendKeyPress(35);
break; break;
case 'previousLine': case 'previousLine':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(33, 'PageUp'); BackgroundKeyboardHandler.sendKeyPress(33);
break; break;
case 'nextLine': case 'nextLine':
if (!isMultiline) if (!isMultiline)
return true; return true;
BackgroundKeyboardHandler.sendKeyPress(34, 'PageDown'); BackgroundKeyboardHandler.sendKeyPress(34);
break; break;
case 'jumpToTop': case 'jumpToTop':
BackgroundKeyboardHandler.sendKeyPress(36, 'Home', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(36, {ctrl: true});
break; break;
case 'jumpToBottom': case 'jumpToBottom':
BackgroundKeyboardHandler.sendKeyPress(35, 'End', Mod.CONTROL); BackgroundKeyboardHandler.sendKeyPress(35, {ctrl: true});
break; break;
default: default:
return true; return true;
......
...@@ -36,14 +36,3 @@ constants.Point; ...@@ -36,14 +36,3 @@ constants.Point;
* @const * @const
*/ */
constants.OBJECT_MAX_CHARCOUNT = 1500; constants.OBJECT_MAX_CHARCOUNT = 1500;
/**
* Modifier values used by Chrome.
* See ui/events/event_constants.h
*/
constants.ModifierFlag = {
SHIFT: 2,
CONTROL: 4,
ALT: 8,
SEARCH: 16
};
...@@ -78,21 +78,17 @@ BackgroundKeyboardHandler.prototype = { ...@@ -78,21 +78,17 @@ BackgroundKeyboardHandler.prototype = {
/** /**
* @param {number} keyCode * @param {number} keyCode
* @param {string} keyName * @param {chrome.accessibilityPrivate.SyntheticKeyboardModifiers=} modifiers
* @param {number=} modifiers
* @return {boolean} * @return {boolean}
*/ */
BackgroundKeyboardHandler.sendKeyPress = function(keyCode, keyName, modifiers) { BackgroundKeyboardHandler.sendKeyPress = function(keyCode, modifiers) {
modifiers = modifiers || 0;
var key = { var key = {
type: 'keydown', type: chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN,
keyCode: keyCode, keyCode: keyCode,
keyName: keyName,
charValue: keyCode,
modifiers: modifiers modifiers: modifiers
}; };
chrome.virtualKeyboardPrivate.sendKeyEvent(key); chrome.accessibilityPrivate.sendSyntheticKeyEvent(key);
key['type'] = 'keyup'; key['type'] = chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP;
chrome.virtualKeyboardPrivate.sendKeyEvent(key); chrome.accessibilityPrivate.sendSyntheticKeyEvent(key);
return true; return true;
}; };
...@@ -39,15 +39,12 @@ ChromeVoxE2ETest.prototype = { ...@@ -39,15 +39,12 @@ ChromeVoxE2ETest.prototype = {
#include "base/callback.h" #include "base/callback.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "ui/keyboard/keyboard_util.h"
*/ }); */ });
}, },
/** @override */ /** @override */
testGenPreamble: function() { testGenPreamble: function() {
GEN_BLOCK(function() { /*! GEN_BLOCK(function() { /*!
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_ENABLED);
ash::Shell::Get()->CreateKeyboard();
base::Closure load_cb = base::Closure load_cb =
base::Bind(&chromeos::AccessibilityManager::EnableSpokenFeedback, base::Bind(&chromeos::AccessibilityManager::EnableSpokenFeedback,
base::Unretained(chromeos::AccessibilityManager::Get()), base::Unretained(chromeos::AccessibilityManager::Get()),
......
...@@ -37,6 +37,51 @@ ...@@ -37,6 +37,51 @@
"type": "string", "type": "string",
"enum": [ "click", "swipeLeft1", "swipeUp1", "swipeRight1", "swipeDown1", "swipeLeft2", "swipeUp2", "swipeRight2", "swipeDown2", "swipeLeft3", "swipeUp3", "swipeRight3", "swipeDown3", "swipeLeft4", "swipeUp4", "swipeRight4", "swipeDown4" ], "enum": [ "click", "swipeLeft1", "swipeUp1", "swipeRight1", "swipeDown1", "swipeLeft2", "swipeUp2", "swipeRight2", "swipeDown2", "swipeLeft3", "swipeUp3", "swipeRight3", "swipeDown3", "swipeLeft4", "swipeUp4", "swipeRight4", "swipeDown4" ],
"description": "Accessibility gestures fired by the touch exploration controller." "description": "Accessibility gestures fired by the touch exploration controller."
},
{
"id": "SyntheticKeyboardEventType",
"type": "string",
"description": "The event to send",
"enum": ["keyup", "keydown"]
},
{
"id": "SyntheticKeyboardModifiers",
"type": "object",
"properties": {
"ctrl": {
"type": "boolean",
"description": "Control modifier.",
"optional": true
},
"alt": {
"type": "boolean",
"description": "alt modifier.",
"optional": true
},
"search": {
"type": "boolean",
"description": "search modifier.",
"optional": true
},
"shift": {
"type": "boolean",
"description": "shift modifier.",
"optional": true
}
}
},
{
"id": "SyntheticKeyboardEvent",
"type": "object",
"properties": {
"type": {"$ref": "SyntheticKeyboardEventType"},
"keyCode": {"type": "integer", "description": "Virtual key code, which is independent of the keyboard layout or modifier state."},
"modifiers": {
"$ref": "SyntheticKeyboardModifiers",
"optional": true,
"description": "Contains all active modifiers."
}
}
} }
], ],
"functions": [ "functions": [
...@@ -149,6 +194,19 @@ ...@@ -149,6 +194,19 @@
} }
], ],
"platforms": ["chromeos"] "platforms": ["chromeos"]
},
{
"name": "sendSyntheticKeyEvent",
"type": "function",
"description": "Sends a fabricated key event.",
"parameters": [
{
"name": "keyEvent",
"$ref": "SyntheticKeyboardEvent",
"description": "The event to send."
}
],
"platforms": ["chromeos"]
} }
], ],
"events": [ "events": [
......
...@@ -1276,6 +1276,7 @@ enum HistogramValue { ...@@ -1276,6 +1276,7 @@ enum HistogramValue {
PASSWORDSPRIVATE_REQUESTEXPORTPROGRESSSTATUS, PASSWORDSPRIVATE_REQUESTEXPORTPROGRESSSTATUS,
WALLPAPERPRIVATE_GETCOLLECTIONSINFO, WALLPAPERPRIVATE_GETCOLLECTIONSINFO,
WALLPAPERPRIVATE_GETIMAGESINFO, WALLPAPERPRIVATE_GETIMAGESINFO,
ACCESSIBILITY_PRIVATE_SENDSYNTHETICKEYEVENT,
// Last entry: Add new entries above, then run: // Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py // python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY ENUM_BOUNDARY
......
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -61,6 +61,45 @@ chrome.accessibilityPrivate.Gesture = { ...@@ -61,6 +61,45 @@ chrome.accessibilityPrivate.Gesture = {
SWIPE_DOWN4: 'swipeDown4', SWIPE_DOWN4: 'swipeDown4',
}; };
/**
* @enum {string}
* @see https://developer.chrome.com/extensions/accessibilityPrivate#type-SyntheticKeyboardEventType
*/
chrome.accessibilityPrivate.SyntheticKeyboardEventType = {
KEYUP: 'keyup',
KEYDOWN: 'keydown',
};
/**
* @typedef {{
* ctrl: (boolean|undefined),
* alt: (boolean|undefined),
* search: (boolean|undefined),
* shift: (boolean|undefined)
* }}
* @see https://developer.chrome.com/extensions/accessibilityPrivate#type-SyntheticKeyboardModifiers
*/
chrome.accessibilityPrivate.SyntheticKeyboardModifiers;
/**
* @typedef {{
* type: !chrome.accessibilityPrivate.SyntheticKeyboardEventType,
* keyCode: number,
* modifiers: (!chrome.accessibilityPrivate.SyntheticKeyboardModifiers|undefined)
* }}
* @see https://developer.chrome.com/extensions/accessibilityPrivate#type-SyntheticKeyboardEvent
*/
chrome.accessibilityPrivate.SyntheticKeyboardEvent;
/**
* @enum {string}
* @see https://developer.chrome.com/extensions/accessibilityPrivate#type-KeyboardMode
*/
chrome.accessibilityPrivate.KeyboardMode = {
FULL_WIDTH: 'FULL_WIDTH',
FLOATING: 'FLOATING',
};
/** /**
* Enables or disables native accessibility support. Once disabled, it is up to * Enables or disables native accessibility support. Once disabled, it is up to
* the calling extension to provide accessibility for web contents. * the calling extension to provide accessibility for web contents.
...@@ -71,7 +110,7 @@ chrome.accessibilityPrivate.Gesture = { ...@@ -71,7 +110,7 @@ chrome.accessibilityPrivate.Gesture = {
chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(enabled) {}; chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(enabled) {};
/** /**
* Set the bounds of the accessibility focus ring. * Sets the bounds of the accessibility focus ring.
* @param {!Array<!chrome.accessibilityPrivate.ScreenRect>} rects Array of * @param {!Array<!chrome.accessibilityPrivate.ScreenRect>} rects Array of
* rectangles to draw the accessibility focus ring around. * rectangles to draw the accessibility focus ring around.
* @param {string=} color CSS-style hex color string beginning with # like * @param {string=} color CSS-style hex color string beginning with # like
...@@ -81,10 +120,10 @@ chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(enabled) {} ...@@ -81,10 +120,10 @@ chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(enabled) {}
chrome.accessibilityPrivate.setFocusRing = function(rects, color) {}; chrome.accessibilityPrivate.setFocusRing = function(rects, color) {};
/** /**
* Set the bounds of highlighted regions on the screen. * Sets the bounds of the accessibility highlight.
* @param {!Array<!chrome.accessibilityPrivate.ScreenRect>} rects Array of * @param {!Array<!chrome.accessibilityPrivate.ScreenRect>} rects Array of
* rectangles to draw the highlights on. * rectangles to draw the highlight around.
* @param {string=} color CSS-style hex color string beginning with # like * @param {string} color CSS-style hex color string beginning with # like
* #FF9982 or #EEE. * #FF9982 or #EEE.
* @see https://developer.chrome.com/extensions/accessibilityPrivate#method-setHighlights * @see https://developer.chrome.com/extensions/accessibilityPrivate#method-setHighlights
*/ */
...@@ -126,6 +165,14 @@ chrome.accessibilityPrivate.setSwitchAccessKeys = function(key_codes) {}; ...@@ -126,6 +165,14 @@ chrome.accessibilityPrivate.setSwitchAccessKeys = function(key_codes) {};
*/ */
chrome.accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp = function(enabled) {}; chrome.accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp = function(enabled) {};
/**
* Sends a fabricated key event.
* @param {!chrome.accessibilityPrivate.SyntheticKeyboardEvent} keyEvent The
* event to send.
* @see https://developer.chrome.com/extensions/accessibilityPrivate#method-sendSyntheticKeyEvent
*/
chrome.accessibilityPrivate.sendSyntheticKeyEvent = function(keyEvent) {};
/** /**
* Fired whenever ChromeVox should output introduction. * Fired whenever ChromeVox should output introduction.
* @type {!ChromeEvent} * @type {!ChromeEvent}
......
...@@ -14633,6 +14633,7 @@ Called by update_net_error_codes.py.--> ...@@ -14633,6 +14633,7 @@ Called by update_net_error_codes.py.-->
<int value="1213" label="PASSWORDSPRIVATE_REQUESTEXPORTPROGRESSSTATUS"/> <int value="1213" label="PASSWORDSPRIVATE_REQUESTEXPORTPROGRESSSTATUS"/>
<int value="1214" label="WALLPAPERPRIVATE_GETCOLLECTIONSINFO"/> <int value="1214" label="WALLPAPERPRIVATE_GETCOLLECTIONSINFO"/>
<int value="1215" label="WALLPAPERPRIVATE_GETIMAGESINFO"/> <int value="1215" label="WALLPAPERPRIVATE_GETIMAGESINFO"/>
<int value="1216" label="ACCESSIBILITY_PRIVATE_SENDSYNTHETICKEYEVENT"/>
</enum> </enum>
<enum name="ExtensionIconState"> <enum name="ExtensionIconState">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment