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

Side by Side Diff: chrome/browser/chromeos/accessibility/select_to_speak_event_handler.cc

Issue 2814213002: Refactor Select-to-speak so that mouse events are forwarded to the extension. (Closed)
Patch Set: Tests updated, ready for review Created 3 years, 7 months 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/chromeos/accessibility/select_to_speak_event_handler.h" 5 #include "chrome/browser/chromeos/accessibility/select_to_speak_event_handler.h"
6 6
7 #include "ash/shell.h" 7 #include "ash/shell.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "chrome/browser/chromeos/accessibility/event_handler_common.h"
9 #include "chrome/browser/speech/tts_controller.h" 10 #include "chrome/browser/speech/tts_controller.h"
10 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" 11 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
11 #include "chrome/common/extensions/api/automation_api_constants.h" 12 #include "chrome/common/extensions/extension_constants.h"
12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
13 #include "ui/accessibility/ax_tree_id_registry.h" 14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/render_widget_host.h"
16 #include "third_party/WebKit/public/platform/WebMouseEvent.h"
17 #include "ui/aura/client/screen_position_client.h"
14 #include "ui/aura/window.h" 18 #include "ui/aura/window.h"
15 #include "ui/display/display.h" 19 #include "ui/display/display.h"
20 #include "ui/events/blink/web_input_event.h"
16 #include "ui/events/event.h" 21 #include "ui/events/event.h"
17 #include "ui/views/view.h" 22 #include "ui/views/view.h"
18 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget.h"
19 24
20 namespace chromeos { 25 namespace chromeos {
21 26
27 namespace {
28
29 gfx::Point GetScreenLocationFromEvent(const ui::LocatedEvent& event) {
30 aura::Window* root =
31 static_cast<aura::Window*>(event.target())->GetRootWindow();
David Tseng 2017/05/07 06:10:27 Are all of these (|root|, |event.target()| always
dmazzoni 2017/05/10 19:43:18 I checked a few other places and it seems like the
32 aura::client::ScreenPositionClient* spc =
33 aura::client::GetScreenPositionClient(root);
34 if (!spc)
35 return event.root_location();
36
37 gfx::Point screen_location(event.root_location());
38 spc->ConvertPointToScreen(root, &screen_location);
39 return screen_location;
40 }
41 } // namespace
42
22 SelectToSpeakEventHandler::SelectToSpeakEventHandler() { 43 SelectToSpeakEventHandler::SelectToSpeakEventHandler() {
23 if (ash::Shell::HasInstance()) 44 if (ash::Shell::HasInstance())
24 ash::Shell::Get()->GetPrimaryRootWindow()->AddPreTargetHandler(this); 45 ash::Shell::Get()->GetPrimaryRootWindow()->AddPreTargetHandler(this);
25 } 46 }
26 47
27 SelectToSpeakEventHandler::~SelectToSpeakEventHandler() { 48 SelectToSpeakEventHandler::~SelectToSpeakEventHandler() {
28 if (ash::Shell::HasInstance()) 49 if (ash::Shell::HasInstance())
29 ash::Shell::Get()->GetPrimaryRootWindow()->RemovePreTargetHandler(this); 50 ash::Shell::Get()->GetPrimaryRootWindow()->RemovePreTargetHandler(this);
30 } 51 }
31 52
53 void SelectToSpeakEventHandler::CaptureForwardedEventsForTesting(
54 SelectToSpeakForwardedEventDelegateForTesting* delegate) {
55 event_delegate_for_testing_ = delegate;
56 }
57
32 void SelectToSpeakEventHandler::OnKeyEvent(ui::KeyEvent* event) { 58 void SelectToSpeakEventHandler::OnKeyEvent(ui::KeyEvent* event) {
33 DCHECK(event); 59 DCHECK(event);
34 60
35 // We can only call TtsController on the UI thread, make sure we 61 // We can only call TtsController on the UI thread, make sure we
36 // don't ever try to run this code on some other thread. 62 // don't ever try to run this code on some other thread.
37 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 63 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
38 64
39 ui::KeyboardCode key_code = event->key_code(); 65 ui::KeyboardCode key_code = event->key_code();
40 66
41 // Stop speech when the user taps and releases Control or Search 67 // Stop speech when the user taps and releases Control or Search
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 if (state_ == WAIT_FOR_MOUSE_RELEASE && 115 if (state_ == WAIT_FOR_MOUSE_RELEASE &&
90 event->type() == ui::ET_MOUSE_RELEASED) { 116 event->type() == ui::ET_MOUSE_RELEASED) {
91 CancelEvent(event); 117 CancelEvent(event);
92 state_ = INACTIVE; 118 state_ = INACTIVE;
93 return; 119 return;
94 } 120 }
95 121
96 if (state_ != CAPTURING) 122 if (state_ != CAPTURING)
97 return; 123 return;
98 124
99 // If we're in the capturing state, send accessibility events to 125 if (event->type() == ui::ET_MOUSE_RELEASED)
100 // the Select-to-speak extension based on the mouse event. 126 state_ = MOUSE_RELEASED;
101 // First, figure out what event to send. 127
102 ui::AXEvent ax_event = ui::AX_EVENT_NONE; 128 // If we're in the capturing state, forward the mouse event to
103 switch (event->type()) { 129 // select-to-speak.
104 case ui::ET_MOUSE_PRESSED: 130 if (event_delegate_for_testing_) {
105 ax_event = ui::AX_EVENT_MOUSE_PRESSED; 131 event_delegate_for_testing_->OnForwardEventToSelectToSpeakExtension(*event);
106 break; 132 } else {
107 case ui::ET_MOUSE_DRAGGED: 133 extensions::ExtensionHost* host = GetAccessibilityExtensionHost(
108 ax_event = ui::AX_EVENT_MOUSE_DRAGGED; 134 extension_misc::kSelectToSpeakExtensionId);
109 break; 135 if (!host)
110 case ui::ET_MOUSE_RELEASED:
111 state_ = MOUSE_RELEASED;
112 ax_event = ui::AX_EVENT_MOUSE_RELEASED;
113 break;
114 case ui::ET_MOUSE_MOVED:
115 case ui::ET_MOUSE_ENTERED:
116 case ui::ET_MOUSE_EXITED:
117 ax_event = ui::AX_EVENT_MOUSE_MOVED;
118 break;
119 default:
120 return; 136 return;
137
138 content::RenderViewHost* rvh = host->render_view_host();
139 if (!rvh)
140 return;
141
142 const blink::WebMouseEvent web_event =
143 ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent));
144 rvh->GetWidget()->ForwardMouseEvent(web_event);
121 } 145 }
122 146
123 CancelEvent(event); 147 CancelEvent(event);
124
125 ui::AXTreeIDRegistry* registry = ui::AXTreeIDRegistry::GetInstance();
126 ui::AXHostDelegate* delegate =
127 registry->GetHostDelegate(extensions::api::automation::kDesktopTreeID);
128 if (delegate) {
129 ui::AXActionData action;
130 action.action = ui::AX_ACTION_HIT_TEST;
131 action.target_point = event->root_location();
132 action.hit_test_event_to_fire = ax_event;
133 delegate->PerformAction(action);
134 }
135 } 148 }
136 149
137 void SelectToSpeakEventHandler::CancelEvent(ui::Event* event) { 150 void SelectToSpeakEventHandler::CancelEvent(ui::Event* event) {
138 DCHECK(event); 151 DCHECK(event);
139 if (event->cancelable()) { 152 if (event->cancelable()) {
140 event->SetHandled(); 153 event->SetHandled();
141 event->StopPropagation(); 154 event->StopPropagation();
142 } 155 }
143 } 156 }
144 157
145 void SelectToSpeakEventHandler::SendCancelAXEvent() { 158 void SelectToSpeakEventHandler::SendCancelAXEvent() {
146 AutomationManagerAura::GetInstance()->HandleEvent( 159 AutomationManagerAura::GetInstance()->HandleEvent(
147 nullptr, nullptr, ui::AX_EVENT_MOUSE_CANCELED); 160 nullptr, nullptr, ui::AX_EVENT_MOUSE_CANCELED);
148 } 161 }
149 162
150 } // namespace chromeos 163 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698