root_window_transformers_unittest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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#include "ash/display/root_window_transformers.h" 6 7#include "ash/display/display_info.h" 8#include "ash/display/display_manager.h" 9#include "ash/magnifier/magnification_controller.h" 10#include "ash/screen_util.h" 11#include "ash/shelf/shelf.h" 12#include "ash/shelf/shelf_widget.h" 13#include "ash/shell.h" 14#include "ash/test/ash_test_base.h" 15#include "ash/test/cursor_manager_test_api.h" 16#include "ash/test/mirror_window_test_api.h" 17#include "base/synchronization/waitable_event.h" 18#include "ui/aura/env.h" 19#include "ui/aura/root_window_transformer.h" 20#include "ui/aura/test/event_generator.h" 21#include "ui/aura/window_event_dispatcher.h" 22#include "ui/aura/window_tracker.h" 23#include "ui/events/event_handler.h" 24#include "ui/gfx/display.h" 25#include "ui/gfx/rect_conversions.h" 26#include "ui/gfx/screen.h" 27#include "ui/views/widget/widget.h" 28 29namespace ash { 30namespace { 31 32const char kDesktopBackgroundView[] = "DesktopBackgroundView"; 33 34class TestEventHandler : public ui::EventHandler { 35 public: 36 TestEventHandler() : target_root_(NULL), 37 touch_radius_x_(0.0), 38 touch_radius_y_(0.0), 39 scroll_x_offset_(0.0), 40 scroll_y_offset_(0.0), 41 scroll_x_offset_ordinal_(0.0), 42 scroll_y_offset_ordinal_(0.0) {} 43 virtual ~TestEventHandler() {} 44 45 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { 46 if (event->flags() & ui::EF_IS_SYNTHESIZED) 47 return; 48 aura::Window* target = static_cast<aura::Window*>(event->target()); 49 mouse_location_ = event->root_location(); 50 target_root_ = target->GetRootWindow(); 51 event->StopPropagation(); 52 } 53 54 virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { 55 aura::Window* target = static_cast<aura::Window*>(event->target()); 56 // Only record when the target is the background which covers 57 // entire root window. 58 if (target->name() != kDesktopBackgroundView) 59 return; 60 touch_radius_x_ = event->radius_x(); 61 touch_radius_y_ = event->radius_y(); 62 event->StopPropagation(); 63 } 64 65 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { 66 aura::Window* target = static_cast<aura::Window*>(event->target()); 67 // Only record when the target is the background which covers 68 // entire root window. 69 if (target->name() != kDesktopBackgroundView) 70 return; 71 72 if (event->type() == ui::ET_SCROLL) { 73 scroll_x_offset_ = event->x_offset(); 74 scroll_y_offset_ = event->y_offset(); 75 scroll_x_offset_ordinal_ = event->x_offset_ordinal(); 76 scroll_y_offset_ordinal_ = event->y_offset_ordinal(); 77 } 78 event->StopPropagation(); 79 } 80 81 std::string GetLocationAndReset() { 82 std::string result = mouse_location_.ToString(); 83 mouse_location_.SetPoint(0, 0); 84 target_root_ = NULL; 85 return result; 86 } 87 88 float touch_radius_x() const { return touch_radius_x_; } 89 float touch_radius_y() const { return touch_radius_y_; } 90 float scroll_x_offset() const { return scroll_x_offset_; } 91 float scroll_y_offset() const { return scroll_y_offset_; } 92 float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; } 93 float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; } 94 95 private: 96 gfx::Point mouse_location_; 97 aura::Window* target_root_; 98 99 float touch_radius_x_; 100 float touch_radius_y_; 101 float scroll_x_offset_; 102 float scroll_y_offset_; 103 float scroll_x_offset_ordinal_; 104 float scroll_y_offset_ordinal_; 105 106 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); 107}; 108 109gfx::Display::Rotation GetStoredRotation(int64 id) { 110 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation(); 111} 112 113float GetStoredUIScale(int64 id) { 114 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id). 115 GetEffectiveUIScale(); 116} 117 118} // namespace 119 120typedef test::AshTestBase RootWindowTransformersTest; 121 122#if defined(OS_WIN) 123// TODO(scottmg): RootWindow doesn't get resized on Windows 124// Ash. http://crbug.com/247916. 125#define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy 126#define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify 127#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords 128#else 129#define MAYBE_RotateAndMagnify RotateAndMagniy 130#define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify 131#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords 132#endif 133 134TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { 135 MagnificationController* magnifier = 136 Shell::GetInstance()->magnification_controller(); 137 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 138 139 TestEventHandler event_handler; 140 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 141 142 UpdateDisplay("120x200,300x400*2"); 143 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 144 int64 display2_id = ScreenUtil::GetSecondaryDisplay().id(); 145 146 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 147 aura::test::EventGenerator generator1(root_windows[0]); 148 aura::test::EventGenerator generator2(root_windows[1]); 149 150 magnifier->SetEnabled(true); 151 EXPECT_EQ(2.0f, magnifier->GetScale()); 152 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); 153 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); 154 EXPECT_EQ("120,0 150x200", 155 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 156 generator1.MoveMouseToInHost(40, 80); 157 EXPECT_EQ("50,90", event_handler.GetLocationAndReset()); 158 EXPECT_EQ("50,90", 159 aura::Env::GetInstance()->last_mouse_location().ToString()); 160 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); 161 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); 162 magnifier->SetEnabled(false); 163 164 display_manager->SetDisplayRotation(display1.id(), 165 gfx::Display::ROTATE_90); 166 // Move the cursor to the center of the first root window. 167 generator1.MoveMouseToInHost(59, 100); 168 169 magnifier->SetEnabled(true); 170 EXPECT_EQ(2.0f, magnifier->GetScale()); 171 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); 172 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); 173 EXPECT_EQ("200,0 150x200", 174 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 175 generator1.MoveMouseToInHost(39, 120); 176 EXPECT_EQ("110,70", event_handler.GetLocationAndReset()); 177 EXPECT_EQ("110,70", 178 aura::Env::GetInstance()->last_mouse_location().ToString()); 179 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); 180 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id)); 181 magnifier->SetEnabled(false); 182 183 DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); 184 display_manager->SetLayoutForCurrentDisplays(display_layout); 185 EXPECT_EQ("50,120 150x200", 186 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 187 188 display_manager->SetDisplayRotation(display2_id, 189 gfx::Display::ROTATE_270); 190 // Move the cursor to the center of the second root window. 191 generator2.MoveMouseToInHost(151, 199); 192 193 magnifier->SetEnabled(true); 194 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); 195 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); 196 EXPECT_EQ("50,120 200x150", 197 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 198 generator2.MoveMouseToInHost(172, 219); 199 EXPECT_EQ("95,80", event_handler.GetLocationAndReset()); 200 EXPECT_EQ("145,200", 201 aura::Env::GetInstance()->last_mouse_location().ToString()); 202 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); 203 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); 204 magnifier->SetEnabled(false); 205 206 display_manager->SetDisplayRotation(display1.id(), 207 gfx::Display::ROTATE_180); 208 // Move the cursor to the center of the first root window. 209 generator1.MoveMouseToInHost(59, 99); 210 211 magnifier->SetEnabled(true); 212 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); 213 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); 214 // Dislay must share at least 100, so the x's offset becomes 20. 215 EXPECT_EQ("20,200 200x150", 216 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 217 generator1.MoveMouseToInHost(39, 59); 218 EXPECT_EQ("70,120", event_handler.GetLocationAndReset()); 219 EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); 220 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); 221 magnifier->SetEnabled(false); 222 223 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 224} 225 226TEST_F(RootWindowTransformersTest, ScaleAndMagnify) { 227 if (!SupportsMultipleDisplays()) 228 return; 229 230 TestEventHandler event_handler; 231 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 232 233 UpdateDisplay("600x400*2@1.5,500x300"); 234 235 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 236 gfx::Display::SetInternalDisplayId(display1.id()); 237 gfx::Display display2 = ScreenUtil::GetSecondaryDisplay(); 238 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 239 MagnificationController* magnifier = 240 Shell::GetInstance()->magnification_controller(); 241 242 magnifier->SetEnabled(true); 243 EXPECT_EQ(2.0f, magnifier->GetScale()); 244 EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); 245 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); 246 EXPECT_EQ("450,0 500x300", display2.bounds().ToString()); 247 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 248 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); 249 250 aura::test::EventGenerator generator(root_windows[0]); 251 generator.MoveMouseToInHost(500, 200); 252 EXPECT_EQ("299,150", event_handler.GetLocationAndReset()); 253 magnifier->SetEnabled(false); 254 255 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 256 display_manager->SetDisplayUIScale(display1.id(), 1.25); 257 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 258 display2 = ScreenUtil::GetSecondaryDisplay(); 259 magnifier->SetEnabled(true); 260 EXPECT_EQ(2.0f, magnifier->GetScale()); 261 EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); 262 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); 263 EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); 264 EXPECT_EQ(1.25f, GetStoredUIScale(display1.id())); 265 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id())); 266 magnifier->SetEnabled(false); 267 268 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 269} 270 271TEST_F(RootWindowTransformersTest, MAYBE_TouchScaleAndMagnify) { 272 TestEventHandler event_handler; 273 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 274 275 UpdateDisplay("200x200*2"); 276 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); 277 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 278 aura::Window* root_window = root_windows[0]; 279 aura::test::EventGenerator generator(root_window); 280 MagnificationController* magnifier = 281 Shell::GetInstance()->magnification_controller(); 282 283 magnifier->SetEnabled(true); 284 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); 285 magnifier->SetScale(2.5f, false); 286 EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale()); 287 generator.PressMoveAndReleaseTouchTo(50, 50); 288 // Default test touches have radius_x/y = 1.0, with device scale 289 // factor = 2, the scaled radius_x/y should be 0.5. 290 EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x()); 291 EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y()); 292 293 generator.ScrollSequence(gfx::Point(0,0), 294 base::TimeDelta::FromMilliseconds(100), 295 10.0, 1.0, 5, 1); 296 297 // ordinal_offset is invariant to the device scale factor. 298 EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(), 299 event_handler.scroll_x_offset_ordinal()); 300 EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(), 301 event_handler.scroll_y_offset_ordinal()); 302 magnifier->SetEnabled(false); 303 304 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 305} 306 307TEST_F(RootWindowTransformersTest, MAYBE_ConvertHostToRootCoords) { 308 TestEventHandler event_handler; 309 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 310 MagnificationController* magnifier = 311 Shell::GetInstance()->magnification_controller(); 312 313 // Test 1 314 UpdateDisplay("600x400*2/r@1.5"); 315 316 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 317 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 318 EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); 319 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); 320 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 321 322 aura::test::EventGenerator generator(root_windows[0]); 323 generator.MoveMouseToInHost(300, 200); 324 magnifier->SetEnabled(true); 325 EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); 326 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); 327 328 generator.MoveMouseToInHost(300, 200); 329 EXPECT_EQ("150,224", event_handler.GetLocationAndReset()); 330 generator.MoveMouseToInHost(200, 300); 331 EXPECT_EQ("187,261", event_handler.GetLocationAndReset()); 332 generator.MoveMouseToInHost(100, 400); 333 EXPECT_EQ("237,299", event_handler.GetLocationAndReset()); 334 generator.MoveMouseToInHost(0, 0); 335 EXPECT_EQ("137,348", event_handler.GetLocationAndReset()); 336 337 magnifier->SetEnabled(false); 338 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); 339 340 // Test 2 341 UpdateDisplay("600x400*2/u@1.5"); 342 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 343 root_windows = Shell::GetAllRootWindows(); 344 EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); 345 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); 346 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 347 348 generator.MoveMouseToInHost(300, 200); 349 magnifier->SetEnabled(true); 350 EXPECT_EQ("224,149", event_handler.GetLocationAndReset()); 351 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); 352 353 generator.MoveMouseToInHost(300, 200); 354 EXPECT_EQ("224,148", event_handler.GetLocationAndReset()); 355 generator.MoveMouseToInHost(200, 300); 356 EXPECT_EQ("261,111", event_handler.GetLocationAndReset()); 357 generator.MoveMouseToInHost(100, 400); 358 EXPECT_EQ("299,60", event_handler.GetLocationAndReset()); 359 generator.MoveMouseToInHost(0, 0); 360 EXPECT_EQ("348,159", event_handler.GetLocationAndReset()); 361 362 magnifier->SetEnabled(false); 363 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); 364 365 // Test 3 366 UpdateDisplay("600x400*2/l@1.5"); 367 display1 = Shell::GetScreen()->GetPrimaryDisplay(); 368 root_windows = Shell::GetAllRootWindows(); 369 EXPECT_EQ("0,0 300x450", display1.bounds().ToString()); 370 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString()); 371 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id())); 372 373 generator.MoveMouseToInHost(300, 200); 374 magnifier->SetEnabled(true); 375 EXPECT_EQ("149,225", event_handler.GetLocationAndReset()); 376 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale()); 377 378 generator.MoveMouseToInHost(300, 200); 379 EXPECT_EQ("148,224", event_handler.GetLocationAndReset()); 380 generator.MoveMouseToInHost(200, 300); 381 EXPECT_EQ("111,187", event_handler.GetLocationAndReset()); 382 generator.MoveMouseToInHost(100, 400); 383 EXPECT_EQ("60,149", event_handler.GetLocationAndReset()); 384 generator.MoveMouseToInHost(0, 0); 385 EXPECT_EQ("159,99", event_handler.GetLocationAndReset()); 386 387 magnifier->SetEnabled(false); 388 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale()); 389 390 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 391} 392 393TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) { 394 if (!SupportsMultipleDisplays()) 395 return; 396 test::MirrorWindowTestApi test_api; 397 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 398 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 399 UpdateDisplay("400x200,500x500"); 400 scoped_ptr<aura::RootWindowTransformer> transformer( 401 test_api.CreateCurrentRootWindowTransformer()); 402 // Y margin must be margin is (500 - 500/400 * 200) / 2 = 125. 403 EXPECT_EQ("0,125,0,125", transformer->GetHostInsets().ToString()); 404 405 UpdateDisplay("200x400,500x500"); 406 // The aspect ratio is flipped, so X margin is now 125. 407 transformer = test_api.CreateCurrentRootWindowTransformer(); 408 EXPECT_EQ("125,0,125,0", transformer->GetHostInsets().ToString()); 409} 410 411} // namespace ash 412