diff options
Diffstat (limited to 'chromium/ash/display/root_window_transformers_unittest.cc')
-rw-r--r-- | chromium/ash/display/root_window_transformers_unittest.cc | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/chromium/ash/display/root_window_transformers_unittest.cc b/chromium/ash/display/root_window_transformers_unittest.cc new file mode 100644 index 00000000000..7919243ae22 --- /dev/null +++ b/chromium/ash/display/root_window_transformers_unittest.cc @@ -0,0 +1,414 @@ +// 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 "ash/display/root_window_transformers.h" + +#include "ash/display/display_info.h" +#include "ash/display/display_manager.h" +#include "ash/launcher/launcher.h" +#include "ash/magnifier/magnification_controller.h" +#include "ash/screen_ash.h" +#include "ash/shelf/shelf_widget.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/cursor_manager_test_api.h" +#include "ash/test/mirror_window_test_api.h" +#include "base/synchronization/waitable_event.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/aura/root_window_transformer.h" +#include "ui/aura/test/event_generator.h" +#include "ui/aura/window_tracker.h" +#include "ui/events/event_handler.h" +#include "ui/gfx/display.h" +#include "ui/gfx/rect_conversions.h" +#include "ui/gfx/screen.h" +#include "ui/views/widget/widget.h" + +namespace ash { +namespace internal { + +namespace { + +const char kDesktopBackgroundView[] = "DesktopBackgroundView"; + +class TestEventHandler : public ui::EventHandler { + public: + TestEventHandler() : target_root_(NULL), + touch_radius_x_(0.0), + touch_radius_y_(0.0), + scroll_x_offset_(0.0), + scroll_y_offset_(0.0), + scroll_x_offset_ordinal_(0.0), + scroll_y_offset_ordinal_(0.0) {} + virtual ~TestEventHandler() {} + + virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { + if (event->flags() & ui::EF_IS_SYNTHESIZED) + return; + aura::Window* target = static_cast<aura::Window*>(event->target()); + mouse_location_ = event->root_location(); + target_root_ = target->GetRootWindow(); + event->StopPropagation(); + } + + virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { + aura::Window* target = static_cast<aura::Window*>(event->target()); + // Only record when the target is the background which covers + // entire root window. + if (target->name() != kDesktopBackgroundView) + return; + touch_radius_x_ = event->radius_x(); + touch_radius_y_ = event->radius_y(); + event->StopPropagation(); + } + + virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { + aura::Window* target = static_cast<aura::Window*>(event->target()); + // Only record when the target is the background which covers + // entire root window. + if (target->name() != kDesktopBackgroundView) + return; + + if (event->type() == ui::ET_SCROLL) { + scroll_x_offset_ = event->x_offset(); + scroll_y_offset_ = event->y_offset(); + scroll_x_offset_ordinal_ = event->x_offset_ordinal(); + scroll_y_offset_ordinal_ = event->y_offset_ordinal(); + } + event->StopPropagation(); + } + + std::string GetLocationAndReset() { + std::string result = mouse_location_.ToString(); + mouse_location_.SetPoint(0, 0); + target_root_ = NULL; + return result; + } + + float touch_radius_x() const { return touch_radius_x_; } + float touch_radius_y() const { return touch_radius_y_; } + float scroll_x_offset() const { return scroll_x_offset_; } + float scroll_y_offset() const { return scroll_y_offset_; } + float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; } + float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; } + + private: + gfx::Point mouse_location_; + aura::Window* target_root_; + + float touch_radius_x_; + float touch_radius_y_; + float scroll_x_offset_; + float scroll_y_offset_; + float scroll_x_offset_ordinal_; + float scroll_y_offset_ordinal_; + + DISALLOW_COPY_AND_ASSIGN(TestEventHandler); +}; + +gfx::Display::Rotation GetStoredRotation(int64 id) { + return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation(); +} + +float GetStoredUIScale(int64 id) { + return Shell::GetInstance()->display_manager()->GetDisplayInfo(id). + GetEffectiveUIScale(); +} + +} // namespace + +typedef test::AshTestBase RootWindowTransformersTest; + +#if defined(OS_WIN) +// TODO(scottmg): RootWindow doesn't get resized on Windows +// Ash. http://crbug.com/247916. +#define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy +#define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify +#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords +#else +#define MAYBE_RotateAndMagnify RotateAndMagniy +#define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify +#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords +#endif + +TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { + MagnificationController* magnifier = + Shell::GetInstance()->magnification_controller(); + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + + TestEventHandler event_handler; + Shell::GetInstance()->AddPreTargetHandler(&event_handler); + + UpdateDisplay("120x200,300x400*2"); + gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); + int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::test::EventGenerator generator1(root_windows[0]); + aura::test::EventGenerator generator2(root_windows[1]); + + magnifier->SetEnabled(true); + EXPECT_EQ(2.0f, magnifier->GetScale()); + EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); + EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); + EXPECT_EQ("120,0 150x200", + ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + generator1.MoveMouseToInHost(40, 80); + EXPECT_EQ("50,90", event_handler.GetLocationAndReset()); + EXPECT_EQ("50,90", + aura::Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); + EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); + magnifier->SetEnabled(false); + + display_manager->SetDisplayRotation(display1.id(), + gfx::Display::ROTATE_90); + // Move the cursor to the center of the first root window. + generator1.MoveMouseToInHost(59, 100); + + magnifier->SetEnabled(true); + EXPECT_EQ(2.0f, magnifier->GetScale()); + EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); + EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); + EXPECT_EQ("200,0 150x200", + ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + generator1.MoveMouseToInHost(39, 120); + EXPECT_EQ("110,70", event_handler.GetLocationAndReset()); + EXPECT_EQ("110,70", + aura::Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); + EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); + magnifier->SetEnabled(false); + + DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); + display_manager->SetLayoutForCurrentDisplays(display_layout); + EXPECT_EQ("50,120 150x200", + ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + + display_manager->SetDisplayRotation(display2_id, + gfx::Display::ROTATE_270); + // Move the cursor to the center of the second root window. + generator2.MoveMouseToInHost(151, 199); + + magnifier->SetEnabled(true); + EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); + EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); + EXPECT_EQ("50,120 200x150", + ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + generator2.MoveMouseToInHost(172, 219); + EXPECT_EQ("95,80", event_handler.GetLocationAndReset()); + EXPECT_EQ("145,200", + aura::Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); + EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); + magnifier->SetEnabled(false); + + display_manager->SetDisplayRotation(display1.id(), + gfx::Display::ROTATE_180); + // Move the cursor to the center of the first root window. + generator1.MoveMouseToInHost(59, 99); + + magnifier->SetEnabled(true); + EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); + EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); + // Dislay must share at least 100, so the x's offset becomes 20. + EXPECT_EQ("20,200 200x150", + ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + generator1.MoveMouseToInHost(39, 59); + EXPECT_EQ("70,120", event_handler.GetLocationAndReset()); + EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); + EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); + magnifier->SetEnabled(false); + + Shell::GetInstance()->RemovePreTargetHandler(&event_handler); +} + +TEST_F(RootWindowTransformersTest, ScaleAndMagnify) { + if (!SupportsMultipleDisplays()) + return; + + TestEventHandler event_handler; + Shell::GetInstance()->AddPreTargetHandler(&event_handler); + + UpdateDisplay("600x400*2@1.5,500x300"); + + gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); + gfx::Display::SetInternalDisplayId(display1.id()); + gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + MagnificationController* magnifier = + Shell::GetInstance()->magnification_controller(); + + magnifier->SetEnabled(true); + EXPECT_EQ(2.0f, magnifier->GetScale()); + EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); + EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); + EXPECT_EQ("450,0 500x300", display2.bounds().ToString()); + EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); + EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); + + aura::test::EventGenerator generator(root_windows[0]); + generator.MoveMouseToInHost(500, 200); + EXPECT_EQ("299,150", event_handler.GetLocationAndReset()); + magnifier->SetEnabled(false); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + display_manager->SetDisplayUIScale(display1.id(), 1.25); + display1 = Shell::GetScreen()->GetPrimaryDisplay(); + display2 = ScreenAsh::GetSecondaryDisplay(); + magnifier->SetEnabled(true); + EXPECT_EQ(2.0f, magnifier->GetScale()); + EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); + EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); + EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); + EXPECT_EQ(1.25f, GetStoredUIScale(display1.id())); + EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); + magnifier->SetEnabled(false); + + Shell::GetInstance()->RemovePreTargetHandler(&event_handler); +} + +TEST_F(RootWindowTransformersTest, MAYBE_TouchScaleAndMagnify) { + TestEventHandler event_handler; + Shell::GetInstance()->AddPreTargetHandler(&event_handler); + + UpdateDisplay("200x200*2"); + gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::Window* root_window = root_windows[0]; + aura::test::EventGenerator generator(root_window); + MagnificationController* magnifier = + Shell::GetInstance()->magnification_controller(); + + magnifier->SetEnabled(true); + EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); + magnifier->SetScale(2.5f, false); + EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale()); + generator.PressMoveAndReleaseTouchTo(50, 50); + // Default test touches have radius_x/y = 1.0, with device scale + // factor = 2, the scaled radius_x/y should be 0.5. + EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x()); + EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y()); + + generator.ScrollSequence(gfx::Point(0,0), + base::TimeDelta::FromMilliseconds(100), + 10.0, 1.0, 5, 1); + + // ordinal_offset is invariant to the device scale factor. + EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(), + event_handler.scroll_x_offset_ordinal()); + EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(), + event_handler.scroll_y_offset_ordinal()); + magnifier->SetEnabled(false); + + Shell::GetInstance()->RemovePreTargetHandler(&event_handler); +} + +TEST_F(RootWindowTransformersTest, MAYBE_ConvertHostToRootCoords) { + TestEventHandler event_handler; + Shell::GetInstance()->AddPreTargetHandler(&event_handler); + MagnificationController* magnifier = + Shell::GetInstance()->magnification_controller(); + + // Test 1 + UpdateDisplay("600x400*2/r@1.5"); + + gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); + EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); + EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); + + aura::test::EventGenerator generator(root_windows[0]); + generator.MoveMouseToInHost(300, 200); + magnifier->SetEnabled(true); + EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); + EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); + + generator.MoveMouseToInHost(300, 200); + EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(200, 300); + EXPECT_EQ("187,261", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(100, 400); + EXPECT_EQ("237,299", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(0, 0); + EXPECT_EQ("137,348", event_handler.GetLocationAndReset()); + + magnifier->SetEnabled(false); + EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); + + // Test 2 + UpdateDisplay("600x400*2/u@1.5"); + display1 = Shell::GetScreen()->GetPrimaryDisplay(); + root_windows = Shell::GetAllRootWindows(); + EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); + EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); + EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); + + generator.MoveMouseToInHost(300, 200); + magnifier->SetEnabled(true); + EXPECT_EQ("224,149", event_handler.GetLocationAndReset()); + EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); + + generator.MoveMouseToInHost(300, 200); + EXPECT_EQ("224,148", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(200, 300); + EXPECT_EQ("261,111", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(100, 400); + EXPECT_EQ("299,60", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(0, 0); + EXPECT_EQ("348,159", event_handler.GetLocationAndReset()); + + magnifier->SetEnabled(false); + EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); + + // Test 3 + UpdateDisplay("600x400*2/l@1.5"); + display1 = Shell::GetScreen()->GetPrimaryDisplay(); + root_windows = Shell::GetAllRootWindows(); + EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); + EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); + EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); + + generator.MoveMouseToInHost(300, 200); + magnifier->SetEnabled(true); + EXPECT_EQ("149,225", event_handler.GetLocationAndReset()); + EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); + + generator.MoveMouseToInHost(300, 200); + EXPECT_EQ("148,224", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(200, 300); + EXPECT_EQ("111,187", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(100, 400); + EXPECT_EQ("60,149", event_handler.GetLocationAndReset()); + generator.MoveMouseToInHost(0, 0); + EXPECT_EQ("159,99", event_handler.GetLocationAndReset()); + + magnifier->SetEnabled(false); + EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); + + Shell::GetInstance()->RemovePreTargetHandler(&event_handler); +} + +TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) { + if (!SupportsMultipleDisplays()) + return; + test::MirrorWindowTestApi test_api; + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); + UpdateDisplay("400x200,500x500"); + scoped_ptr<aura::RootWindowTransformer> transformer( + test_api.CreateCurrentRootWindowTransformer()); + // Y margin must be margin is (500 - 500/400 * 200) / 2 = 125. + EXPECT_EQ("0,125,0,125", transformer->GetHostInsets().ToString()); + + UpdateDisplay("200x400,500x500"); + // The aspect ratio is flipped, so X margin is now 125. + transformer = test_api.CreateCurrentRootWindowTransformer(); + EXPECT_EQ("125,0,125,0", transformer->GetHostInsets().ToString()); +} + +} // namespace test +} // namespace ash |