mirror_window_controller_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright (c) 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/mirror_window_controller.h" 6 7#include "ash/ash_switches.h" 8#include "ash/display/display_manager.h" 9#include "ash/shell.h" 10#include "ash/test/ash_test_base.h" 11#include "ash/test/display_manager_test_api.h" 12#include "ash/test/mirror_window_test_api.h" 13#include "base/command_line.h" 14#include "base/strings/stringprintf.h" 15#include "ui/aura/root_window.h" 16#include "ui/aura/test/event_generator.h" 17#include "ui/aura/test/test_window_delegate.h" 18#include "ui/aura/test/test_windows.h" 19#include "ui/aura/window.h" 20#include "ui/base/hit_test.h" 21 22namespace ash { 23namespace internal { 24 25namespace { 26DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { 27 DisplayInfo info(id, base::StringPrintf("x-%d", static_cast<int>(id)), false); 28 info.SetBounds(bounds); 29 return info; 30} 31 32class MirrorOnBootTest : public test::AshTestBase { 33 public: 34 MirrorOnBootTest() {} 35 virtual ~MirrorOnBootTest() {} 36 37 virtual void SetUp() OVERRIDE { 38 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 39 switches::kAshHostWindowBounds, "1+1-300x300,1+301-300x300"); 40 CommandLine::ForCurrentProcess()->AppendSwitch( 41 switches::kAshEnableSoftwareMirroring); 42 test::AshTestBase::SetUp(); 43 } 44 virtual void TearDown() OVERRIDE { 45 test::AshTestBase::TearDown(); 46 } 47 48 private: 49 DISALLOW_COPY_AND_ASSIGN(MirrorOnBootTest); 50}; 51 52} 53 54typedef test::AshTestBase MirrorWindowControllerTest; 55 56#if defined(OS_WIN) 57// Software mirroring does not work on win. 58#define MAYBE_MirrorCursorBasic DISABLED_MirrorCursorBasic 59#define MAYBE_MirrorCursorLocations DISABLED_MirrorCursorLocations 60#define MAYBE_MirrorCursorRotate DISABLED_MirrorCursorRotate 61#define MAYBE_DockMode DISABLED_DockMode 62#define MAYBE_MirrorOnBoot DISABLED_MirrorOnBoot 63#else 64#define MAYBE_MirrorCursorBasic MirrorCursorBasic 65#define MAYBE_MirrorCursorLocations MirrorCursorLocations 66#define MAYBE_MirrorCursorRotate MirrorCursorRotate 67#define MAYBE_DockMode DockMode 68#define MAYBE_MirrorOnBoot MirrorOnBoot 69#endif 70 71TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorBasic) { 72 test::MirrorWindowTestApi test_api; 73 aura::test::TestWindowDelegate test_window_delegate; 74 test_window_delegate.set_window_component(HTTOP); 75 76 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 77 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 78 UpdateDisplay("400x400,400x400"); 79 aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); 80 scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( 81 &test_window_delegate, 82 0, 83 gfx::Rect(50, 50, 100, 100), 84 root)); 85 window->Show(); 86 window->SetName("foo"); 87 88 EXPECT_TRUE(test_api.GetCursorWindow()); 89 EXPECT_EQ("50,50 100x100", window->bounds().ToString()); 90 91 aura::test::EventGenerator generator(root); 92 generator.MoveMouseTo(10, 10); 93 94 // Test if cursor movement is propertly reflected in mirror window. 95 gfx::Point hot_point = test_api.GetCursorHotPoint(); 96 gfx::Point cursor_window_origin = 97 test_api.GetCursorWindow()->bounds().origin(); 98 EXPECT_EQ("4,4", hot_point.ToString()); 99 EXPECT_EQ(10 - hot_point.x(), cursor_window_origin.x()); 100 EXPECT_EQ(10 - hot_point.y(), cursor_window_origin.y()); 101 EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType()); 102 EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible()); 103 104 // Test if cursor type change is propertly reflected in mirror window. 105 generator.MoveMouseTo(100, 100); 106 hot_point = test_api.GetCursorHotPoint(); 107 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 108 EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); 109 EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); 110 EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); 111 112 // Test if visibility change is propertly reflected in mirror window. 113 // A key event hides cursor. 114 generator.PressKey(ui::VKEY_A, 0); 115 generator.ReleaseKey(ui::VKEY_A, 0); 116 EXPECT_FALSE(test_api.GetCursorWindow()->IsVisible()); 117 118 // Mouse event makes it visible again. 119 generator.MoveMouseTo(300, 300); 120 hot_point = test_api.GetCursorHotPoint(); 121 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 122 EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); 123 EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); 124 EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType()); 125 EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible()); 126} 127 128TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorRotate) { 129 test::MirrorWindowTestApi test_api; 130 aura::test::TestWindowDelegate test_window_delegate; 131 test_window_delegate.set_window_component(HTTOP); 132 133 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 134 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 135 UpdateDisplay("400x400,400x400"); 136 aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); 137 scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( 138 &test_window_delegate, 139 0, 140 gfx::Rect(50, 50, 100, 100), 141 root)); 142 window->Show(); 143 window->SetName("foo"); 144 145 EXPECT_TRUE(test_api.GetCursorWindow()); 146 EXPECT_EQ("50,50 100x100", window->bounds().ToString()); 147 148 aura::test::EventGenerator generator(root); 149 generator.MoveMouseToInHost(100, 100); 150 151 // Test if cursor movement is propertly reflected in mirror window. 152 gfx::Point hot_point = test_api.GetCursorHotPoint(); 153 gfx::Point cursor_window_origin = 154 test_api.GetCursorWindow()->bounds().origin(); 155 EXPECT_EQ("11,12", hot_point.ToString()); 156 EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); 157 EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); 158 EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); 159 160 UpdateDisplay("400x400/r,400x400"); // 90 degrees. 161 generator.MoveMouseToInHost(300, 100); 162 hot_point = test_api.GetCursorHotPoint(); 163 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 164 EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); 165 // The size of cursor image is 25x25, so the rotated hot point must 166 // be (25-12, 11). 167 EXPECT_EQ("13,11", hot_point.ToString()); 168 EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); 169 EXPECT_EQ(100 - hot_point.y(), cursor_window_origin.y()); 170 171 UpdateDisplay("400x400/u,400x400"); // 180 degrees. 172 generator.MoveMouseToInHost(300, 300); 173 hot_point = test_api.GetCursorHotPoint(); 174 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 175 EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); 176 // Rotated hot point must be (25-11, 25-12). 177 EXPECT_EQ("14,13", hot_point.ToString()); 178 EXPECT_EQ(300 - hot_point.x(), cursor_window_origin.x()); 179 EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); 180 181 UpdateDisplay("400x400/l,400x400"); // 270 degrees. 182 generator.MoveMouseToInHost(100, 300); 183 hot_point = test_api.GetCursorHotPoint(); 184 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 185 EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType()); 186 // Rotated hot point must be (12, 25-11). 187 EXPECT_EQ("12,14", hot_point.ToString()); 188 EXPECT_EQ(100 - hot_point.x(), cursor_window_origin.x()); 189 EXPECT_EQ(300 - hot_point.y(), cursor_window_origin.y()); 190} 191 192// Make sure that the mirror cursor's location is same as 193// the source display's host location in the mirror root window's 194// coordinates. 195TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorLocations) { 196 test::MirrorWindowTestApi test_api; 197 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 198 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 199 200 // Test with device scale factor. 201 UpdateDisplay("400x600*2,400x600"); 202 203 aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow(); 204 aura::test::EventGenerator generator(root); 205 generator.MoveMouseToInHost(10, 20); 206 207 gfx::Point hot_point = test_api.GetCursorHotPoint(); 208 EXPECT_EQ("8,9", hot_point.ToString()); 209 gfx::Point cursor_window_origin = 210 test_api.GetCursorWindow()->bounds().origin(); 211 EXPECT_EQ(10 - hot_point.x(), cursor_window_origin.x()); 212 EXPECT_EQ(20 - hot_point.y(), cursor_window_origin.y()); 213 214 // Test with ui scale 215 UpdateDisplay("400x600*0.5,400x600"); 216 generator.MoveMouseToInHost(20, 30); 217 218 hot_point = test_api.GetCursorHotPoint(); 219 EXPECT_EQ("4,4", hot_point.ToString()); 220 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 221 EXPECT_EQ(20 - hot_point.x(), cursor_window_origin.x()); 222 EXPECT_EQ(30 - hot_point.y(), cursor_window_origin.y()); 223 224 // Test with rotation 225 UpdateDisplay("400x600/r,400x600"); 226 generator.MoveMouseToInHost(30, 40); 227 228 hot_point = test_api.GetCursorHotPoint(); 229 EXPECT_EQ("21,4", hot_point.ToString()); 230 cursor_window_origin = test_api.GetCursorWindow()->bounds().origin(); 231 EXPECT_EQ(30 - hot_point.x(), cursor_window_origin.x()); 232 EXPECT_EQ(40 - hot_point.y(), cursor_window_origin.y()); 233} 234 235// Make sure that the compositor based mirroring can switch 236// from/to dock mode. 237TEST_F(MirrorWindowControllerTest, MAYBE_DockMode) { 238 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 239 const int64 internal_id = 1; 240 const int64 external_id = 2; 241 242 const DisplayInfo internal_display_info = 243 CreateDisplayInfo(internal_id, gfx::Rect(0, 0, 500, 500)); 244 const DisplayInfo external_display_info = 245 CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); 246 std::vector<DisplayInfo> display_info_list; 247 248 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 249 250 // software mirroring. 251 display_info_list.push_back(internal_display_info); 252 display_info_list.push_back(external_display_info); 253 display_manager->OnNativeDisplaysChanged(display_info_list); 254 const int64 internal_display_id = 255 test::DisplayManagerTestApi(display_manager). 256 SetFirstDisplayAsInternalDisplay(); 257 EXPECT_EQ(internal_id, internal_display_id); 258 259 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 260 EXPECT_TRUE(display_manager->IsMirrored()); 261 EXPECT_EQ(external_id, display_manager->mirrored_display_id()); 262 263 // dock mode. 264 display_info_list.clear(); 265 display_info_list.push_back(external_display_info); 266 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 267 display_manager->OnNativeDisplaysChanged(display_info_list); 268 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 269 EXPECT_FALSE(display_manager->IsMirrored()); 270 271 // back to software mirroring. 272 display_info_list.clear(); 273 display_info_list.push_back(internal_display_info); 274 display_info_list.push_back(external_display_info); 275 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 276 display_manager->OnNativeDisplaysChanged(display_info_list); 277 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 278 EXPECT_TRUE(display_manager->IsMirrored()); 279 EXPECT_EQ(external_id, display_manager->mirrored_display_id()); 280} 281 282TEST_F(MirrorOnBootTest, MAYBE_MirrorOnBoot) { 283 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 284 EXPECT_TRUE(display_manager->IsMirrored()); 285 RunAllPendingInMessageLoop(); 286 test::MirrorWindowTestApi test_api; 287 EXPECT_TRUE(test_api.GetRootWindow()); 288} 289 290} // namsspace internal 291} // namespace ash 292