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: 22 TestRootWindowHostDelegate() : last_touch_type_(ui::ET_UNKNOWN), 23 last_touch_id_(-1), 24 last_touch_location_(0, 0) { 25 } 26 virtual ~TestRootWindowHostDelegate() {} 27 28 // aura::RootWindowHostDelegate: 29 virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE { 30 return true; 31 } 32 virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE { 33 return true; 34 } 35 virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE { 36 return true; 37 } 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 45 virtual void OnHostCancelMode() OVERRIDE {} 46 virtual void OnHostActivated() OVERRIDE {} 47 virtual void OnHostLostWindowCapture() OVERRIDE {} 48 virtual void OnHostLostMouseGrab() OVERRIDE {} 49 virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE {} 50 virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE {} 51 virtual void OnHostResized(const gfx::Size& size) OVERRIDE {} 52 virtual float GetDeviceScaleFactor() OVERRIDE { return 1.0f; } 53 virtual aura::RootWindow* AsRootWindow() OVERRIDE { return NULL; } 54 virtual const aura::RootWindow* AsRootWindow() const OVERRIDE { return NULL; } 55 virtual ui::EventProcessor* GetEventProcessor() OVERRIDE { 56 return this; 57 } 58 59 // ui::EventProcessor: 60 virtual ui::EventTarget* GetRootTarget() OVERRIDE { return this; } 61 virtual bool CanDispatchToTarget(ui::EventTarget* target) OVERRIDE { 62 return true; 63 } 64 65 // ui::EventHandler: 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: 73 virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE { 74 return true; 75 } 76 virtual ui::EventTarget* GetParentTarget() OVERRIDE { return NULL; } 77 virtual scoped_ptr<ui::EventTargetIterator> 78 GetChildIterator() const OVERRIDE { 79 return scoped_ptr<ui::EventTargetIterator>(); 80 } 81 virtual ui::EventTargeter* GetEventTargeter() OVERRIDE { return &targeter_; } 82 83 ui::EventType last_touch_type() { 84 return last_touch_type_; 85 } 86 87 int last_touch_id() { 88 return last_touch_id_; 89 } 90 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. 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) 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