1 // Copyright 2013 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.
4
5
6 #include "base/sys_info.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/aura/root_window.h"
9 #include "ui/aura/root_window_host_x11.h"
10 #include "ui/aura/test/aura_test_base.h"
11 #include "ui/aura/window_tree_host_delegate.h"
12 #include "ui/events/event_processor.h"
13 #include "ui/events/event_target.h"
14 #include "ui/events/event_target_iterator.h"
15 #include "ui/events/test/events_test_utils_x11.h"
16
17 namespace {
18 class TestRootWindowHostDelegate : public aura::RootWindowHostDelegate,
19 public ui::EventProcessor,
20 public ui::EventTarget {
21 public:
TestRootWindowHostDelegate()22 TestRootWindowHostDelegate() : last_touch_type_(ui::ET_UNKNOWN),
23 last_touch_id_(-1),
24 last_touch_location_(0, 0) {
25 }
~TestRootWindowHostDelegate()26 virtual ~TestRootWindowHostDelegate() {}
27
28 // aura::RootWindowHostDelegate:
OnHostKeyEvent(ui::KeyEvent * event)29 virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE {
30 return true;
31 }
OnHostMouseEvent(ui::MouseEvent * event)32 virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE {
33 return true;
34 }
OnHostScrollEvent(ui::ScrollEvent * event)35 virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE {
36 return true;
37 }
OnHostTouchEvent(ui::TouchEvent * event)38 virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE {
39 last_touch_id_ = event->touch_id();
40 last_touch_type_ = event->type();
41 last_touch_location_ = event->location();
42 return true;
43 }
44
OnHostCancelMode()45 virtual void OnHostCancelMode() OVERRIDE {}
OnHostActivated()46 virtual void OnHostActivated() OVERRIDE {}
OnHostLostWindowCapture()47 virtual void OnHostLostWindowCapture() OVERRIDE {}
OnHostLostMouseGrab()48 virtual void OnHostLostMouseGrab() OVERRIDE {}
OnHostPaint(const gfx::Rect & damage_rect)49 virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE {}
OnHostMoved(const gfx::Point & origin)50 virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE {}
OnHostResized(const gfx::Size & size)51 virtual void OnHostResized(const gfx::Size& size) OVERRIDE {}
GetDeviceScaleFactor()52 virtual float GetDeviceScaleFactor() OVERRIDE { return 1.0f; }
AsRootWindow()53 virtual aura::RootWindow* AsRootWindow() OVERRIDE { return NULL; }
AsRootWindow() const54 virtual const aura::RootWindow* AsRootWindow() const OVERRIDE { return NULL; }
GetEventProcessor()55 virtual ui::EventProcessor* GetEventProcessor() OVERRIDE {
56 return this;
57 }
58
59 // ui::EventProcessor:
GetRootTarget()60 virtual ui::EventTarget* GetRootTarget() OVERRIDE { return this; }
CanDispatchToTarget(ui::EventTarget * target)61 virtual bool CanDispatchToTarget(ui::EventTarget* target) OVERRIDE {
62 return true;
63 }
64
65 // ui::EventHandler:
OnTouchEvent(ui::TouchEvent * event)66 virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
67 last_touch_id_ = event->touch_id();
68 last_touch_type_ = event->type();
69 last_touch_location_ = event->location();
70 }
71
72 // ui::EventTarget:
CanAcceptEvent(const ui::Event & event)73 virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE {
74 return true;
75 }
GetParentTarget()76 virtual ui::EventTarget* GetParentTarget() OVERRIDE { return NULL; }
77 virtual scoped_ptr<ui::EventTargetIterator>
GetChildIterator() const78 GetChildIterator() const OVERRIDE {
79 return scoped_ptr<ui::EventTargetIterator>();
80 }
GetEventTargeter()81 virtual ui::EventTargeter* GetEventTargeter() OVERRIDE { return &targeter_; }
82
last_touch_type()83 ui::EventType last_touch_type() {
84 return last_touch_type_;
85 }
86
last_touch_id()87 int last_touch_id() {
88 return last_touch_id_;
89 }
90
last_touch_location()91 gfx::Point last_touch_location() {
92 return last_touch_location_;
93 }
94
95 private:
96 ui::EventType last_touch_type_;
97 int last_touch_id_;
98 gfx::Point last_touch_location_;
99 ui::EventTargeter targeter_;
100
101 DISALLOW_COPY_AND_ASSIGN(TestRootWindowHostDelegate);
102 };
103
104 } // namespace
105
106 namespace aura {
107
108 typedef test::AuraTestBase RootWindowHostX11Test;
109
110 // Send X touch events to one RootWindowHost. The RootWindowHost's
111 // delegate will get corresponding ui::TouchEvent if the touch events
112 // are winthin the bound of the RootWindowHost.
TEST_F(RootWindowHostX11Test,DispatchTouchEventToOneRootWindow)113 TEST_F(RootWindowHostX11Test, DispatchTouchEventToOneRootWindow) {
114 #if defined(OS_CHROMEOS)
115 // Fake a ChromeOS running env.
116 const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n";
117 base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time());
118 #endif // defined(OS_CHROMEOS)
119
120 scoped_ptr<RootWindowHostX11> root_window_host(
121 new RootWindowHostX11(gfx::Rect(0, 0, 2560, 1700)));
122 scoped_ptr<TestRootWindowHostDelegate> delegate(
123 new TestRootWindowHostDelegate());
124 root_window_host->set_delegate(delegate.get());
125
126 std::vector<unsigned int> devices;
127 devices.push_back(0);
128 ui::SetUpTouchDevicesForTest(devices);
129 std::vector<ui::Valuator> valuators;
130
131 EXPECT_EQ(ui::ET_UNKNOWN, delegate->last_touch_type());
132 EXPECT_EQ(-1, delegate->last_touch_id());
133
134 ui::ScopedXI2Event scoped_xevent;
135 #if defined(OS_CHROMEOS)
136 // This touch is out of bounds.
137 scoped_xevent.InitTouchEvent(
138 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators);
139 root_window_host->Dispatch(scoped_xevent);
140 EXPECT_EQ(ui::ET_UNKNOWN, delegate->last_touch_type());
141 EXPECT_EQ(-1, delegate->last_touch_id());
142 EXPECT_EQ(gfx::Point(0, 0), delegate->last_touch_location());
143 #endif // defined(OS_CHROMEOS)
144
145 // Following touchs are within bounds and are passed to delegate.
146 scoped_xevent.InitTouchEvent(
147 0, XI_TouchBegin, 5, gfx::Point(1500, 1500), valuators);
148 root_window_host->Dispatch(scoped_xevent);
149 EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate->last_touch_type());
150 EXPECT_EQ(0, delegate->last_touch_id());
151 EXPECT_EQ(gfx::Point(1500, 1500), delegate->last_touch_location());
152
153 scoped_xevent.InitTouchEvent(
154 0, XI_TouchUpdate, 5, gfx::Point(1500, 1600), valuators);
155 root_window_host->Dispatch(scoped_xevent);
156 EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate->last_touch_type());
157 EXPECT_EQ(0, delegate->last_touch_id());
158 EXPECT_EQ(gfx::Point(1500, 1600), delegate->last_touch_location());
159
160 scoped_xevent.InitTouchEvent(
161 0, XI_TouchEnd, 5, gfx::Point(1500, 1600), valuators);
162 root_window_host->Dispatch(scoped_xevent);
163 EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate->last_touch_type());
164 EXPECT_EQ(0, delegate->last_touch_id());
165 EXPECT_EQ(gfx::Point(1500, 1600), delegate->last_touch_location());
166
167 // Revert the CrOS testing env otherwise the following non-CrOS aura
168 // tests will fail.
169 #if defined(OS_CHROMEOS)
170 // Fake a ChromeOS running env.
171 kLsbRelease = "";
172 base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time());
173 #endif // defined(OS_CHROMEOS)
174 }
175
176 // Send X touch events to two RootWindowHost. The RootWindowHost which is
177 // the event target of the X touch events should generate the corresponding
178 // ui::TouchEvent for its delegate.
179 #if defined(OS_CHROMEOS)
TEST_F(RootWindowHostX11Test,DispatchTouchEventToTwoRootWindow)180 TEST_F(RootWindowHostX11Test, DispatchTouchEventToTwoRootWindow) {
181 // Fake a ChromeOS running env.
182 const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n";
183 base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time());
184
185 scoped_ptr<RootWindowHostX11> root_window_host1(
186 new RootWindowHostX11(gfx::Rect(0, 0, 2560, 1700)));
187 scoped_ptr<TestRootWindowHostDelegate> delegate1(
188 new TestRootWindowHostDelegate());
189 root_window_host1->set_delegate(delegate1.get());
190
191 int host2_y_offset = 1700;
192 scoped_ptr<RootWindowHostX11> root_window_host2(
193 new RootWindowHostX11(gfx::Rect(0, host2_y_offset, 1920, 1080)));
194 scoped_ptr<TestRootWindowHostDelegate> delegate2(
195 new TestRootWindowHostDelegate());
196 root_window_host2->set_delegate(delegate2.get());
197
198 std::vector<unsigned int> devices;
199 devices.push_back(0);
200 ui::SetUpTouchDevicesForTest(devices);
201 std::vector<ui::Valuator> valuators;
202
203 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
204 EXPECT_EQ(-1, delegate1->last_touch_id());
205 EXPECT_EQ(ui::ET_UNKNOWN, delegate2->last_touch_type());
206 EXPECT_EQ(-1, delegate2->last_touch_id());
207
208 // 2 Touch events are targeted at the second RootWindowHost.
209 ui::ScopedXI2Event scoped_xevent;
210 scoped_xevent.InitTouchEvent(
211 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators);
212 root_window_host1->Dispatch(scoped_xevent);
213 root_window_host2->Dispatch(scoped_xevent);
214 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
215 EXPECT_EQ(-1, delegate1->last_touch_id());
216 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
217 EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate2->last_touch_type());
218 EXPECT_EQ(0, delegate2->last_touch_id());
219 EXPECT_EQ(gfx::Point(1500, 2500 - host2_y_offset),
220 delegate2->last_touch_location());
221
222 scoped_xevent.InitTouchEvent(
223 0, XI_TouchBegin, 6, gfx::Point(1600, 2600), valuators);
224 root_window_host1->Dispatch(scoped_xevent);
225 root_window_host2->Dispatch(scoped_xevent);
226 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
227 EXPECT_EQ(-1, delegate1->last_touch_id());
228 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
229 EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate2->last_touch_type());
230 EXPECT_EQ(1, delegate2->last_touch_id());
231 EXPECT_EQ(gfx::Point(1600, 2600 - host2_y_offset),
232 delegate2->last_touch_location());
233
234 scoped_xevent.InitTouchEvent(
235 0, XI_TouchUpdate, 5, gfx::Point(1500, 2550), valuators);
236 root_window_host1->Dispatch(scoped_xevent);
237 root_window_host2->Dispatch(scoped_xevent);
238 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
239 EXPECT_EQ(-1, delegate1->last_touch_id());
240 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
241 EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate2->last_touch_type());
242 EXPECT_EQ(0, delegate2->last_touch_id());
243 EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset),
244 delegate2->last_touch_location());
245
246 scoped_xevent.InitTouchEvent(
247 0, XI_TouchUpdate, 6, gfx::Point(1600, 2650), valuators);
248 root_window_host1->Dispatch(scoped_xevent);
249 root_window_host2->Dispatch(scoped_xevent);
250 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
251 EXPECT_EQ(-1, delegate1->last_touch_id());
252 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
253 EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate2->last_touch_type());
254 EXPECT_EQ(1, delegate2->last_touch_id());
255 EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset),
256 delegate2->last_touch_location());
257
258 scoped_xevent.InitTouchEvent(
259 0, XI_TouchEnd, 5, gfx::Point(1500, 2550), valuators);
260 root_window_host1->Dispatch(scoped_xevent);
261 root_window_host2->Dispatch(scoped_xevent);
262 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
263 EXPECT_EQ(-1, delegate1->last_touch_id());
264 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
265 EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate2->last_touch_type());
266 EXPECT_EQ(0, delegate2->last_touch_id());
267 EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset),
268 delegate2->last_touch_location());
269
270 scoped_xevent.InitTouchEvent(
271 0, XI_TouchEnd, 6, gfx::Point(1600, 2650), valuators);
272 root_window_host1->Dispatch(scoped_xevent);
273 root_window_host2->Dispatch(scoped_xevent);
274 EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type());
275 EXPECT_EQ(-1, delegate1->last_touch_id());
276 EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location());
277 EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate2->last_touch_type());
278 EXPECT_EQ(1, delegate2->last_touch_id());
279 EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset),
280 delegate2->last_touch_location());
281
282 // Revert the CrOS testing env otherwise the following non-CrOS aura
283 // tests will fail.
284 // Fake a ChromeOS running env.
285 kLsbRelease = "";
286 base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time());
287 }
288 #endif // defined(OS_CHROMEOS)
289
290 } // namespace aura
291