Commit 16b34dcf authored by Josiah K's avatar Josiah K Committed by Chromium LUCI CQ

Add listeners for magnifier commands and onMagnifierCommand API

(http://go/magnifier-panning-improvements-design-doc)

AX-Relnotes: n/a
Bug: 1144037
Change-Id: I82c2b1c330826a4e48ed47482f98f1a0c0168894
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2503568
Commit-Queue: Josiah Krutz <josiahk@google.com>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837882}
parent d0506dd8
...@@ -239,15 +239,19 @@ void AccessibilityEventRewriter::OnMagnifierKeyPressed( ...@@ -239,15 +239,19 @@ void AccessibilityEventRewriter::OnMagnifierKeyPressed(
switch (event->key_code()) { switch (event->key_code()) {
case ui::VKEY_UP: case ui::VKEY_UP:
controller->SetScrollDirection(MagnificationController::SCROLL_UP); controller->SetScrollDirection(MagnificationController::SCROLL_UP);
delegate_->SendMagnifierCommand(MagnifierCommand::kMoveUp);
break; break;
case ui::VKEY_DOWN: case ui::VKEY_DOWN:
controller->SetScrollDirection(MagnificationController::SCROLL_DOWN); controller->SetScrollDirection(MagnificationController::SCROLL_DOWN);
delegate_->SendMagnifierCommand(MagnifierCommand::kMoveDown);
break; break;
case ui::VKEY_LEFT: case ui::VKEY_LEFT:
controller->SetScrollDirection(MagnificationController::SCROLL_LEFT); controller->SetScrollDirection(MagnificationController::SCROLL_LEFT);
delegate_->SendMagnifierCommand(MagnifierCommand::kMoveLeft);
break; break;
case ui::VKEY_RIGHT: case ui::VKEY_RIGHT:
controller->SetScrollDirection(MagnificationController::SCROLL_RIGHT); controller->SetScrollDirection(MagnificationController::SCROLL_RIGHT);
delegate_->SendMagnifierCommand(MagnifierCommand::kMoveRight);
break; break;
default: default:
NOTREACHED() << "Unexpected keyboard_code:" << event->key_code(); NOTREACHED() << "Unexpected keyboard_code:" << event->key_code();
...@@ -259,6 +263,7 @@ void AccessibilityEventRewriter::OnMagnifierKeyReleased( ...@@ -259,6 +263,7 @@ void AccessibilityEventRewriter::OnMagnifierKeyReleased(
MagnificationController* controller = MagnificationController* controller =
Shell::Get()->magnification_controller(); Shell::Get()->magnification_controller();
controller->SetScrollDirection(MagnificationController::SCROLL_NONE); controller->SetScrollDirection(MagnificationController::SCROLL_NONE);
delegate_->SendMagnifierCommand(MagnifierCommand::kMoveStop);
} }
void AccessibilityEventRewriter::UpdateKeyboardDeviceIds() { void AccessibilityEventRewriter::UpdateKeyboardDeviceIds() {
...@@ -296,7 +301,10 @@ ui::EventDispatchDetails AccessibilityEventRewriter::RewriteEvent( ...@@ -296,7 +301,10 @@ ui::EventDispatchDetails AccessibilityEventRewriter::RewriteEvent(
captured = RewriteEventForSwitchAccess(event, continuation); captured = RewriteEventForSwitchAccess(event, continuation);
} }
if (!captured && Shell::Get()->magnification_controller()->IsEnabled()) { if (!captured && Shell::Get()
->accessibility_controller()
->fullscreen_magnifier()
.enabled()) {
captured = RewriteEventForMagnifier(event, continuation); captured = RewriteEventForMagnifier(event, continuation);
} }
......
...@@ -60,6 +60,7 @@ class ChromeVoxTestDelegate : public AccessibilityEventRewriterDelegate { ...@@ -60,6 +60,7 @@ class ChromeVoxTestDelegate : public AccessibilityEventRewriterDelegate {
} }
void SendSwitchAccessCommand(SwitchAccessCommand command) override {} void SendSwitchAccessCommand(SwitchAccessCommand command) override {}
void SendPointScanPoint(const gfx::PointF& point) override {} void SendPointScanPoint(const gfx::PointF& point) override {}
void SendMagnifierCommand(MagnifierCommand command) override {}
}; };
class ChromeVoxAccessibilityEventRewriterTest class ChromeVoxAccessibilityEventRewriterTest
...@@ -380,6 +381,8 @@ TEST_F(ChromeVoxAccessibilityEventRewriterTest, ...@@ -380,6 +381,8 @@ TEST_F(ChromeVoxAccessibilityEventRewriterTest,
class EventCapturer : public ui::EventHandler { class EventCapturer : public ui::EventHandler {
public: public:
EventCapturer() = default; EventCapturer() = default;
EventCapturer(const EventCapturer&) = delete;
EventCapturer& operator=(const EventCapturer&) = delete;
~EventCapturer() override = default; ~EventCapturer() override = default;
void Reset() { last_key_event_.reset(); } void Reset() { last_key_event_.reset(); }
...@@ -392,13 +395,13 @@ class EventCapturer : public ui::EventHandler { ...@@ -392,13 +395,13 @@ class EventCapturer : public ui::EventHandler {
} }
std::unique_ptr<ui::KeyEvent> last_key_event_; std::unique_ptr<ui::KeyEvent> last_key_event_;
DISALLOW_COPY_AND_ASSIGN(EventCapturer);
}; };
class SwitchAccessTestDelegate : public AccessibilityEventRewriterDelegate { class SwitchAccessTestDelegate : public AccessibilityEventRewriterDelegate {
public: public:
SwitchAccessTestDelegate() = default; SwitchAccessTestDelegate() = default;
SwitchAccessTestDelegate(const SwitchAccessTestDelegate&) = delete;
SwitchAccessTestDelegate& operator=(const SwitchAccessTestDelegate&) = delete;
~SwitchAccessTestDelegate() override = default; ~SwitchAccessTestDelegate() override = default;
SwitchAccessCommand last_command() { return commands_.back(); } SwitchAccessCommand last_command() { return commands_.back(); }
...@@ -409,13 +412,12 @@ class SwitchAccessTestDelegate : public AccessibilityEventRewriterDelegate { ...@@ -409,13 +412,12 @@ class SwitchAccessTestDelegate : public AccessibilityEventRewriterDelegate {
commands_.push_back(command); commands_.push_back(command);
} }
void SendPointScanPoint(const gfx::PointF& point) override {} void SendPointScanPoint(const gfx::PointF& point) override {}
void SendMagnifierCommand(MagnifierCommand command) override {}
void DispatchKeyEventToChromeVox(std::unique_ptr<ui::Event>, bool) override {} void DispatchKeyEventToChromeVox(std::unique_ptr<ui::Event>, bool) override {}
void DispatchMouseEvent(std::unique_ptr<ui::Event>) override {} void DispatchMouseEvent(std::unique_ptr<ui::Event>) override {}
private: private:
std::vector<SwitchAccessCommand> commands_; std::vector<SwitchAccessCommand> commands_;
DISALLOW_COPY_AND_ASSIGN(SwitchAccessTestDelegate);
}; };
class SwitchAccessAccessibilityEventRewriterTest : public AshTestBase { class SwitchAccessAccessibilityEventRewriterTest : public AshTestBase {
...@@ -724,5 +726,107 @@ TEST_F(SwitchAccessAccessibilityEventRewriterTest, SetKeyboardInputTypes) { ...@@ -724,5 +726,107 @@ TEST_F(SwitchAccessAccessibilityEventRewriterTest, SetKeyboardInputTypes) {
EXPECT_TRUE(event_capturer_.last_key_event()); EXPECT_TRUE(event_capturer_.last_key_event());
} }
class MagnifierTestDelegate : public AccessibilityEventRewriterDelegate {
public:
MagnifierTestDelegate() = default;
MagnifierTestDelegate(const MagnifierTestDelegate&) = delete;
MagnifierTestDelegate& operator=(const MagnifierTestDelegate&) = delete;
~MagnifierTestDelegate() override = default;
MagnifierCommand last_command() { return commands_.back(); }
int command_count() { return commands_.size(); }
// AccessibilityEventRewriterDelegate:
void SendSwitchAccessCommand(SwitchAccessCommand command) override {}
void SendPointScanPoint(const gfx::PointF& point) override {}
void SendMagnifierCommand(MagnifierCommand command) override {
commands_.push_back(command);
}
void DispatchKeyEventToChromeVox(std::unique_ptr<ui::Event>, bool) override {}
void DispatchMouseEvent(std::unique_ptr<ui::Event>) override {}
private:
std::vector<MagnifierCommand> commands_;
};
class MagnifierAccessibilityEventRewriterTest : public AshTestBase {
public:
MagnifierAccessibilityEventRewriterTest() {
event_rewriter_chromeos_ =
std::make_unique<ui::EventRewriterChromeOS>(nullptr, nullptr, false);
}
~MagnifierAccessibilityEventRewriterTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
// This test triggers a resize of WindowTreeHost, which will end up
// throttling events. set_throttle_input_on_resize_for_testing() disables
// this.
aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
delegate_ = std::make_unique<MagnifierTestDelegate>();
accessibility_event_rewriter_ =
std::make_unique<AccessibilityEventRewriter>(
event_rewriter_chromeos_.get(), delegate_.get());
generator_ = AshTestBase::GetEventGenerator();
GetContext()->AddPreTargetHandler(&event_capturer_);
GetContext()->GetHost()->GetEventSource()->AddEventRewriter(
accessibility_event_rewriter_.get());
controller_ = Shell::Get()->accessibility_controller();
controller_->SetAccessibilityEventRewriter(
accessibility_event_rewriter_.get());
controller_->fullscreen_magnifier().SetEnabled(true);
}
void TearDown() override {
GetContext()->RemovePreTargetHandler(&event_capturer_);
generator_ = nullptr;
controller_ = nullptr;
accessibility_event_rewriter_.reset();
AshTestBase::TearDown();
}
protected:
ui::test::EventGenerator* generator_ = nullptr;
EventCapturer event_capturer_;
AccessibilityControllerImpl* controller_ = nullptr;
std::unique_ptr<MagnifierTestDelegate> delegate_;
std::unique_ptr<AccessibilityEventRewriter> accessibility_event_rewriter_;
std::unique_ptr<ui::EventRewriterChromeOS> event_rewriter_chromeos_;
};
TEST_F(MagnifierAccessibilityEventRewriterTest, CaptureKeys) {
// Press and release Ctrl+Alt+Up.
// Verify that the events are captured by AccessibilityEventRewriter.
generator_->PressKey(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
EXPECT_FALSE(event_capturer_.last_key_event());
EXPECT_EQ(MagnifierCommand::kMoveUp, delegate_->last_command());
generator_->ReleaseKey(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
EXPECT_FALSE(event_capturer_.last_key_event());
EXPECT_EQ(MagnifierCommand::kMoveStop, delegate_->last_command());
// Press and release Ctrl+Alt+Down.
// Verify that the events are captured by AccessibilityEventRewriter.
generator_->PressKey(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
EXPECT_FALSE(event_capturer_.last_key_event());
EXPECT_EQ(MagnifierCommand::kMoveDown, delegate_->last_command());
generator_->ReleaseKey(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
EXPECT_FALSE(event_capturer_.last_key_event());
EXPECT_EQ(MagnifierCommand::kMoveStop, delegate_->last_command());
// Press and release the "3" key.
// Verify that the events are not captured by AccessibilityEventRewriter.
generator_->PressKey(ui::VKEY_3, ui::EF_NONE);
EXPECT_TRUE(event_capturer_.last_key_event());
generator_->ReleaseKey(ui::VKEY_3, ui::EF_NONE);
EXPECT_TRUE(event_capturer_.last_key_event());
}
} // namespace } // namespace
} // namespace ash } // namespace ash
...@@ -115,6 +115,19 @@ enum class SwitchAccessCommand { ...@@ -115,6 +115,19 @@ enum class SwitchAccessCommand {
kPrevious, kPrevious,
}; };
enum class MagnifierCommand {
// Stop moving magnifier viewport.
kMoveStop,
// Command to move magnifier viewport up.
kMoveUp,
// Command to move magnifier viewport down.
kMoveDown,
// Command to move magnifier viewport left.
kMoveLeft,
// Command to move magnifier viewport right.
kMoveRight,
};
// The type of mouse event the Automatic Clicks feature should perform when // The type of mouse event the Automatic Clicks feature should perform when
// dwelling. These values are written to prefs and correspond to // dwelling. These values are written to prefs and correspond to
// AutoclickActionType in enums.xml, so should not be changed. New values // AutoclickActionType in enums.xml, so should not be changed. New values
......
...@@ -17,6 +17,7 @@ class Event; ...@@ -17,6 +17,7 @@ class Event;
namespace ash { namespace ash {
enum class SwitchAccessCommand; enum class SwitchAccessCommand;
enum class MagnifierCommand;
// Allows a client to implement event processing for accessibility features; // Allows a client to implement event processing for accessibility features;
// used for ChromeVox and Switch Access. // used for ChromeVox and Switch Access.
...@@ -37,6 +38,9 @@ class ASH_PUBLIC_EXPORT AccessibilityEventRewriterDelegate { ...@@ -37,6 +38,9 @@ class ASH_PUBLIC_EXPORT AccessibilityEventRewriterDelegate {
// Sends a point to Switch Access's Point Scan. // Sends a point to Switch Access's Point Scan.
virtual void SendPointScanPoint(const gfx::PointF& point) = 0; virtual void SendPointScanPoint(const gfx::PointF& point) = 0;
// Sends a command to Magnifier.
virtual void SendMagnifierCommand(MagnifierCommand command) = 0;
protected: protected:
virtual ~AccessibilityEventRewriterDelegate() {} virtual ~AccessibilityEventRewriterDelegate() {}
}; };
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
namespace { namespace {
std::string AccessibilityPrivateEnumForCommand( std::string ToString(ash::SwitchAccessCommand command) {
ash::SwitchAccessCommand command) {
switch (command) { switch (command) {
case ash::SwitchAccessCommand::kSelect: case ash::SwitchAccessCommand::kSelect:
return extensions::api::accessibility_private::ToString( return extensions::api::accessibility_private::ToString(
...@@ -44,6 +43,28 @@ std::string AccessibilityPrivateEnumForCommand( ...@@ -44,6 +43,28 @@ std::string AccessibilityPrivateEnumForCommand(
} }
} }
std::string ToString(ash::MagnifierCommand command) {
switch (command) {
case ash::MagnifierCommand::kMoveStop:
return extensions::api::accessibility_private::ToString(
extensions::api::accessibility_private::MAGNIFIER_COMMAND_MOVESTOP);
case ash::MagnifierCommand::kMoveUp:
return extensions::api::accessibility_private::ToString(
extensions::api::accessibility_private::MAGNIFIER_COMMAND_MOVEUP);
case ash::MagnifierCommand::kMoveDown:
return extensions::api::accessibility_private::ToString(
extensions::api::accessibility_private::MAGNIFIER_COMMAND_MOVEDOWN);
case ash::MagnifierCommand::kMoveLeft:
return extensions::api::accessibility_private::ToString(
extensions::api::accessibility_private::MAGNIFIER_COMMAND_MOVELEFT);
case ash::MagnifierCommand::kMoveRight:
return extensions::api::accessibility_private::ToString(
extensions::api::accessibility_private::MAGNIFIER_COMMAND_MOVERIGHT);
}
return "";
}
} // namespace } // namespace
AccessibilityEventRewriterDelegate::AccessibilityEventRewriterDelegate() { AccessibilityEventRewriterDelegate::AccessibilityEventRewriterDelegate() {
...@@ -90,7 +111,7 @@ void AccessibilityEventRewriterDelegate::SendSwitchAccessCommand( ...@@ -90,7 +111,7 @@ void AccessibilityEventRewriterDelegate::SendSwitchAccessCommand(
chromeos::AccessibilityManager::Get()->profile()); chromeos::AccessibilityManager::Get()->profile());
auto event_args = std::make_unique<base::ListValue>(); auto event_args = std::make_unique<base::ListValue>();
event_args->AppendString(AccessibilityPrivateEnumForCommand(command)); event_args->AppendString(ToString(command));
auto event = std::make_unique<extensions::Event>( auto event = std::make_unique<extensions::Event>(
extensions::events::ACCESSIBILITY_PRIVATE_ON_SWITCH_ACCESS_COMMAND, extensions::events::ACCESSIBILITY_PRIVATE_ON_SWITCH_ACCESS_COMMAND,
...@@ -123,6 +144,23 @@ void AccessibilityEventRewriterDelegate::SendPointScanPoint( ...@@ -123,6 +144,23 @@ void AccessibilityEventRewriterDelegate::SendPointScanPoint(
extension_misc::kSwitchAccessExtensionId, std::move(event)); extension_misc::kSwitchAccessExtensionId, std::move(event));
} }
void AccessibilityEventRewriterDelegate::SendMagnifierCommand(
ash::MagnifierCommand command) {
extensions::EventRouter* event_router = extensions::EventRouter::Get(
chromeos::AccessibilityManager::Get()->profile());
auto event_args = std::make_unique<base::ListValue>();
event_args->AppendString(ToString(command));
auto event = std::make_unique<extensions::Event>(
extensions::events::ACCESSIBILITY_PRIVATE_ON_SWITCH_ACCESS_COMMAND,
extensions::api::accessibility_private::OnMagnifierCommand::kEventName,
std::move(event_args));
event_router->DispatchEventWithLazyListener(
extension_misc::kAccessibilityCommonExtensionId, std::move(event));
}
void AccessibilityEventRewriterDelegate::OnUnhandledSpokenFeedbackEvent( void AccessibilityEventRewriterDelegate::OnUnhandledSpokenFeedbackEvent(
std::unique_ptr<ui::Event> event) const { std::unique_ptr<ui::Event> event) const {
ash::EventRewriterController::Get()->OnUnhandledSpokenFeedbackEvent( ash::EventRewriterController::Get()->OnUnhandledSpokenFeedbackEvent(
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
namespace ash { namespace ash {
enum class SwitchAccessCommand; enum class SwitchAccessCommand;
enum class MagnifierCommand;
} }
// Passes key events from Ash's EventRewriter to accessibility component // Passes key events from Ash's EventRewriter to accessibility component
...@@ -39,6 +40,7 @@ class AccessibilityEventRewriterDelegate ...@@ -39,6 +40,7 @@ class AccessibilityEventRewriterDelegate
void DispatchMouseEvent(std::unique_ptr<ui::Event> event) override; void DispatchMouseEvent(std::unique_ptr<ui::Event> event) override;
void SendSwitchAccessCommand(ash::SwitchAccessCommand command) override; void SendSwitchAccessCommand(ash::SwitchAccessCommand command) override;
void SendPointScanPoint(const gfx::PointF& point) override; void SendPointScanPoint(const gfx::PointF& point) override;
void SendMagnifierCommand(ash::MagnifierCommand command) override;
private: private:
// Reports unhandled key events to the EventRewriterController for dispatch. // Reports unhandled key events to the EventRewriterController for dispatch.
......
...@@ -38,6 +38,12 @@ ...@@ -38,6 +38,12 @@
"enum": [ "click", "swipeLeft1", "swipeUp1", "swipeRight1", "swipeDown1", "swipeLeft2", "swipeUp2", "swipeRight2", "swipeDown2", "swipeLeft3", "swipeUp3", "swipeRight3", "swipeDown3", "swipeLeft4", "swipeUp4", "swipeRight4", "swipeDown4", "tap2", "tap3", "tap4", "touchExplore" ], "enum": [ "click", "swipeLeft1", "swipeUp1", "swipeRight1", "swipeDown1", "swipeLeft2", "swipeUp2", "swipeRight2", "swipeDown2", "swipeLeft3", "swipeUp3", "swipeRight3", "swipeDown3", "swipeLeft4", "swipeUp4", "swipeRight4", "swipeDown4", "tap2", "tap3", "tap4", "touchExplore" ],
"description": "Accessibility gestures fired by the touch exploration controller." "description": "Accessibility gestures fired by the touch exploration controller."
}, },
{
"id": "MagnifierCommand",
"type": "string",
"enum": [ "moveStop", "moveUp", "moveDown", "moveLeft", "moveRight" ],
"description": "Commands for magnifier (e.g. move magnifier viewport up)."
},
{ {
"id": "SwitchAccessCommand", "id": "SwitchAccessCommand",
"type": "string", "type": "string",
...@@ -658,6 +664,18 @@ ...@@ -658,6 +664,18 @@
], ],
"platforms": ["chromeos"] "platforms": ["chromeos"]
}, },
{
"name": "onMagnifierCommand",
"type": "function",
"description": "Fired when Chrome OS has received a key event corresponding to a Magnifier command.",
"parameters": [
{
"name": "command",
"$ref": "MagnifierCommand"
}
],
"platforms": ["chromeos"]
},
{ {
"name": "onAnnounceForAccessibility", "name": "onAnnounceForAccessibility",
"type": "function", "type": "function",
......
...@@ -60,6 +60,17 @@ chrome.accessibilityPrivate.Gesture = { ...@@ -60,6 +60,17 @@ chrome.accessibilityPrivate.Gesture = {
TOUCH_EXPLORE: 'touchExplore', TOUCH_EXPLORE: 'touchExplore',
}; };
/**
* @enum {string}
*/
chrome.accessibilityPrivate.MagnifierCommand = {
MOVE_STOP: 'moveStop',
MOVE_UP: 'moveUp',
MOVE_DOWN: 'moveDown',
MOVE_LEFT: 'moveLeft',
MOVE_RIGHT: 'moveRight',
};
/** /**
* @enum {string} * @enum {string}
*/ */
...@@ -483,6 +494,13 @@ chrome.accessibilityPrivate.onSwitchAccessCommand; ...@@ -483,6 +494,13 @@ chrome.accessibilityPrivate.onSwitchAccessCommand;
*/ */
chrome.accessibilityPrivate.onPointScanSet; chrome.accessibilityPrivate.onPointScanSet;
/**
* Fired when Chrome OS has received a key event corresponding to a Magnifier
* command.
* @type {!ChromeEvent}
*/
chrome.accessibilityPrivate.onMagnifierCommand;
/** /**
* Fired when an internal component within accessibility wants to force speech * Fired when an internal component within accessibility wants to force speech
* output for an accessibility extension. Do not use without approval from * output for an accessibility extension. Do not use without approval from
......
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