Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / aura / test / ui_controls_factory_ozone.cc
bloba928275da3e72eaf97154b071119879c5627ecf7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/logging.h"
7 #include "ui/aura/client/screen_position_client.h"
8 #include "ui/aura/env.h"
9 #include "ui/aura/test/aura_test_utils.h"
10 #include "ui/aura/test/ui_controls_factory_aura.h"
11 #include "ui/aura/window_tree_host.h"
12 #include "ui/base/test/ui_controls_aura.h"
13 #include "ui/events/event_utils.h"
14 #include "ui/events/test/events_test_utils.h"
16 namespace aura {
17 namespace test {
18 namespace {
20 class UIControlsOzone : public ui_controls::UIControlsAura {
21 public:
22 UIControlsOzone(WindowTreeHost* host) : host_(host) {}
24 bool SendKeyPress(gfx::NativeWindow window,
25 ui::KeyboardCode key,
26 bool control,
27 bool shift,
28 bool alt,
29 bool command) override {
30 return SendKeyPressNotifyWhenDone(
31 window, key, control, shift, alt, command, base::Closure());
33 bool SendKeyPressNotifyWhenDone(
34 gfx::NativeWindow window,
35 ui::KeyboardCode key,
36 bool control,
37 bool shift,
38 bool alt,
39 bool command,
40 const base::Closure& closure) override {
41 int flags = button_down_mask_;
43 if (control) {
44 flags |= ui::EF_CONTROL_DOWN;
45 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, flags);
48 if (shift) {
49 flags |= ui::EF_SHIFT_DOWN;
50 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, flags);
53 if (alt) {
54 flags |= ui::EF_ALT_DOWN;
55 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_MENU, flags);
58 if (command) {
59 flags |= ui::EF_COMMAND_DOWN;
60 PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LWIN, flags);
63 PostKeyEvent(ui::ET_KEY_PRESSED, key, flags);
64 PostKeyEvent(ui::ET_KEY_RELEASED, key, flags);
66 if (alt) {
67 flags &= ~ui::EF_ALT_DOWN;
68 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_MENU, flags);
71 if (shift) {
72 flags &= ~ui::EF_SHIFT_DOWN;
73 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, flags);
76 if (control) {
77 flags &= ~ui::EF_CONTROL_DOWN;
78 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, flags);
81 if (command) {
82 flags &= ~ui::EF_COMMAND_DOWN;
83 PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_LWIN, flags);
86 RunClosureAfterAllPendingUIEvents(closure);
87 return true;
90 bool SendMouseMove(long screen_x, long screen_y) override {
91 return SendMouseMoveNotifyWhenDone(screen_x, screen_y, base::Closure());
93 bool SendMouseMoveNotifyWhenDone(
94 long screen_x,
95 long screen_y,
96 const base::Closure& closure) override {
97 gfx::Point root_location(screen_x, screen_y);
98 aura::client::ScreenPositionClient* screen_position_client =
99 aura::client::GetScreenPositionClient(host_->window());
100 if (screen_position_client) {
101 screen_position_client->ConvertPointFromScreen(host_->window(),
102 &root_location);
105 gfx::Point host_location = root_location;
106 host_->ConvertPointToHost(&host_location);
108 ui::EventType event_type;
110 if (button_down_mask_)
111 event_type = ui::ET_MOUSE_DRAGGED;
112 else
113 event_type = ui::ET_MOUSE_MOVED;
115 PostMouseEvent(event_type, host_location, 0, 0);
117 RunClosureAfterAllPendingUIEvents(closure);
118 return true;
120 bool SendMouseEvents(ui_controls::MouseButton type, int state) override {
121 return SendMouseEventsNotifyWhenDone(type, state, base::Closure());
123 bool SendMouseEventsNotifyWhenDone(
124 ui_controls::MouseButton type,
125 int state,
126 const base::Closure& closure) override {
127 gfx::Point root_location = aura::Env::GetInstance()->last_mouse_location();
128 aura::client::ScreenPositionClient* screen_position_client =
129 aura::client::GetScreenPositionClient(host_->window());
130 if (screen_position_client) {
131 screen_position_client->ConvertPointFromScreen(host_->window(),
132 &root_location);
135 gfx::Point host_location = root_location;
136 host_->ConvertPointToHost(&host_location);
138 int flag = 0;
140 switch (type) {
141 case ui_controls::LEFT:
142 flag = ui::EF_LEFT_MOUSE_BUTTON;
143 break;
144 case ui_controls::MIDDLE:
145 flag = ui::EF_MIDDLE_MOUSE_BUTTON;
146 break;
147 case ui_controls::RIGHT:
148 flag = ui::EF_RIGHT_MOUSE_BUTTON;
149 break;
150 default:
151 NOTREACHED();
152 break;
155 if (state & ui_controls::DOWN) {
156 button_down_mask_ |= flag;
157 PostMouseEvent(ui::ET_MOUSE_PRESSED, host_location,
158 button_down_mask_ | flag, flag);
160 if (state & ui_controls::UP) {
161 button_down_mask_ &= ~flag;
162 PostMouseEvent(ui::ET_MOUSE_RELEASED, host_location,
163 button_down_mask_ | flag, flag);
166 RunClosureAfterAllPendingUIEvents(closure);
167 return true;
169 bool SendMouseClick(ui_controls::MouseButton type) override {
170 return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN);
172 void RunClosureAfterAllPendingUIEvents(
173 const base::Closure& closure) override {
174 if (!closure.is_null())
175 base::MessageLoop::current()->PostTask(FROM_HERE, closure);
178 private:
179 void SendEventToProcessor(ui::Event* event) {
180 ui::EventSourceTestApi event_source_test(host_->GetEventSource());
181 ui::EventDispatchDetails details =
182 event_source_test.SendEventToProcessor(event);
183 if (details.dispatcher_destroyed)
184 return;
187 void PostKeyEvent(ui::EventType type, ui::KeyboardCode key_code, int flags) {
188 base::MessageLoop::current()->PostTask(
189 FROM_HERE,
190 base::Bind(&UIControlsOzone::PostKeyEventTask,
191 base::Unretained(this),
192 type,
193 key_code,
194 flags));
197 void PostKeyEventTask(ui::EventType type,
198 ui::KeyboardCode key_code,
199 int flags) {
200 // Do not rewrite injected events. See crbug.com/136465.
201 flags |= ui::EF_FINAL;
203 ui::KeyEvent key_event(type, key_code, flags);
204 SendEventToProcessor(&key_event);
207 void PostMouseEvent(ui::EventType type,
208 const gfx::PointF& host_location,
209 int flags,
210 int changed_button_flags) {
211 base::MessageLoop::current()->PostTask(
212 FROM_HERE,
213 base::Bind(&UIControlsOzone::PostMouseEventTask, base::Unretained(this),
214 type, host_location, flags, changed_button_flags));
217 void PostMouseEventTask(ui::EventType type,
218 const gfx::PointF& host_location,
219 int flags,
220 int changed_button_flags) {
221 ui::MouseEvent mouse_event(type, host_location, host_location,
222 ui::EventTimeForNow(), flags,
223 changed_button_flags);
225 // This hack is necessary to set the repeat count for clicks.
226 ui::MouseEvent mouse_event2(&mouse_event);
228 SendEventToProcessor(&mouse_event2);
231 WindowTreeHost* host_;
233 // Mask of the mouse buttons currently down.
234 unsigned button_down_mask_ = 0;
236 DISALLOW_COPY_AND_ASSIGN(UIControlsOzone);
239 } // namespace
241 ui_controls::UIControlsAura* CreateUIControlsAura(WindowTreeHost* host) {
242 return new UIControlsOzone(host);
245 } // namespace test
246 } // namespace aura