diff options
author | oshima <oshima@chromium.org> | 2015-08-05 17:59:30 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-06 01:00:13 +0000 |
commit | c3cc7bf04463267ff3ef3979a0a8ebdb016f88a9 (patch) | |
tree | 55461b312c13bbe0d45e4ed3e8a47b65a223879b | |
parent | 8a04dba0d1867e3c2e034ab838ddaab393cbc126 (diff) | |
download | chromium_src-c3cc7bf04463267ff3ef3979a0a8ebdb016f88a9.zip chromium_src-c3cc7bf04463267ff3ef3979a0a8ebdb016f88a9.tar.gz chromium_src-c3cc7bf04463267ff3ef3979a0a8ebdb016f88a9.tar.bz2 |
Unified Desktop: Add unit test for mouse warp with 2x displays
* Added EventGenerator::MoveMouseToWithNative so that we can write a unit test that requires native motion event.
* Move the unified desktop specific code from test API because it now takes the argument in different coords.
BUG=514877
TEST=the test now covers 2x display scenarios.
Review URL: https://codereview.chromium.org/1259513006
Cr-Commit-Position: refs/heads/master@{#342032}
-rw-r--r-- | ash/display/display_util.cc | 15 | ||||
-rw-r--r-- | ash/display/unified_mouse_warp_controller.cc | 22 | ||||
-rw-r--r-- | ash/display/unified_mouse_warp_controller.h | 4 | ||||
-rw-r--r-- | ash/display/unified_mouse_warp_controller_unittest.cc | 175 | ||||
-rw-r--r-- | ash/test/display_manager_test_api.cc | 47 | ||||
-rw-r--r-- | ui/events/test/event_generator.cc | 28 | ||||
-rw-r--r-- | ui/events/test/event_generator.h | 5 | ||||
-rw-r--r-- | ui/events/test/events_test_utils_x11.cc | 22 | ||||
-rw-r--r-- | ui/events/test/events_test_utils_x11.h | 3 |
9 files changed, 244 insertions, 77 deletions
diff --git a/ash/display/display_util.cc b/ash/display/display_util.cc index 291b9a3..4c4bf7c 100644 --- a/ash/display/display_util.cc +++ b/ash/display/display_util.cc @@ -315,16 +315,19 @@ void MoveCursorTo(AshWindowTreeHost* ash_host, host->MoveCursorToHostLocation(point_in_host); if (update_last_location_now) { - gfx::Point new_point_in_screen = point_in_native; + gfx::Point new_point_in_screen; if (Shell::GetInstance()->display_manager()->IsInUnifiedMode()) { - // TODO(oshima): Do not use ConvertPointFromNativeScreen because - // the mirroring display has a transform that should not be applied here. - gfx::Point origin = host->GetBounds().origin(); - new_point_in_screen.Offset(-origin.x(), -origin.y()); + new_point_in_screen = point_in_host; + // First convert to the unified host. + host->ConvertPointFromHost(&new_point_in_screen); + // Then convert to the unified screen. + Shell::GetPrimaryRootWindow()->GetHost()->ConvertPointFromHost( + &new_point_in_screen); } else { + new_point_in_screen = point_in_native; host->ConvertPointFromNativeScreen(&new_point_in_screen); + ::wm::ConvertPointToScreen(host->window(), &new_point_in_screen); } - ::wm::ConvertPointToScreen(host->window(), &new_point_in_screen); aura::Env::GetInstance()->set_last_mouse_location(new_point_in_screen); } } diff --git a/ash/display/unified_mouse_warp_controller.cc b/ash/display/unified_mouse_warp_controller.cc index 7ee731485..086f97e 100644 --- a/ash/display/unified_mouse_warp_controller.cc +++ b/ash/display/unified_mouse_warp_controller.cc @@ -31,6 +31,7 @@ AshWindowTreeHost* GetMirroringAshWindowTreeHostForDisplayId(int64 display_id) { ->GetAshWindowTreeHostForDisplayId(display_id); } +#if defined(USE_OZONE) // Find a WindowTreeHost used for mirroring displays that contains // the |point_in_screen|. Returns nullptr if such WTH does not exist. aura::WindowTreeHost* FindMirroringWindowTreeHostFromScreenPoint( @@ -46,12 +47,13 @@ aura::WindowTreeHost* FindMirroringWindowTreeHostFromScreenPoint( return GetMirroringAshWindowTreeHostForDisplayId( mirroring_display_list[index].id())->AsWindowTreeHost(); } +#endif } // namespace UnifiedMouseWarpController::UnifiedMouseWarpController() : current_cursor_display_id_(gfx::Display::kInvalidDisplayID), - allow_non_native_event_(false) {} + update_location_for_test_(false) {} UnifiedMouseWarpController::~UnifiedMouseWarpController() { } @@ -89,19 +91,9 @@ bool UnifiedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) { } } - // A native event may not exist in unit test. Generate the native point - // from the screen point instead. - if (!event->HasNativeEvent()) { - if (!allow_non_native_event_) - return false; - gfx::Point point_in_native = point_in_unified_host; - aura::WindowTreeHost* host = - FindMirroringWindowTreeHostFromScreenPoint(point_in_unified_host); - DCHECK(host); - host->ConvertPointToNativeScreen(&point_in_native); - return WarpMouseCursorInNativeCoords(point_in_native, point_in_unified_host, - true); - } + // A native event may not exist in unit test. + if (!event->HasNativeEvent()) + return false; gfx::Point point_in_native = ui::EventSystemLocationFromNative(event->native_event()); @@ -119,7 +111,7 @@ bool UnifiedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) { #endif return WarpMouseCursorInNativeCoords(point_in_native, point_in_unified_host, - false); + update_location_for_test_); } void UnifiedMouseWarpController::SetEnabled(bool enabled) { diff --git a/ash/display/unified_mouse_warp_controller.h b/ash/display/unified_mouse_warp_controller.h index 696dd9c2..95fdbf6 100644 --- a/ash/display/unified_mouse_warp_controller.h +++ b/ash/display/unified_mouse_warp_controller.h @@ -48,14 +48,14 @@ class ASH_EXPORT UnifiedMouseWarpController : public MouseWarpController { const gfx::Point& point_in_screen, bool update_mouse_location_now); - void allow_non_native_event_for_test() { allow_non_native_event_ = true; } + void update_location_for_test() { update_location_for_test_ = true; } gfx::Rect first_edge_bounds_in_native_; gfx::Rect second_edge_bounds_in_native_; int64 current_cursor_display_id_; - bool allow_non_native_event_; + bool update_location_for_test_; DISALLOW_COPY_AND_ASSIGN(UnifiedMouseWarpController); }; diff --git a/ash/display/unified_mouse_warp_controller_unittest.cc b/ash/display/unified_mouse_warp_controller_unittest.cc index e176141..ca6e5c5 100644 --- a/ash/display/unified_mouse_warp_controller_unittest.cc +++ b/ash/display/unified_mouse_warp_controller_unittest.cc @@ -5,14 +5,19 @@ #include "ash/display/unified_mouse_warp_controller.h" #include "ash/display/display_manager.h" +#include "ash/display/display_util.h" +#include "ash/display/mirror_window_controller.h" #include "ash/display/mouse_cursor_event_filter.h" +#include "ash/host/ash_window_tree_host.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/display_manager_test_api.h" #include "ui/aura/env.h" +#include "ui/aura/window_tree_host.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/display.h" #include "ui/gfx/screen.h" +#include "ui/wm/core/coordinate_conversion.h" namespace ash { @@ -27,9 +32,71 @@ class UnifiedMouseWarpControllerTest : public test::AshTestBase { } protected: - bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) { - return test::DisplayManagerTestApi::TestIfMouseWarpsAt(GetEventGenerator(), - point_in_screen); + bool FindMirrroingDisplayIdContainingNativePoint( + const gfx::Point& point_in_native, + int64* display_id, + gfx::Point* point_in_mirroring_host, + gfx::Point* point_in_unified_host) { + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + for (auto display : display_manager->software_mirroring_display_list()) { + DisplayInfo info = display_manager->GetDisplayInfo(display.id()); + if (info.bounds_in_native().Contains(point_in_native)) { + *display_id = info.id(); + *point_in_unified_host = point_in_native; + const gfx::Point& origin = info.bounds_in_native().origin(); + // Convert to mirroring host. + point_in_unified_host->Offset(-origin.x(), -origin.y()); + *point_in_mirroring_host = *point_in_unified_host; + // Convert from mirroring host to unified host. + AshWindowTreeHost* ash_host = + Shell::GetInstance() + ->window_tree_host_manager() + ->mirror_window_controller() + ->GetAshWindowTreeHostForDisplayId(info.id()); + ash_host->AsWindowTreeHost()->ConvertPointFromHost( + point_in_unified_host); + return true; + } + } + return false; + } + + bool TestIfMouseWarpsAt(const gfx::Point& point_in_native) { + static_cast<UnifiedMouseWarpController*>( + Shell::GetInstance() + ->mouse_cursor_filter() + ->mouse_warp_controller_for_test()) + ->update_location_for_test(); + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + int64 orig_mirroring_display_id; + gfx::Point point_in_unified_host; + gfx::Point point_in_mirroring_host; + if (!FindMirrroingDisplayIdContainingNativePoint( + point_in_native, &orig_mirroring_display_id, + &point_in_mirroring_host, &point_in_unified_host)) { + return false; + } +#if defined(USE_OZONE) + // The location of the ozone's native event is relative to the host. + GetEventGenerator().MoveMouseToWithNative(point_in_unified_host, + point_in_mirroring_host); +#else + GetEventGenerator().MoveMouseToWithNative(point_in_unified_host, + point_in_native); +#endif + aura::Window* root = Shell::GetPrimaryRootWindow(); + gfx::Point new_location_in_unified_host = + aura::Env::GetInstance()->last_mouse_location(); + // Convert screen to the host. + root->GetHost()->ConvertPointToHost(&new_location_in_unified_host); + + int new_index = FindDisplayIndexContainingPoint( + display_manager->software_mirroring_display_list(), + new_location_in_unified_host); + if (new_index < 0) + return false; + return orig_mirroring_display_id != + display_manager->software_mirroring_display_list()[new_index].id(); } MouseCursorEventFilter* event_filter() { @@ -68,6 +135,22 @@ class UnifiedMouseWarpControllerTest : public test::AshTestBase { mouse_warp_controller()->second_edge_bounds_in_native_.ToString()); } + void NoWarpTestBody() { + // Touch the left edge of the first display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 10))); + // Touch the top edge of the first display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 0))); + // Touch the bottom edge of the first display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 499))); + + // Touch the right edge of the second display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(1099, 10))); + // Touch the top edge of the second display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(610, 0))); + // Touch the bottom edge of the second display. + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(610, 499))); + } + private: DISALLOW_COPY_AND_ASSIGN(UnifiedMouseWarpControllerTest); }; @@ -100,35 +183,85 @@ TEST_F(UnifiedMouseWarpControllerTest, BoundaryTest) { TEST_F(UnifiedMouseWarpControllerTest, WarpMouse) { if (!SupportsMultipleDisplays()) return; + UpdateDisplay("500x500,600+0-500x500"); + ASSERT_EQ(1, gfx::Screen::GetScreenFor(Shell::GetPrimaryRootWindow()) + ->GetNumDisplays()); + + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10))); + // Touch the right edge of the first display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 10))); + EXPECT_EQ("501,10", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the second display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(600, 10))); + EXPECT_EQ("498,10", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + { + SCOPED_TRACE("1x1 NO WARP"); + NoWarpTestBody(); + } - UpdateDisplay("500x500,500x500"); + // With 2X and 1X displays + UpdateDisplay("500x500*2,600+0-500x500"); ASSERT_EQ(1, gfx::Screen::GetScreenFor(Shell::GetPrimaryRootWindow()) ->GetNumDisplays()); - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 11))); + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10))); + // Touch the right edge of the first display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 10))); + EXPECT_EQ("250,5", // moved to 501 by 2px, devided by 2 (dsf). + aura::Env::GetInstance()->last_mouse_location().ToString()); + // Touch the left edge of the second display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(600, 10))); + EXPECT_EQ("249,5", // moved to 498 by 2px, divided by 2 (dsf). + aura::Env::GetInstance()->last_mouse_location().ToString()); + + { + SCOPED_TRACE("2x1 NO WARP"); + NoWarpTestBody(); + } + + // With 1X and 2X displays + UpdateDisplay("500x500,600+0-500x500*2"); + ASSERT_EQ(1, gfx::Screen::GetScreenFor(Shell::GetPrimaryRootWindow()) + ->GetNumDisplays()); + + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10))); // Touch the right edge of the first display. Pointer should warp. - EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11))); - EXPECT_EQ("501,11", // by 2px. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 10))); + EXPECT_EQ("501,10", // by 2px. aura::Env::GetInstance()->last_mouse_location().ToString()); // Touch the left edge of the second display. Pointer should warp. - EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 11))); - EXPECT_EQ("498,11", // by 2px. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(600, 10))); + EXPECT_EQ("498,10", // by 2px. aura::Env::GetInstance()->last_mouse_location().ToString()); + { + SCOPED_TRACE("1x2 NO WARP"); + NoWarpTestBody(); + } - // Touch the left edge of the first display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 11))); - // Touch the top edge of the first display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0))); - // Touch the bottom edge of the first display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 499))); - // Touch the right edge of the second display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(999, 11))); - // Touch the top edge of the second display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0))); - // Touch the bottom edge of the second display. - EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 499))); + // With two 2X displays + UpdateDisplay("500x500*2,600+0-500x500*2"); + ASSERT_EQ(1, gfx::Screen::GetScreenFor(Shell::GetPrimaryRootWindow()) + ->GetNumDisplays()); + + EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10))); + // Touch the right edge of the first display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 10))); + EXPECT_EQ("250,5", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the second display. Pointer should warp. + EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(600, 10))); + EXPECT_EQ("249,5", // moved to 498 by 2px, divided by 2 (dsf). + aura::Env::GetInstance()->last_mouse_location().ToString()); + { + SCOPED_TRACE("1x2 NO WARP"); + NoWarpTestBody(); + } } } // namespace aura diff --git a/ash/test/display_manager_test_api.cc b/ash/test/display_manager_test_api.cc index 73fb2d8..77d88ec 100644 --- a/ash/test/display_manager_test_api.cc +++ b/ash/test/display_manager_test_api.cc @@ -60,39 +60,20 @@ bool DisplayManagerTestApi::TestIfMouseWarpsAt( ui::test::EventGenerator& event_generator, const gfx::Point& point_in_screen) { aura::Window* context = Shell::GetAllRootWindows()[0]; - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - if (display_manager->IsInUnifiedMode()) { - static_cast<UnifiedMouseWarpController*>( - Shell::GetInstance() - ->mouse_cursor_filter() - ->mouse_warp_controller_for_test()) - ->allow_non_native_event_for_test(); - int orig_index = FindDisplayIndexContainingPoint( - display_manager->software_mirroring_display_list(), point_in_screen); - if (orig_index < 0) - return false; - event_generator.MoveMouseTo(point_in_screen); - - int new_index = FindDisplayIndexContainingPoint( - display_manager->software_mirroring_display_list(), - aura::Env::GetInstance()->last_mouse_location()); - if (new_index < 0) - return false; - return orig_index != new_index; - } else { - static_cast<ExtendedMouseWarpController*>( - Shell::GetInstance() - ->mouse_cursor_filter() - ->mouse_warp_controller_for_test()) - ->allow_non_native_event_for_test(); - gfx::Screen* screen = gfx::Screen::GetScreenFor(context); - gfx::Display original_display = - screen->GetDisplayNearestPoint(point_in_screen); - event_generator.MoveMouseTo(point_in_screen); - return original_display.id() != - screen->GetDisplayNearestPoint( - aura::Env::GetInstance()->last_mouse_location()).id(); - } + DCHECK(!Shell::GetInstance()->display_manager()->IsInUnifiedMode()); + static_cast<ExtendedMouseWarpController*>( + Shell::GetInstance() + ->mouse_cursor_filter() + ->mouse_warp_controller_for_test()) + ->allow_non_native_event_for_test(); + gfx::Screen* screen = gfx::Screen::GetScreenFor(context); + gfx::Display original_display = + screen->GetDisplayNearestPoint(point_in_screen); + event_generator.MoveMouseTo(point_in_screen); + return original_display.id() != + screen->GetDisplayNearestPoint( + aura::Env::GetInstance()->last_mouse_location()) + .id(); } DisplayManagerTestApi::DisplayManagerTestApi() diff --git a/ui/events/test/event_generator.cc b/ui/events/test/event_generator.cc index ae3bcb6..6e619d0 100644 --- a/ui/events/test/event_generator.cc +++ b/ui/events/test/event_generator.cc @@ -173,6 +173,34 @@ void EventGenerator::SendMouseExit() { Dispatch(&mouseev); } +void EventGenerator::MoveMouseToWithNative(const gfx::Point& point_in_host, + const gfx::Point& point_for_native) { +#if defined(USE_X11) + ui::ScopedXI2Event xevent; + xevent.InitMotionEvent(point_in_host, point_for_native, flags_); + static_cast<XEvent*>(xevent)->xmotion.time = Now().InMicroseconds(); + ui::MouseEvent mouseev(xevent); +#elif defined(USE_OZONE) + // Ozone uses the location in native event as a system location. + // Create a fake event with the point in host, which will be passed + // to the non native event, then update the native event with the native + // (root) one. + scoped_ptr<ui::MouseEvent> native_event(new ui::MouseEvent( + ui::ET_MOUSE_MOVED, point_in_host, point_in_host, Now(), flags_, 0)); + ui::MouseEvent mouseev(native_event.get()); + native_event->set_location(point_for_native); +#else + ui::MouseEvent mouseev(ui::ET_MOUSE_MOVED, point_in_host, point_for_native, + Now(), flags_, 0); + LOG(FATAL) + << "Generating a native motion event is not supported on this platform"; +#endif + Dispatch(&mouseev); + + current_location_ = point_in_host; + delegate()->ConvertPointFromHost(current_target_, ¤t_location_); +} + void EventGenerator::MoveMouseToInHost(const gfx::Point& point_in_host) { const ui::EventType event_type = (flags_ & ui::EF_LEFT_MOUSE_BUTTON) ? ui::ET_MOUSE_DRAGGED : ui::ET_MOUSE_MOVED; diff --git a/ui/events/test/event_generator.h b/ui/events/test/event_generator.h index c2b95ff..6f84e80 100644 --- a/ui/events/test/event_generator.h +++ b/ui/events/test/event_generator.h @@ -171,6 +171,11 @@ class EventGenerator { MoveMouseToInHost(gfx::Point(x, y)); } + // Generates a mouse move event at the point given in the host + // coordinates, with a native event with |point_for_natve|. + void MoveMouseToWithNative(const gfx::Point& point_in_host, + const gfx::Point& point_for_native); + // Generates events to move mouse to be the given |point| in screen // coordinates. void MoveMouseTo(const gfx::Point& point_in_screen, int count); diff --git a/ui/events/test/events_test_utils_x11.cc b/ui/events/test/events_test_utils_x11.cc index 921d755..cfb28b1 100644 --- a/ui/events/test/events_test_utils_x11.cc +++ b/ui/events/test/events_test_utils_x11.cc @@ -169,6 +169,28 @@ void ScopedXI2Event::InitKeyEvent(EventType type, event_->xkey.same_screen = 1; } +void ScopedXI2Event::InitMotionEvent(const gfx::Point& location, + const gfx::Point& root_location, + int flags) { + XDisplay* display = gfx::GetXDisplay(); + event_.reset(new XEvent); + memset(event_.get(), 0, sizeof(XEvent)); + event_->type = MotionNotify; + event_->xmotion.serial = 0; + event_->xmotion.send_event = 0; + event_->xmotion.display = display; + event_->xmotion.time = 0; + event_->xmotion.window = 0; + event_->xmotion.root = 0; + event_->xkey.subwindow = 0; + event_->xmotion.x = location.x(); + event_->xmotion.y = location.y(); + event_->xmotion.x_root = root_location.x(); + event_->xmotion.y_root = root_location.y(); + event_->xmotion.state = XEventState(flags); + event_->xmotion.same_screen = 1; +} + void ScopedXI2Event::InitGenericKeyEvent(int deviceid, int sourceid, EventType type, diff --git a/ui/events/test/events_test_utils_x11.h b/ui/events/test/events_test_utils_x11.h index d40e084..f312c83 100644 --- a/ui/events/test/events_test_utils_x11.h +++ b/ui/events/test/events_test_utils_x11.h @@ -41,6 +41,9 @@ class ScopedXI2Event { void InitKeyEvent(EventType type, KeyboardCode key_code, int flags); + void InitMotionEvent(const gfx::Point& location, + const gfx::Point& root_location, + int flags); // Initializes an Xinput2 key event. // |deviceid| is the master, and |sourceid| is the slave device. |