Commit 30e08415 authored by Katie D's avatar Katie D Committed by Commit Bot

Plumbs Select-to-Speak state change and state change requests to Ash.

This will allow a button in the shelf to request Select-to-Speak state changes
and to be updated when Select-to-Speak updates its own state.

This builds off of https://chromium-review.googlesource.com/c/chromium/src/+/1030901
and the full working proof of concept can be seen at https://chromium-review.googlesource.com/c/chromium/src/+/1031550.

Still TODO: Add the button, and update the SelectToSpeakEventHandler to start
processing touch events or mouse when the button was clicked rather than just
when the search key was held down.

This change also adds tests for toggling Select-to-Speak on and off in
accessibility_manager, as those tests were missing.

Bug: 753018
Change-Id: I93bb77dc23bdfa855e991e31d67dc4e3b8271036
Reviewed-on: https://chromium-review.googlesource.com/1036198
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555451}
parent 8a2c87fe
......@@ -400,6 +400,21 @@ bool AccessibilityController::IsSelectToSpeakEnabled() const {
return select_to_speak_enabled_;
}
void AccessibilityController::RequestSelectToSpeakStateChange() {
client_->RequestSelectToSpeakStateChange();
}
void AccessibilityController::SetSelectToSpeakState(
mojom::SelectToSpeakState state) {
select_to_speak_state_ = state;
NotifyAccessibilityStatusChanged();
}
mojom::SelectToSpeakState AccessibilityController::GetSelectToSpeakState()
const {
return select_to_speak_state_;
}
void AccessibilityController::SetStickyKeysEnabled(bool enabled) {
if (!active_user_prefs_)
return;
......@@ -835,6 +850,8 @@ void AccessibilityController::UpdateSelectToSpeakFromPref() {
return;
select_to_speak_enabled_ = enabled;
select_to_speak_state_ =
mojom::SelectToSpeakState::kSelectToSpeakStateInactive;
NotifyAccessibilityStatusChanged();
}
......
......@@ -83,6 +83,9 @@ class ASH_EXPORT AccessibilityController
void SetSelectToSpeakEnabled(bool enabled);
bool IsSelectToSpeakEnabled() const;
void RequestSelectToSpeakStateChange();
mojom::SelectToSpeakState GetSelectToSpeakState() const;
void SetStickyKeysEnabled(bool enabled);
bool IsStickyKeysEnabled() const;
......@@ -138,6 +141,7 @@ class ASH_EXPORT AccessibilityController
void BrailleDisplayStateChanged(bool connected) override;
void SetFocusHighlightRect(const gfx::Rect& bounds_in_screen) override;
void SetAccessibilityPanelFullscreen(bool fullscreen) override;
void SetSelectToSpeakState(mojom::SelectToSpeakState state) override;
// SessionObserver:
void OnSigninScreenPrefServiceInitialized(PrefService* prefs) override;
......@@ -193,6 +197,9 @@ class ASH_EXPORT AccessibilityController
bool sticky_keys_enabled_ = false;
bool virtual_keyboard_enabled_ = false;
mojom::SelectToSpeakState select_to_speak_state_ =
mojom::SelectToSpeakState::kSelectToSpeakStateInactive;
// Used to control the highlights of caret, cursor and focus.
std::unique_ptr<AccessibilityHighlightController>
accessibility_highlight_controller_;
......
......@@ -439,6 +439,25 @@ TEST_F(AccessibilityControllerTest,
EXPECT_EQ(kChromeVoxEnabled, (*notifications.begin())->message());
}
TEST_F(AccessibilityControllerTest, SelectToSpeakStateChanges) {
AccessibilityController* controller =
Shell::Get()->accessibility_controller();
TestAccessibilityObserver observer;
controller->AddObserver(&observer);
controller->SetSelectToSpeakState(
ash::mojom::SelectToSpeakState::kSelectToSpeakStateSelecting);
EXPECT_EQ(controller->GetSelectToSpeakState(),
ash::mojom::SelectToSpeakState::kSelectToSpeakStateSelecting);
EXPECT_EQ(observer.status_changed_count_, 1);
controller->SetSelectToSpeakState(
ash::mojom::SelectToSpeakState::kSelectToSpeakStateSpeaking);
EXPECT_EQ(controller->GetSelectToSpeakState(),
ash::mojom::SelectToSpeakState::kSelectToSpeakStateSpeaking);
EXPECT_EQ(observer.status_changed_count_, 2);
}
namespace {
enum class TestUserLoginType {
......
......@@ -57,6 +57,8 @@ void TestAccessibilityControllerClient::ShouldToggleSpokenFeedbackViaTouch(
void TestAccessibilityControllerClient::PlaySpokenFeedbackToggleCountdown(
int tick_count) {}
void TestAccessibilityControllerClient::RequestSelectToSpeakStateChange() {}
int32_t TestAccessibilityControllerClient::GetPlayedEarconAndReset() {
int32_t tmp = sound_key_;
sound_key_ = -1;
......
......@@ -39,6 +39,7 @@ class TestAccessibilityControllerClient
void ShouldToggleSpokenFeedbackViaTouch(
ShouldToggleSpokenFeedbackViaTouchCallback callback) override;
void PlaySpokenFeedbackToggleCountdown(int tick_count) override;
void RequestSelectToSpeakStateChange() override;
int32_t GetPlayedEarconAndReset();
......
......@@ -68,6 +68,10 @@ interface AccessibilityController {
// Sets whether the accessibility panel is filling the entire screen (e.g. to
// show the expanded UI for the ChromeVox spoken feedback extension).
SetAccessibilityPanelFullscreen(bool fullscreen);
// Sets the current Select-to-Speak state. This should be used by the Select-
// to-Speak extension to inform ash of its updated state.
SetSelectToSpeakState(SelectToSpeakState state);
};
// Interface for ash to request accessibility service from its client (e.g.
......@@ -111,4 +115,10 @@ interface AccessibilityControllerClient {
// Plays tick sound indicating spoken feedback will be toggled after
// countdown.
PlaySpokenFeedbackToggleCountdown(int32 tick_count);
// Requests the Select-to-Speak extension to change its state. This lets users
// do the same things in tablet mode as with a keyboard. Specifically, if
// Select-to-Speak is not speaking, move to capturing state; if
// Select-to-Speak is speaking, cancel speaking and move to inactive state.
RequestSelectToSpeakStateChange();
};
......@@ -286,8 +286,8 @@ AccessibilityPrivateOnSelectToSpeakStateChangedFunction::Run() {
state = ash::mojom::SelectToSpeakState::kSelectToSpeakStateInactive;
}
// TODO(katie): Plumb state updates into AccessibilityManager for
// http://crbug.com/753018.
auto* accessibility_manager = chromeos::AccessibilityManager::Get();
accessibility_manager->OnSelectToSpeakStateChanged(state);
return RespondNow(NoArguments());
}
......
......@@ -473,7 +473,6 @@ void AccessibilityManager::OnTwoFingerTouchStart() {
extensions::EventRouter* event_router =
extensions::EventRouter::Get(profile());
CHECK(event_router);
auto event_args = std::make_unique<base::ListValue>();
auto event = std::make_unique<extensions::Event>(
......@@ -489,7 +488,6 @@ void AccessibilityManager::OnTwoFingerTouchStop() {
extensions::EventRouter* event_router =
extensions::EventRouter::Get(profile());
CHECK(event_router);
auto event_args = std::make_unique<base::ListValue>();
auto event = std::make_unique<extensions::Event>(
......@@ -538,9 +536,9 @@ void AccessibilityManager::HandleAccessibilityGesture(
ax::mojom::Gesture gesture) {
extensions::EventRouter* event_router =
extensions::EventRouter::Get(profile());
CHECK(event_router);
std::unique_ptr<base::ListValue> event_args(new base::ListValue());
std::unique_ptr<base::ListValue> event_args =
std::make_unique<base::ListValue>();
event_args->AppendString(ui::ToString(gesture));
std::unique_ptr<extensions::Event> event(new extensions::Event(
extensions::events::ACCESSIBILITY_PRIVATE_ON_ACCESSIBILITY_GESTURE,
......@@ -699,6 +697,33 @@ bool AccessibilityManager::IsSelectToSpeakEnabled() const {
return select_to_speak_enabled_;
}
void AccessibilityManager::RequestSelectToSpeakStateChange() {
extensions::EventRouter* event_router =
extensions::EventRouter::Get(profile_);
// Send an event to the Select-to-Speak extension requesting a state change.
std::unique_ptr<base::ListValue> event_args =
std::make_unique<base::ListValue>();
std::unique_ptr<extensions::Event> event(new extensions::Event(
extensions::events::
ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED,
extensions::api::accessibility_private::
OnSelectToSpeakStateChangeRequested::kEventName,
std::move(event_args)));
event_router->DispatchEventWithLazyListener(
extension_misc::kSelectToSpeakExtensionId, std::move(event));
}
void AccessibilityManager::OnSelectToSpeakStateChanged(
ash::mojom::SelectToSpeakState state) {
// TODO(katie): Forward the state change event to
// select_to_speak_event_handler_. The extension may have requested that the
// handler enter SELECTING state. Prepare to start capturing events from
// stylus, mouse or touch. http://crbug.com/753018.
accessibility_controller_->SetSelectToSpeakState(state);
}
void AccessibilityManager::OnSelectToSpeakChanged() {
if (!profile_)
return;
......@@ -1147,9 +1172,9 @@ void AccessibilityManager::PostLoadChromeVox() {
extensions::EventRouter* event_router =
extensions::EventRouter::Get(profile_);
CHECK(event_router);
std::unique_ptr<base::ListValue> event_args(new base::ListValue());
std::unique_ptr<base::ListValue> event_args =
std::make_unique<base::ListValue>();
std::unique_ptr<extensions::Event> event(new extensions::Event(
extensions::events::ACCESSIBILITY_PRIVATE_ON_INTRODUCE_CHROME_VOX,
extensions::api::accessibility_private::OnIntroduceChromeVox::kEventName,
......
......@@ -187,6 +187,12 @@ class AccessibilityManager
// Returns if select-to-speak is enabled.
bool IsSelectToSpeakEnabled() const;
// Requests that the Select-to-Speak extension change its state.
void RequestSelectToSpeakStateChange();
// Called when the Select-to-Speak extension state has changed.
void OnSelectToSpeakStateChanged(ash::mojom::SelectToSpeakState state);
// Invoked to enable or disable switch access.
void SetSwitchAccessEnabled(bool enabled);
......
......@@ -161,6 +161,14 @@ bool IsMonoAudioEnabled() {
return AccessibilityManager::Get()->IsMonoAudioEnabled();
}
void SetSelectToSpeakEnabled(bool enabled) {
AccessibilityManager::Get()->SetSelectToSpeakEnabled(enabled);
}
bool IsSelectToSpeakEnabled() {
return AccessibilityManager::Get()->IsSelectToSpeakEnabled();
}
void SetAlwaysShowMenuEnabledPref(bool enabled) {
GetActiveUserPrefs()->SetBoolean(
ash::prefs::kShouldAlwaysShowAccessibilityMenu, enabled);
......@@ -201,6 +209,11 @@ void SetMonoAudioEnabledPref(bool enabled) {
enabled);
}
void SetSelectToSpeakEnabledPref(bool enabled) {
GetActiveUserPrefs()->SetBoolean(
ash::prefs::kAccessibilitySelectToSpeakEnabled, enabled);
}
bool IsBrailleImeActive() {
InputMethodManager* imm = InputMethodManager::Get();
std::unique_ptr<InputMethodDescriptors> descriptors =
......@@ -252,6 +265,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) {
EXPECT_EQ(default_autoclick_delay_, GetAutoclickDelay());
EXPECT_FALSE(IsVirtualKeyboardEnabled());
EXPECT_FALSE(IsMonoAudioEnabled());
EXPECT_FALSE(IsSelectToSpeakEnabled());
SetLargeCursorEnabledPref(true);
EXPECT_TRUE(IsLargeCursorEnabled());
......@@ -274,6 +288,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) {
SetMonoAudioEnabledPref(true);
EXPECT_TRUE(IsMonoAudioEnabled());
SetSelectToSpeakEnabledPref(true);
EXPECT_TRUE(IsSelectToSpeakEnabled());
SetLargeCursorEnabledPref(false);
EXPECT_FALSE(IsLargeCursorEnabled());
......@@ -291,6 +308,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) {
SetMonoAudioEnabledPref(false);
EXPECT_FALSE(IsMonoAudioEnabled());
SetSelectToSpeakEnabledPref(false);
EXPECT_FALSE(IsSelectToSpeakEnabled());
}
IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest,
......@@ -351,6 +371,20 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest,
EXPECT_FALSE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
EXPECT_FALSE(IsMonoAudioEnabled());
observer.reset();
SetSelectToSpeakEnabled(true);
EXPECT_TRUE(observer.observed());
EXPECT_TRUE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
EXPECT_TRUE(IsSelectToSpeakEnabled());
observer.reset();
SetSelectToSpeakEnabled(false);
EXPECT_TRUE(observer.observed());
EXPECT_FALSE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
EXPECT_FALSE(IsSelectToSpeakEnabled());
}
IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest,
......@@ -411,6 +445,20 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest,
EXPECT_FALSE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
EXPECT_FALSE(IsMonoAudioEnabled());
observer.reset();
SetSelectToSpeakEnabledPref(true);
EXPECT_TRUE(observer.observed());
EXPECT_TRUE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
EXPECT_TRUE(IsSelectToSpeakEnabled());
observer.reset();
SetSelectToSpeakEnabledPref(false);
EXPECT_TRUE(observer.observed());
EXPECT_FALSE(observer.observed_enabled());
EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
EXPECT_FALSE(IsSelectToSpeakEnabled());
}
IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AccessibilityMenuVisibility) {
......@@ -457,6 +505,11 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AccessibilityMenuVisibility) {
EXPECT_TRUE(ShouldShowAccessibilityMenu());
SetMonoAudioEnabled(false);
EXPECT_FALSE(ShouldShowAccessibilityMenu());
SetSelectToSpeakEnabled(true);
EXPECT_TRUE(ShouldShowAccessibilityMenu());
SetSelectToSpeakEnabled(false);
EXPECT_FALSE(ShouldShowAccessibilityMenu());
}
// For signin screen to user session accessibility manager tests.
......
......@@ -138,6 +138,10 @@ void AccessibilityControllerClient::PlaySpokenFeedbackToggleCountdown(
tick_count);
}
void AccessibilityControllerClient::RequestSelectToSpeakStateChange() {
chromeos::AccessibilityManager::Get()->RequestSelectToSpeakStateChange();
}
void AccessibilityControllerClient::FlushForTesting() {
accessibility_controller_.FlushForTesting();
}
......
......@@ -35,6 +35,7 @@ class AccessibilityControllerClient
void ShouldToggleSpokenFeedbackViaTouch(
ShouldToggleSpokenFeedbackViaTouchCallback callback) override;
void PlaySpokenFeedbackToggleCountdown(int tick_count) override;
void RequestSelectToSpeakStateChange() override;
// Flushes the mojo pipe to ash.
void FlushForTesting();
......
......@@ -38,6 +38,7 @@ class TestAccessibilityController : ash::mojom::AccessibilityController {
void BrailleDisplayStateChanged(bool connected) override {}
void SetFocusHighlightRect(const gfx::Rect& bounds_in_screen) override {}
void SetAccessibilityPanelFullscreen(bool fullscreen) override {}
void SetSelectToSpeakState(ash::mojom::SelectToSpeakState state) override {}
bool was_client_set() const { return was_client_set_; }
......@@ -86,6 +87,10 @@ class FakeAccessibilityControllerClient : public AccessibilityControllerClient {
spoken_feedback_toggle_count_down_ = tick_count;
}
void RequestSelectToSpeakStateChange() override {
++select_to_speak_state_changes_;
}
ash::mojom::AccessibilityAlert last_a11y_alert_ =
ash::mojom::AccessibilityAlert::NONE;
int32_t last_sound_key_ = -1;
......@@ -95,6 +100,7 @@ class FakeAccessibilityControllerClient : public AccessibilityControllerClient {
int on_two_finger_touch_start_count_ = 0;
int on_two_finger_touch_stop_count_ = 0;
int spoken_feedback_toggle_count_down_ = -1;
int select_to_speak_state_changes_ = 0;
private:
DISALLOW_COPY_AND_ASSIGN(FakeAccessibilityControllerClient);
......@@ -177,4 +183,8 @@ TEST_F(AccessibilityControllerClientTest, MethodCalls) {
const int tick_count = 2;
client.PlaySpokenFeedbackToggleCountdown(tick_count);
EXPECT_EQ(tick_count, client.spoken_feedback_toggle_count_down_);
// Tests RequestSelectToSpeakStateChange method call.
client.RequestSelectToSpeakStateChange();
EXPECT_EQ(1, client.select_to_speak_state_changes_);
}
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