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