| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| |
| #include "base/sys_info.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/aura/root_window.h" |
| #include "ui/aura/root_window_host_x11.h" |
| #include "ui/aura/test/aura_test_base.h" |
| #include "ui/aura/window_tree_host_delegate.h" |
| #include "ui/events/x/events_x_utils.h" |
| |
| namespace { |
| class TestRootWindowHostDelegate : public aura::RootWindowHostDelegate { |
| public: |
| TestRootWindowHostDelegate() : last_touch_type_(ui::ET_UNKNOWN), |
| last_touch_id_(-1), |
| last_touch_location_(0, 0) { |
| } |
| virtual ~TestRootWindowHostDelegate() {} |
| |
| virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE { |
| return true; |
| } |
| |
| virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE { |
| return true; |
| } |
| virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE { |
| return true; |
| } |
| |
| virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE { |
| last_touch_id_ = event->touch_id(); |
| last_touch_type_ = event->type(); |
| last_touch_location_ = event->location(); |
| return true; |
| } |
| |
| virtual void OnHostCancelMode() OVERRIDE {} |
| |
| // Called when the windowing system activates the window. |
| virtual void OnHostActivated() OVERRIDE {} |
| |
| // Called when system focus is changed to another window. |
| virtual void OnHostLostWindowCapture() OVERRIDE {} |
| |
| // Called when the windowing system has mouse grab because it's performing a |
| // window move on our behalf, but we should still paint as if we're active. |
| virtual void OnHostLostMouseGrab() OVERRIDE {} |
| |
| virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE {} |
| |
| virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE {} |
| virtual void OnHostResized(const gfx::Size& size) OVERRIDE {} |
| |
| virtual float GetDeviceScaleFactor() OVERRIDE { |
| return 1.0f; |
| } |
| |
| virtual aura::RootWindow* AsRootWindow() OVERRIDE { |
| return NULL; |
| } |
| virtual const aura::RootWindow* AsRootWindow() const OVERRIDE { |
| return NULL; |
| } |
| |
| ui::EventType last_touch_type() { |
| return last_touch_type_; |
| } |
| |
| int last_touch_id() { |
| return last_touch_id_; |
| } |
| |
| gfx::Point last_touch_location() { |
| return last_touch_location_; |
| } |
| |
| private: |
| ui::EventType last_touch_type_; |
| int last_touch_id_; |
| gfx::Point last_touch_location_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestRootWindowHostDelegate); |
| }; |
| |
| } // namespace |
| |
| namespace aura { |
| |
| typedef test::AuraTestBase RootWindowHostX11Test; |
| |
| // Send X touch events to one RootWindowHost. The RootWindowHost's |
| // delegate will get corresponding ui::TouchEvent if the touch events |
| // are winthin the bound of the RootWindowHost. |
| TEST_F(RootWindowHostX11Test, DispatchTouchEventToOneRootWindow) { |
| #if defined(OS_CHROMEOS) |
| // Fake a ChromeOS running env. |
| const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; |
| base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); |
| #endif // defined(OS_CHROMEOS) |
| |
| scoped_ptr<RootWindowHostX11> root_window_host( |
| new RootWindowHostX11(gfx::Rect(0, 0, 2560, 1700))); |
| scoped_ptr<TestRootWindowHostDelegate> delegate( |
| new TestRootWindowHostDelegate()); |
| root_window_host->set_delegate(delegate.get()); |
| |
| std::vector<unsigned int> devices; |
| devices.push_back(0); |
| ui::SetupTouchDevicesForTest(devices); |
| std::vector<ui::Valuator> valuators; |
| |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate->last_touch_type()); |
| EXPECT_EQ(-1, delegate->last_touch_id()); |
| |
| #if defined(OS_CHROMEOS) |
| // This touch is out of bounds. |
| ui::ScopedXI2Event event1(ui::CreateTouchEventForTest( |
| 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators)); |
| root_window_host->Dispatch(event1); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate->last_touch_type()); |
| EXPECT_EQ(-1, delegate->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate->last_touch_location()); |
| #endif // defined(OS_CHROMEOS) |
| |
| // Following touchs are within bounds and are passed to delegate. |
| ui::ScopedXI2Event event2(ui::CreateTouchEventForTest( |
| 0, XI_TouchBegin, 5, gfx::Point(1500, 1500), valuators)); |
| root_window_host->Dispatch(event2); |
| EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate->last_touch_type()); |
| EXPECT_EQ(0, delegate->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 1500), delegate->last_touch_location()); |
| |
| ui::ScopedXI2Event event3(ui::CreateTouchEventForTest( |
| 0, XI_TouchUpdate, 5, gfx::Point(1500, 1600), valuators)); |
| root_window_host->Dispatch(event3); |
| EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate->last_touch_type()); |
| EXPECT_EQ(0, delegate->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 1600), delegate->last_touch_location()); |
| |
| ui::ScopedXI2Event event4(ui::CreateTouchEventForTest( |
| 0, XI_TouchEnd, 5, gfx::Point(1500, 1600), valuators)); |
| root_window_host->Dispatch(event4); |
| EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate->last_touch_type()); |
| EXPECT_EQ(0, delegate->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 1600), delegate->last_touch_location()); |
| |
| // Revert the CrOS testing env otherwise the following non-CrOS aura |
| // tests will fail. |
| #if defined(OS_CHROMEOS) |
| // Fake a ChromeOS running env. |
| kLsbRelease = ""; |
| base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); |
| #endif // defined(OS_CHROMEOS) |
| } |
| |
| // Send X touch events to two RootWindowHost. The RootWindowHost which is |
| // the event target of the X touch events should generate the corresponding |
| // ui::TouchEvent for its delegate. |
| #if defined(OS_CHROMEOS) |
| TEST_F(RootWindowHostX11Test, DispatchTouchEventToTwoRootWindow) { |
| // Fake a ChromeOS running env. |
| const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; |
| base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); |
| |
| scoped_ptr<RootWindowHostX11> root_window_host1( |
| new RootWindowHostX11(gfx::Rect(0, 0, 2560, 1700))); |
| scoped_ptr<TestRootWindowHostDelegate> delegate1( |
| new TestRootWindowHostDelegate()); |
| root_window_host1->set_delegate(delegate1.get()); |
| |
| int host2_y_offset = 1700; |
| scoped_ptr<RootWindowHostX11> root_window_host2( |
| new RootWindowHostX11(gfx::Rect(0, host2_y_offset, 1920, 1080))); |
| scoped_ptr<TestRootWindowHostDelegate> delegate2( |
| new TestRootWindowHostDelegate()); |
| root_window_host2->set_delegate(delegate2.get()); |
| |
| std::vector<unsigned int> devices; |
| devices.push_back(0); |
| ui::SetupTouchDevicesForTest(devices); |
| std::vector<ui::Valuator> valuators; |
| |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate2->last_touch_type()); |
| EXPECT_EQ(-1, delegate2->last_touch_id()); |
| |
| // 2 Touch events are targeted at the second RootWindowHost. |
| ui::ScopedXI2Event touch1_begin(ui::CreateTouchEventForTest( |
| 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators)); |
| root_window_host1->Dispatch(touch1_begin); |
| root_window_host2->Dispatch(touch1_begin); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate2->last_touch_type()); |
| EXPECT_EQ(0, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 2500 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| ui::ScopedXI2Event touch2_begin(ui::CreateTouchEventForTest( |
| 0, XI_TouchBegin, 6, gfx::Point(1600, 2600), valuators)); |
| root_window_host1->Dispatch(touch2_begin); |
| root_window_host2->Dispatch(touch2_begin); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_PRESSED, delegate2->last_touch_type()); |
| EXPECT_EQ(1, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1600, 2600 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| ui::ScopedXI2Event touch1_move(ui::CreateTouchEventForTest( |
| 0, XI_TouchUpdate, 5, gfx::Point(1500, 2550), valuators)); |
| root_window_host1->Dispatch(touch1_move); |
| root_window_host2->Dispatch(touch1_move); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate2->last_touch_type()); |
| EXPECT_EQ(0, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| ui::ScopedXI2Event touch2_move(ui::CreateTouchEventForTest( |
| 0, XI_TouchUpdate, 6, gfx::Point(1600, 2650), valuators)); |
| root_window_host1->Dispatch(touch2_move); |
| root_window_host2->Dispatch(touch2_move); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_MOVED, delegate2->last_touch_type()); |
| EXPECT_EQ(1, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| ui::ScopedXI2Event touch1_end(ui::CreateTouchEventForTest( |
| 0, XI_TouchEnd, 5, gfx::Point(1500, 2550), valuators)); |
| root_window_host1->Dispatch(touch1_end); |
| root_window_host2->Dispatch(touch1_end); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate2->last_touch_type()); |
| EXPECT_EQ(0, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| ui::ScopedXI2Event touch2_end(ui::CreateTouchEventForTest( |
| 0, XI_TouchEnd, 6, gfx::Point(1600, 2650), valuators)); |
| root_window_host1->Dispatch(touch2_end); |
| root_window_host2->Dispatch(touch2_end); |
| EXPECT_EQ(ui::ET_UNKNOWN, delegate1->last_touch_type()); |
| EXPECT_EQ(-1, delegate1->last_touch_id()); |
| EXPECT_EQ(gfx::Point(0, 0), delegate1->last_touch_location()); |
| EXPECT_EQ(ui::ET_TOUCH_RELEASED, delegate2->last_touch_type()); |
| EXPECT_EQ(1, delegate2->last_touch_id()); |
| EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset), |
| delegate2->last_touch_location()); |
| |
| // Revert the CrOS testing env otherwise the following non-CrOS aura |
| // tests will fail. |
| // Fake a ChromeOS running env. |
| kLsbRelease = ""; |
| base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); |
| } |
| #endif // defined(OS_CHROMEOS) |
| |
| } // namespace aura |