Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / ash / display / display_manager_unittest.cc
blob822452edf1c95f90968c12a5af11ac762866e149
1 // Copyright (c) 2012 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.
5 #include "ash/display/display_manager.h"
7 #include "ash/accelerators/accelerator_commands.h"
8 #include "ash/ash_switches.h"
9 #include "ash/display/display_info.h"
10 #include "ash/display/display_layout_store.h"
11 #include "ash/display/display_util.h"
12 #include "ash/display/mirror_window_controller.h"
13 #include "ash/display/window_tree_host_manager.h"
14 #include "ash/screen_util.h"
15 #include "ash/shell.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/test/display_manager_test_api.h"
18 #include "ash/test/mirror_window_test_api.h"
19 #include "ash/wm/window_state.h"
20 #include "base/command_line.h"
21 #include "base/format_macros.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/stringprintf.h"
24 #include "ui/aura/client/aura_constants.h"
25 #include "ui/aura/env.h"
26 #include "ui/aura/window_observer.h"
27 #include "ui/aura/window_tree_host.h"
28 #include "ui/events/test/event_generator.h"
29 #include "ui/gfx/display.h"
30 #include "ui/gfx/display_observer.h"
31 #include "ui/gfx/font_render_params.h"
32 #include "ui/gfx/screen.h"
33 #include "ui/gfx/screen_type_delegate.h"
35 namespace ash {
37 using std::vector;
38 using std::string;
40 using base::StringPrintf;
42 namespace {
44 std::string ToDisplayName(int64 id) {
45 return "x-" + base::Int64ToString(id);
48 } // namespace
50 class DisplayManagerTest : public test::AshTestBase,
51 public gfx::DisplayObserver,
52 public aura::WindowObserver {
53 public:
54 DisplayManagerTest()
55 : removed_count_(0U),
56 root_window_destroyed_(false),
57 changed_metrics_(0U) {
59 ~DisplayManagerTest() override {}
61 void SetUp() override {
62 AshTestBase::SetUp();
63 Shell::GetScreen()->AddObserver(this);
64 Shell::GetPrimaryRootWindow()->AddObserver(this);
66 void TearDown() override {
67 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
68 Shell::GetScreen()->RemoveObserver(this);
69 AshTestBase::TearDown();
72 DisplayManager* display_manager() {
73 return Shell::GetInstance()->display_manager();
75 const vector<gfx::Display>& changed() const { return changed_; }
76 const vector<gfx::Display>& added() const { return added_; }
77 uint32_t changed_metrics() const { return changed_metrics_; }
79 string GetCountSummary() const {
80 return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS,
81 changed_.size(), added_.size(), removed_count_);
84 void reset() {
85 changed_.clear();
86 added_.clear();
87 removed_count_ = 0U;
88 changed_metrics_ = 0U;
89 root_window_destroyed_ = false;
92 bool root_window_destroyed() const {
93 return root_window_destroyed_;
96 const DisplayInfo& GetDisplayInfo(const gfx::Display& display) {
97 return display_manager()->GetDisplayInfo(display.id());
100 const DisplayInfo& GetDisplayInfoAt(int index) {
101 return GetDisplayInfo(display_manager()->GetDisplayAt(index));
104 const gfx::Display& GetDisplayForId(int64 id) {
105 return display_manager()->GetDisplayForId(id);
108 const DisplayInfo& GetDisplayInfoForId(int64 id) {
109 return GetDisplayInfo(display_manager()->GetDisplayForId(id));
112 // aura::DisplayObserver overrides:
113 void OnDisplayMetricsChanged(const gfx::Display& display,
114 uint32_t changed_metrics) override {
115 changed_.push_back(display);
116 changed_metrics_ |= changed_metrics;
118 void OnDisplayAdded(const gfx::Display& new_display) override {
119 added_.push_back(new_display);
121 void OnDisplayRemoved(const gfx::Display& old_display) override {
122 ++removed_count_;
125 // aura::WindowObserver overrides:
126 void OnWindowDestroying(aura::Window* window) override {
127 ASSERT_EQ(Shell::GetPrimaryRootWindow(), window);
128 root_window_destroyed_ = true;
131 private:
132 vector<gfx::Display> changed_;
133 vector<gfx::Display> added_;
134 size_t removed_count_;
135 bool root_window_destroyed_;
136 uint32_t changed_metrics_;
138 DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest);
141 TEST_F(DisplayManagerTest, UpdateDisplayTest) {
142 if (!SupportsMultipleDisplays())
143 return;
145 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
147 // Update primary and add seconary.
148 UpdateDisplay("100+0-500x500,0+501-400x400");
149 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
150 EXPECT_EQ("0,0 500x500",
151 display_manager()->GetDisplayAt(0).bounds().ToString());
153 EXPECT_EQ("1 1 0", GetCountSummary());
154 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
155 EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
156 EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString());
157 // Secondary display is on right.
158 EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString());
159 EXPECT_EQ("0,501 400x400",
160 GetDisplayInfo(added()[0]).bounds_in_native().ToString());
161 reset();
163 // Delete secondary.
164 UpdateDisplay("100+0-500x500");
165 EXPECT_EQ("0 0 1", GetCountSummary());
166 reset();
168 // Change primary.
169 UpdateDisplay("1+1-1000x600");
170 EXPECT_EQ("1 0 0", GetCountSummary());
171 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
172 EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString());
173 reset();
175 // Add secondary.
176 UpdateDisplay("1+1-1000x600,1002+0-600x400");
177 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
178 EXPECT_EQ("0 1 0", GetCountSummary());
179 EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
180 // Secondary display is on right.
181 EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString());
182 EXPECT_EQ("1002,0 600x400",
183 GetDisplayInfo(added()[0]).bounds_in_native().ToString());
184 reset();
186 // Secondary removed, primary changed.
187 UpdateDisplay("1+1-800x300");
188 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
189 EXPECT_EQ("1 0 1", GetCountSummary());
190 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
191 EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString());
192 reset();
194 // # of display can go to zero when screen is off.
195 const vector<DisplayInfo> empty;
196 display_manager()->OnNativeDisplaysChanged(empty);
197 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
198 EXPECT_EQ("0 0 0", GetCountSummary());
199 EXPECT_FALSE(root_window_destroyed());
200 // Display configuration stays the same
201 EXPECT_EQ("0,0 800x300",
202 display_manager()->GetDisplayAt(0).bounds().ToString());
203 reset();
205 // Connect to display again
206 UpdateDisplay("100+100-500x400");
207 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
208 EXPECT_EQ("1 0 0", GetCountSummary());
209 EXPECT_FALSE(root_window_destroyed());
210 EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString());
211 EXPECT_EQ("100,100 500x400",
212 GetDisplayInfo(changed()[0]).bounds_in_native().ToString());
213 reset();
215 // Go back to zero and wake up with multiple displays.
216 display_manager()->OnNativeDisplaysChanged(empty);
217 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
218 EXPECT_FALSE(root_window_destroyed());
219 reset();
221 // Add secondary.
222 UpdateDisplay("0+0-1000x600,1000+1000-600x400");
223 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
224 EXPECT_EQ("0,0 1000x600",
225 display_manager()->GetDisplayAt(0).bounds().ToString());
226 // Secondary display is on right.
227 EXPECT_EQ("1000,0 600x400",
228 display_manager()->GetDisplayAt(1).bounds().ToString());
229 EXPECT_EQ("1000,1000 600x400",
230 GetDisplayInfoAt(1).bounds_in_native().ToString());
231 reset();
233 // Changing primary will update secondary as well.
234 UpdateDisplay("0+0-800x600,1000+1000-600x400");
235 EXPECT_EQ("2 0 0", GetCountSummary());
236 reset();
237 EXPECT_EQ("0,0 800x600",
238 display_manager()->GetDisplayAt(0).bounds().ToString());
239 EXPECT_EQ("800,0 600x400",
240 display_manager()->GetDisplayAt(1).bounds().ToString());
243 TEST_F(DisplayManagerTest, ScaleOnlyChange) {
244 if (!SupportsMultipleDisplays())
245 return;
246 display_manager()->ToggleDisplayScaleFactor();
247 EXPECT_TRUE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
248 EXPECT_TRUE(changed_metrics() &
249 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
252 // Test in emulation mode (use_fullscreen_host_window=false)
253 TEST_F(DisplayManagerTest, EmulatorTest) {
254 if (!SupportsMultipleDisplays())
255 return;
257 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
259 display_manager()->AddRemoveDisplay();
260 // Update primary and add seconary.
261 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
262 EXPECT_EQ("0 1 0", GetCountSummary());
263 reset();
265 display_manager()->AddRemoveDisplay();
266 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
267 EXPECT_EQ("0 0 1", GetCountSummary());
268 reset();
270 display_manager()->AddRemoveDisplay();
271 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
272 EXPECT_EQ("0 1 0", GetCountSummary());
273 reset();
276 // Tests support for 3 displays.
277 TEST_F(DisplayManagerTest, UpdateThreeDisplaysTest) {
278 if (!SupportsMultipleDisplays())
279 return;
281 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
283 // Test with three displays.
284 UpdateDisplay("0+0-640x480,640+0-320x200,960+0-400x300");
285 EXPECT_EQ(3U, display_manager()->GetNumDisplays());
286 EXPECT_EQ("0,0 640x480",
287 display_manager()->GetDisplayAt(0).bounds().ToString());
288 EXPECT_EQ("640,0 320x200",
289 display_manager()->GetDisplayAt(1).bounds().ToString());
290 EXPECT_EQ("960,0 400x300",
291 display_manager()->GetDisplayAt(2).bounds().ToString());
293 EXPECT_EQ("1 2 0", GetCountSummary());
294 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
295 EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
296 EXPECT_EQ(display_manager()->GetDisplayAt(2).id(), added()[1].id());
297 EXPECT_EQ("0,0 640x480", changed()[0].bounds().ToString());
298 // Secondary and terniary displays are on right.
299 EXPECT_EQ("640,0 320x200", added()[0].bounds().ToString());
300 EXPECT_EQ("640,0 320x200",
301 GetDisplayInfo(added()[0]).bounds_in_native().ToString());
302 EXPECT_EQ("960,0 400x300", added()[1].bounds().ToString());
303 EXPECT_EQ("960,0 400x300",
304 GetDisplayInfo(added()[1]).bounds_in_native().ToString());
305 reset();
308 TEST_F(DisplayManagerTest, OverscanInsetsTest) {
309 if (!SupportsMultipleDisplays())
310 return;
312 UpdateDisplay("0+0-500x500,0+501-400x400");
313 reset();
314 ASSERT_EQ(2u, display_manager()->GetNumDisplays());
315 const DisplayInfo& display_info1 = GetDisplayInfoAt(0);
316 const DisplayInfo& display_info2 = GetDisplayInfoAt(1);
317 display_manager()->SetOverscanInsets(
318 display_info2.id(), gfx::Insets(13, 12, 11, 10));
320 std::vector<gfx::Display> changed_displays = changed();
321 EXPECT_EQ(1u, changed_displays.size());
322 EXPECT_EQ(display_info2.id(), changed_displays[0].id());
323 EXPECT_EQ("0,0 500x500",
324 GetDisplayInfoAt(0).bounds_in_native().ToString());
325 DisplayInfo updated_display_info2 = GetDisplayInfoAt(1);
326 EXPECT_EQ("0,501 400x400",
327 updated_display_info2.bounds_in_native().ToString());
328 EXPECT_EQ("378x376",
329 updated_display_info2.size_in_pixel().ToString());
330 EXPECT_EQ("13,12,11,10",
331 updated_display_info2.overscan_insets_in_dip().ToString());
332 EXPECT_EQ("500,0 378x376",
333 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
335 // Make sure that SetOverscanInsets() is idempotent.
336 display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets());
337 display_manager()->SetOverscanInsets(
338 display_info2.id(), gfx::Insets(13, 12, 11, 10));
339 EXPECT_EQ("0,0 500x500",
340 GetDisplayInfoAt(0).bounds_in_native().ToString());
341 updated_display_info2 = GetDisplayInfoAt(1);
342 EXPECT_EQ("0,501 400x400",
343 updated_display_info2.bounds_in_native().ToString());
344 EXPECT_EQ("378x376",
345 updated_display_info2.size_in_pixel().ToString());
346 EXPECT_EQ("13,12,11,10",
347 updated_display_info2.overscan_insets_in_dip().ToString());
349 display_manager()->SetOverscanInsets(
350 display_info2.id(), gfx::Insets(10, 11, 12, 13));
351 EXPECT_EQ("0,0 500x500",
352 GetDisplayInfoAt(0).bounds_in_native().ToString());
353 EXPECT_EQ("376x378",
354 GetDisplayInfoAt(1).size_in_pixel().ToString());
355 EXPECT_EQ("10,11,12,13",
356 GetDisplayInfoAt(1).overscan_insets_in_dip().ToString());
358 // Recreate a new 2nd display. It won't apply the overscan inset because the
359 // new display has a different ID.
360 UpdateDisplay("0+0-500x500");
361 UpdateDisplay("0+0-500x500,0+501-400x400");
362 EXPECT_EQ("0,0 500x500",
363 GetDisplayInfoAt(0).bounds_in_native().ToString());
364 EXPECT_EQ("0,501 400x400",
365 GetDisplayInfoAt(1).bounds_in_native().ToString());
367 // Recreate the displays with the same ID. It should apply the overscan
368 // inset.
369 UpdateDisplay("0+0-500x500");
370 std::vector<DisplayInfo> display_info_list;
371 display_info_list.push_back(display_info1);
372 display_info_list.push_back(display_info2);
373 display_manager()->OnNativeDisplaysChanged(display_info_list);
374 EXPECT_EQ("1,1 500x500",
375 GetDisplayInfoAt(0).bounds_in_native().ToString());
376 updated_display_info2 = GetDisplayInfoAt(1);
377 EXPECT_EQ("376x378",
378 updated_display_info2.size_in_pixel().ToString());
379 EXPECT_EQ("10,11,12,13",
380 updated_display_info2.overscan_insets_in_dip().ToString());
382 // HiDPI but overscan display. The specified insets size should be doubled.
383 UpdateDisplay("0+0-500x500,0+501-400x400*2");
384 display_manager()->SetOverscanInsets(
385 display_manager()->GetDisplayAt(1).id(), gfx::Insets(4, 5, 6, 7));
386 EXPECT_EQ("0,0 500x500",
387 GetDisplayInfoAt(0).bounds_in_native().ToString());
388 updated_display_info2 = GetDisplayInfoAt(1);
389 EXPECT_EQ("0,501 400x400",
390 updated_display_info2.bounds_in_native().ToString());
391 EXPECT_EQ("376x380",
392 updated_display_info2.size_in_pixel().ToString());
393 EXPECT_EQ("4,5,6,7",
394 updated_display_info2.overscan_insets_in_dip().ToString());
395 EXPECT_EQ("8,10,12,14",
396 updated_display_info2.GetOverscanInsetsInPixel().ToString());
398 // Make sure switching primary display applies the overscan offset only once.
399 ash::Shell::GetInstance()->window_tree_host_manager()->SetPrimaryDisplay(
400 ScreenUtil::GetSecondaryDisplay());
401 EXPECT_EQ("-500,0 500x500",
402 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
403 EXPECT_EQ("0,0 500x500",
404 GetDisplayInfo(ScreenUtil::GetSecondaryDisplay()).
405 bounds_in_native().ToString());
406 EXPECT_EQ("0,501 400x400",
407 GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()).
408 bounds_in_native().ToString());
409 EXPECT_EQ("0,0 188x190",
410 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
412 // Make sure just moving the overscan area should property notify observers.
413 UpdateDisplay("0+0-500x500");
414 int64 primary_id = Shell::GetScreen()->GetPrimaryDisplay().id();
415 display_manager()->SetOverscanInsets(primary_id, gfx::Insets(0, 0, 20, 20));
416 EXPECT_EQ("0,0 480x480",
417 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
418 reset();
419 display_manager()->SetOverscanInsets(primary_id, gfx::Insets(10, 10, 10, 10));
420 EXPECT_TRUE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
421 EXPECT_TRUE(
422 changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
423 EXPECT_EQ("0,0 480x480",
424 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
425 reset();
426 display_manager()->SetOverscanInsets(primary_id, gfx::Insets(0, 0, 0, 0));
427 EXPECT_TRUE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
428 EXPECT_TRUE(
429 changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
430 EXPECT_EQ("0,0 500x500",
431 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
434 TEST_F(DisplayManagerTest, ZeroOverscanInsets) {
435 if (!SupportsMultipleDisplays())
436 return;
438 // Make sure the display change events is emitted for overscan inset changes.
439 UpdateDisplay("0+0-500x500,0+501-400x400");
440 ASSERT_EQ(2u, display_manager()->GetNumDisplays());
441 int64 display2_id = display_manager()->GetDisplayAt(1).id();
443 reset();
444 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
445 EXPECT_EQ(0u, changed().size());
447 reset();
448 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0));
449 EXPECT_EQ(1u, changed().size());
450 EXPECT_EQ(display2_id, changed()[0].id());
452 reset();
453 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
454 EXPECT_EQ(1u, changed().size());
455 EXPECT_EQ(display2_id, changed()[0].id());
458 TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
459 if (!SupportsHostWindowResize())
460 return;
462 UpdateDisplay("1000x600");
463 aura::WindowTreeHost* host = Shell::GetPrimaryRootWindow()->GetHost();
464 EXPECT_EQ(1, host->compositor()->device_scale_factor());
465 EXPECT_EQ("1000x600",
466 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
467 EXPECT_EQ("1 0 0", GetCountSummary());
469 UpdateDisplay("1000x600*2");
470 EXPECT_EQ(2, host->compositor()->device_scale_factor());
471 EXPECT_EQ("2 0 0", GetCountSummary());
472 EXPECT_EQ("500x300",
473 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
476 DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
477 DisplayInfo info(id, ToDisplayName(id), false);
478 info.SetBounds(bounds);
479 return info;
482 TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) {
483 const int64 internal_display_id =
484 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
485 const int external_id = 10;
486 const int mirror_id = 11;
487 const int64 invalid_id = gfx::Display::kInvalidDisplayID;
488 const DisplayInfo internal_display_info =
489 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
490 const DisplayInfo external_display_info =
491 CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
492 const DisplayInfo mirroring_display_info =
493 CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500));
495 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
496 EXPECT_EQ(1U, display_manager()->num_connected_displays());
497 std::string default_bounds =
498 display_manager()->GetDisplayAt(0).bounds().ToString();
500 std::vector<DisplayInfo> display_info_list;
501 // Primary disconnected.
502 display_manager()->OnNativeDisplaysChanged(display_info_list);
503 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
504 EXPECT_EQ(default_bounds,
505 display_manager()->GetDisplayAt(0).bounds().ToString());
506 EXPECT_EQ(1U, display_manager()->num_connected_displays());
507 EXPECT_FALSE(display_manager()->IsInMirrorMode());
509 if (!SupportsMultipleDisplays())
510 return;
512 // External connected while primary was disconnected.
513 display_info_list.push_back(external_display_info);
514 display_manager()->OnNativeDisplaysChanged(display_info_list);
515 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
517 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
518 EXPECT_EQ("1,1 100x100",
519 GetDisplayInfoForId(external_id).bounds_in_native().ToString());
520 EXPECT_EQ(1U, display_manager()->num_connected_displays());
521 EXPECT_FALSE(display_manager()->IsInMirrorMode());
522 EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id());
524 EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId());
526 // Primary connected, with different bounds.
527 display_info_list.clear();
528 display_info_list.push_back(internal_display_info);
529 display_info_list.push_back(external_display_info);
530 display_manager()->OnNativeDisplaysChanged(display_info_list);
531 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
532 EXPECT_EQ(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id());
534 // This combinatino is new, so internal display becomes primary.
535 EXPECT_EQ("0,0 500x500",
536 GetDisplayForId(internal_display_id).bounds().ToString());
537 EXPECT_EQ("1,1 100x100",
538 GetDisplayInfoForId(10).bounds_in_native().ToString());
539 EXPECT_EQ(2U, display_manager()->num_connected_displays());
540 EXPECT_FALSE(display_manager()->IsInMirrorMode());
541 EXPECT_EQ(ToDisplayName(internal_display_id),
542 display_manager()->GetDisplayNameForId(internal_display_id));
544 // Emulate suspend.
545 display_info_list.clear();
546 display_manager()->OnNativeDisplaysChanged(display_info_list);
547 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
548 EXPECT_EQ("0,0 500x500",
549 GetDisplayForId(internal_display_id).bounds().ToString());
550 EXPECT_EQ("1,1 100x100",
551 GetDisplayInfoForId(10).bounds_in_native().ToString());
552 EXPECT_EQ(2U, display_manager()->num_connected_displays());
553 EXPECT_FALSE(display_manager()->IsInMirrorMode());
554 EXPECT_EQ(ToDisplayName(internal_display_id),
555 display_manager()->GetDisplayNameForId(internal_display_id));
557 // External display has disconnected then resumed.
558 display_info_list.push_back(internal_display_info);
559 display_manager()->OnNativeDisplaysChanged(display_info_list);
560 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
561 EXPECT_EQ("0,0 500x500",
562 GetDisplayForId(internal_display_id).bounds().ToString());
563 EXPECT_EQ(1U, display_manager()->num_connected_displays());
564 EXPECT_FALSE(display_manager()->IsInMirrorMode());
566 // External display was changed during suspend.
567 display_info_list.push_back(external_display_info);
568 display_manager()->OnNativeDisplaysChanged(display_info_list);
569 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
570 EXPECT_EQ(2U, display_manager()->num_connected_displays());
571 EXPECT_FALSE(display_manager()->IsInMirrorMode());
573 // suspend...
574 display_info_list.clear();
575 display_manager()->OnNativeDisplaysChanged(display_info_list);
576 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
577 EXPECT_EQ(2U, display_manager()->num_connected_displays());
578 EXPECT_FALSE(display_manager()->IsInMirrorMode());
580 // and resume with different external display.
581 display_info_list.push_back(internal_display_info);
582 display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100)));
583 display_manager()->OnNativeDisplaysChanged(display_info_list);
584 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
585 EXPECT_EQ(2U, display_manager()->num_connected_displays());
586 EXPECT_FALSE(display_manager()->IsInMirrorMode());
587 EXPECT_FALSE(display_manager()->IsInMirrorMode());
589 // mirrored...
590 display_info_list.clear();
591 display_info_list.push_back(internal_display_info);
592 display_info_list.push_back(mirroring_display_info);
593 display_manager()->OnNativeDisplaysChanged(display_info_list);
594 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
595 EXPECT_EQ("0,0 500x500",
596 GetDisplayForId(internal_display_id).bounds().ToString());
597 EXPECT_EQ(2U, display_manager()->num_connected_displays());
598 EXPECT_EQ(11U, display_manager()->mirroring_display_id());
599 EXPECT_TRUE(display_manager()->IsInMirrorMode());
601 // Test display name.
602 EXPECT_EQ(ToDisplayName(internal_display_id),
603 display_manager()->GetDisplayNameForId(internal_display_id));
604 EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10));
605 EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11));
606 EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12));
607 // Default name for the id that doesn't exist.
608 EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100));
610 // and exit mirroring.
611 display_info_list.clear();
612 display_info_list.push_back(internal_display_info);
613 display_info_list.push_back(external_display_info);
614 display_manager()->OnNativeDisplaysChanged(display_info_list);
615 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
616 EXPECT_EQ(2U, display_manager()->num_connected_displays());
617 EXPECT_FALSE(display_manager()->IsInMirrorMode());
618 EXPECT_EQ("0,0 500x500",
619 GetDisplayForId(internal_display_id).bounds().ToString());
620 EXPECT_EQ("500,0 100x100",
621 GetDisplayForId(10).bounds().ToString());
623 // Turn off internal
624 display_info_list.clear();
625 display_info_list.push_back(external_display_info);
626 display_manager()->OnNativeDisplaysChanged(display_info_list);
627 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
628 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
629 EXPECT_EQ("1,1 100x100",
630 GetDisplayInfoForId(external_id).bounds_in_native().ToString());
631 EXPECT_EQ(1U, display_manager()->num_connected_displays());
632 EXPECT_FALSE(display_manager()->IsInMirrorMode());
634 // Switched to another display
635 display_info_list.clear();
636 display_info_list.push_back(internal_display_info);
637 display_manager()->OnNativeDisplaysChanged(display_info_list);
638 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
639 EXPECT_EQ(
640 "0,0 500x500",
641 GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString());
642 EXPECT_EQ(1U, display_manager()->num_connected_displays());
643 EXPECT_FALSE(display_manager()->IsInMirrorMode());
646 // Make sure crash does not happen if add and remove happens at the same time.
647 // See: crbug.com/414394
648 TEST_F(DisplayManagerTest, DisplayAddRemoveAtTheSameTime) {
649 if (!SupportsMultipleDisplays())
650 return;
652 UpdateDisplay("100+0-500x500,0+501-400x400");
654 const int64 primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
655 const int64 secondary_id = ScreenUtil::GetSecondaryDisplay().id();
657 DisplayInfo primary_info = display_manager()->GetDisplayInfo(primary_id);
658 DisplayInfo secondary_info = display_manager()->GetDisplayInfo(secondary_id);
660 // An id which is different from primary and secondary.
661 const int64 third_id = secondary_id + 1;
663 DisplayInfo third_info =
664 CreateDisplayInfo(third_id, gfx::Rect(0, 0, 600, 600));
666 std::vector<DisplayInfo> display_info_list;
667 display_info_list.push_back(third_info);
668 display_info_list.push_back(secondary_info);
669 display_manager()->OnNativeDisplaysChanged(display_info_list);
671 // Secondary seconary_id becomes the primary as it has smaller output index.
672 EXPECT_EQ(secondary_id, WindowTreeHostManager::GetPrimaryDisplayId());
673 EXPECT_EQ(third_id, ScreenUtil::GetSecondaryDisplay().id());
674 EXPECT_EQ("600x600", GetDisplayForId(third_id).size().ToString());
677 #if defined(OS_WIN)
678 // TODO(scottmg): RootWindow doesn't get resized on Windows
679 // Ash. http://crbug.com/247916.
680 #define MAYBE_TestNativeDisplaysChangedNoInternal \
681 DISABLED_TestNativeDisplaysChangedNoInternal
682 #else
683 #define MAYBE_TestNativeDisplaysChangedNoInternal \
684 TestNativeDisplaysChangedNoInternal
685 #endif
687 TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) {
688 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
690 // Don't change the display info if all displays are disconnected.
691 std::vector<DisplayInfo> display_info_list;
692 display_manager()->OnNativeDisplaysChanged(display_info_list);
693 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
695 // Connect another display which will become primary.
696 const DisplayInfo external_display_info =
697 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
698 display_info_list.push_back(external_display_info);
699 display_manager()->OnNativeDisplaysChanged(display_info_list);
700 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
701 EXPECT_EQ("1,1 100x100",
702 GetDisplayInfoForId(10).bounds_in_native().ToString());
703 EXPECT_EQ("100x100", ash::Shell::GetPrimaryRootWindow()->GetHost()->
704 GetBounds().size().ToString());
707 TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
708 if (!SupportsMultipleDisplays())
709 return;
711 const int64 internal_display_id =
712 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
713 const DisplayInfo native_display_info =
714 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
715 const DisplayInfo secondary_display_info =
716 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
718 std::vector<DisplayInfo> display_info_list;
719 display_info_list.push_back(native_display_info);
720 display_info_list.push_back(secondary_display_info);
721 display_manager()->OnNativeDisplaysChanged(display_info_list);
722 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
723 EXPECT_EQ("0,0 500x500",
724 GetDisplayForId(internal_display_id).bounds().ToString());
725 EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString());
727 ash::Shell::GetInstance()->window_tree_host_manager()->SetPrimaryDisplay(
728 GetDisplayForId(secondary_display_info.id()));
729 EXPECT_EQ("-500,0 500x500",
730 GetDisplayForId(internal_display_id).bounds().ToString());
731 EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());
733 // OnNativeDisplaysChanged may change the display bounds. Here makes sure
734 // nothing changed if the exactly same displays are specified.
735 display_manager()->OnNativeDisplaysChanged(display_info_list);
736 EXPECT_EQ("-500,0 500x500",
737 GetDisplayForId(internal_display_id).bounds().ToString());
738 EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());
741 TEST_F(DisplayManagerTest, DontRememberBestResolution) {
742 int display_id = 1000;
743 DisplayInfo native_display_info =
744 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
745 std::vector<DisplayMode> display_modes;
746 display_modes.push_back(
747 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true));
748 display_modes.push_back(
749 DisplayMode(gfx::Size(800, 300), 59.0f, false, false));
750 display_modes.push_back(
751 DisplayMode(gfx::Size(400, 500), 60.0f, false, false));
753 native_display_info.SetDisplayModes(display_modes);
755 std::vector<DisplayInfo> display_info_list;
756 display_info_list.push_back(native_display_info);
757 display_manager()->OnNativeDisplaysChanged(display_info_list);
759 DisplayMode mode;
760 DisplayMode expected_mode;
761 expected_mode.size = gfx::Size(1000, 500);
762 EXPECT_FALSE(
763 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
764 EXPECT_TRUE(expected_mode.IsEquivalent(
765 display_manager()->GetActiveModeForDisplayId(display_id)));
767 // Unsupported resolution.
768 test::SetDisplayResolution(display_id, gfx::Size(800, 4000));
769 EXPECT_FALSE(
770 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
771 EXPECT_TRUE(expected_mode.IsEquivalent(
772 display_manager()->GetActiveModeForDisplayId(display_id)));
774 // Supported resolution.
775 test::SetDisplayResolution(display_id, gfx::Size(800, 300));
776 EXPECT_TRUE(
777 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
778 EXPECT_EQ("800x300", mode.size.ToString());
779 EXPECT_EQ(59.0f, mode.refresh_rate);
780 EXPECT_FALSE(mode.native);
781 expected_mode.size = gfx::Size(800, 300);
782 EXPECT_TRUE(expected_mode.IsEquivalent(
783 display_manager()->GetActiveModeForDisplayId(display_id)));
785 // Best resolution.
786 test::SetDisplayResolution(display_id, gfx::Size(1000, 500));
787 EXPECT_TRUE(
788 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
789 EXPECT_EQ("1000x500", mode.size.ToString());
790 EXPECT_EQ(58.0f, mode.refresh_rate);
791 EXPECT_TRUE(mode.native);
792 expected_mode.size = gfx::Size(1000, 500);
793 EXPECT_TRUE(expected_mode.IsEquivalent(
794 display_manager()->GetActiveModeForDisplayId(display_id)));
797 TEST_F(DisplayManagerTest, ResolutionFallback) {
798 int display_id = 1000;
799 DisplayInfo native_display_info =
800 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
801 std::vector<DisplayMode> display_modes;
802 display_modes.push_back(
803 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true));
804 display_modes.push_back(
805 DisplayMode(gfx::Size(800, 300), 59.0f, false, false));
806 display_modes.push_back(
807 DisplayMode(gfx::Size(400, 500), 60.0f, false, false));
809 std::vector<DisplayMode> copy = display_modes;
810 native_display_info.SetDisplayModes(copy);
812 std::vector<DisplayInfo> display_info_list;
813 display_info_list.push_back(native_display_info);
814 display_manager()->OnNativeDisplaysChanged(display_info_list);
816 test::SetDisplayResolution(display_id, gfx::Size(800, 300));
817 DisplayInfo new_native_display_info =
818 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 400, 500));
819 copy = display_modes;
820 new_native_display_info.SetDisplayModes(copy);
821 std::vector<DisplayInfo> new_display_info_list;
822 new_display_info_list.push_back(new_native_display_info);
823 display_manager()->OnNativeDisplaysChanged(new_display_info_list);
825 DisplayMode mode;
826 EXPECT_TRUE(
827 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
828 EXPECT_EQ("400x500", mode.size.ToString());
829 EXPECT_EQ(60.0f, mode.refresh_rate);
830 EXPECT_FALSE(mode.native);
833 // Best resolution should find itself on the resolutions list.
834 test::SetDisplayResolution(display_id, gfx::Size(800, 300));
835 DisplayInfo new_native_display_info =
836 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
837 std::vector<DisplayMode> copy = display_modes;
838 new_native_display_info.SetDisplayModes(copy);
839 std::vector<DisplayInfo> new_display_info_list;
840 new_display_info_list.push_back(new_native_display_info);
841 display_manager()->OnNativeDisplaysChanged(new_display_info_list);
843 DisplayMode mode;
844 EXPECT_TRUE(
845 display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
846 EXPECT_EQ("1000x500", mode.size.ToString());
847 EXPECT_EQ(58.0f, mode.refresh_rate);
848 EXPECT_TRUE(mode.native);
852 TEST_F(DisplayManagerTest, Rotate) {
853 if (!SupportsMultipleDisplays())
854 return;
856 UpdateDisplay("100x200/r,300x400/l");
857 EXPECT_EQ("1,1 100x200",
858 GetDisplayInfoAt(0).bounds_in_native().ToString());
859 EXPECT_EQ("200x100",
860 GetDisplayInfoAt(0).size_in_pixel().ToString());
862 EXPECT_EQ("1,201 300x400",
863 GetDisplayInfoAt(1).bounds_in_native().ToString());
864 EXPECT_EQ("400x300",
865 GetDisplayInfoAt(1).size_in_pixel().ToString());
866 reset();
867 UpdateDisplay("100x200/b,300x400");
868 EXPECT_EQ("2 0 0", GetCountSummary());
869 reset();
871 EXPECT_EQ("1,1 100x200",
872 GetDisplayInfoAt(0).bounds_in_native().ToString());
873 EXPECT_EQ("100x200",
874 GetDisplayInfoAt(0).size_in_pixel().ToString());
876 EXPECT_EQ("1,201 300x400",
877 GetDisplayInfoAt(1).bounds_in_native().ToString());
878 EXPECT_EQ("300x400",
879 GetDisplayInfoAt(1).size_in_pixel().ToString());
881 // Just Rotating display will change the bounds on both display.
882 UpdateDisplay("100x200/l,300x400");
883 EXPECT_EQ("2 0 0", GetCountSummary());
884 reset();
886 // Updating to the same configuration should report no changes.
887 UpdateDisplay("100x200/l,300x400");
888 EXPECT_EQ("0 0 0", GetCountSummary());
889 reset();
891 // Rotating 180 degrees should report one change.
892 UpdateDisplay("100x200/r,300x400");
893 EXPECT_EQ("1 0 0", GetCountSummary());
894 reset();
896 UpdateDisplay("200x200");
897 EXPECT_EQ("1 0 1", GetCountSummary());
898 reset();
900 // Rotating 180 degrees should report one change.
901 UpdateDisplay("200x200/u");
902 EXPECT_EQ("1 0 0", GetCountSummary());
903 reset();
905 UpdateDisplay("200x200/l");
906 EXPECT_EQ("1 0 0", GetCountSummary());
908 // Having the internal display deactivated should restore user rotation. Newly
909 // set rotations should be applied.
910 UpdateDisplay("200x200, 200x200");
911 const int64 internal_display_id =
912 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
914 display_manager()->SetDisplayRotation(internal_display_id,
915 gfx::Display::ROTATE_90,
916 gfx::Display::ROTATION_SOURCE_USER);
917 display_manager()->SetDisplayRotation(internal_display_id,
918 gfx::Display::ROTATE_0,
919 gfx::Display::ROTATION_SOURCE_ACTIVE);
921 const DisplayInfo info = GetDisplayInfoForId(internal_display_id);
922 EXPECT_EQ(gfx::Display::ROTATE_0, info.GetActiveRotation());
924 // Deactivate internal display to simulate Docked Mode.
925 vector<DisplayInfo> secondary_only;
926 secondary_only.push_back(GetDisplayInfoAt(1));
927 display_manager()->OnNativeDisplaysChanged(secondary_only);
929 const DisplayInfo post_removal_info =
930 display_manager()->display_info_[internal_display_id];
931 EXPECT_NE(info.GetActiveRotation(), post_removal_info.GetActiveRotation());
932 EXPECT_EQ(gfx::Display::ROTATE_90, post_removal_info.GetActiveRotation());
934 display_manager()->SetDisplayRotation(internal_display_id,
935 gfx::Display::ROTATE_180,
936 gfx::Display::ROTATION_SOURCE_ACTIVE);
937 const DisplayInfo post_rotation_info =
938 display_manager()->display_info_[internal_display_id];
939 EXPECT_NE(info.GetActiveRotation(), post_rotation_info.GetActiveRotation());
940 EXPECT_EQ(gfx::Display::ROTATE_180, post_rotation_info.GetActiveRotation());
943 TEST_F(DisplayManagerTest, UIScale) {
944 test::ScopedDisable125DSFForUIScaling disable;
946 UpdateDisplay("1280x800");
947 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id();
948 SetDisplayUIScale(display_id, 1.125f);
949 EXPECT_EQ(1.0, GetDisplayInfoAt(0).configured_ui_scale());
950 SetDisplayUIScale(display_id, 0.8f);
951 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
952 SetDisplayUIScale(display_id, 0.75f);
953 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
954 SetDisplayUIScale(display_id, 0.625f);
955 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
957 test::ScopedSetInternalDisplayId set_internal(display_id);
959 SetDisplayUIScale(display_id, 1.5f);
960 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
961 SetDisplayUIScale(display_id, 1.25f);
962 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
963 SetDisplayUIScale(display_id, 1.125f);
964 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale());
965 SetDisplayUIScale(display_id, 0.8f);
966 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
967 SetDisplayUIScale(display_id, 0.75f);
968 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
969 SetDisplayUIScale(display_id, 0.625f);
970 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
971 SetDisplayUIScale(display_id, 0.6f);
972 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
973 SetDisplayUIScale(display_id, 0.5f);
974 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale());
976 UpdateDisplay("1366x768");
977 SetDisplayUIScale(display_id, 1.5f);
978 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
979 SetDisplayUIScale(display_id, 1.25f);
980 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
981 SetDisplayUIScale(display_id, 1.125f);
982 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale());
983 SetDisplayUIScale(display_id, 0.8f);
984 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale());
985 SetDisplayUIScale(display_id, 0.75f);
986 EXPECT_EQ(0.75f, GetDisplayInfoAt(0).configured_ui_scale());
987 SetDisplayUIScale(display_id, 0.6f);
988 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale());
989 SetDisplayUIScale(display_id, 0.625f);
990 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale());
991 SetDisplayUIScale(display_id, 0.5f);
992 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale());
994 UpdateDisplay("1280x850*2");
995 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
996 SetDisplayUIScale(display_id, 1.5f);
997 EXPECT_EQ(1.5f, GetDisplayInfoAt(0).configured_ui_scale());
998 SetDisplayUIScale(display_id, 1.25f);
999 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).configured_ui_scale());
1000 SetDisplayUIScale(display_id, 1.125f);
1001 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale());
1002 SetDisplayUIScale(display_id, 1.0f);
1003 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
1004 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
1005 EXPECT_EQ(2.0f, display.device_scale_factor());
1006 EXPECT_EQ("640x425", display.bounds().size().ToString());
1008 SetDisplayUIScale(display_id, 0.8f);
1009 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
1010 SetDisplayUIScale(display_id, 0.75f);
1011 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
1012 SetDisplayUIScale(display_id, 0.625f);
1013 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
1014 SetDisplayUIScale(display_id, 0.6f);
1015 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
1016 SetDisplayUIScale(display_id, 0.5f);
1017 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale());
1019 SetDisplayUIScale(display_id, 2.0f);
1020 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).configured_ui_scale());
1021 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1022 display = Shell::GetScreen()->GetPrimaryDisplay();
1023 EXPECT_EQ(1.0f, display.device_scale_factor());
1024 EXPECT_EQ("1280x850", display.bounds().size().ToString());
1026 // 1.25 ui scaling on 1.25 DSF device should use 1.0 DSF
1027 // on screen.
1028 UpdateDisplay("1280x850*1.25");
1029 SetDisplayUIScale(display_id, 1.25f);
1030 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).configured_ui_scale());
1031 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1032 display = Shell::GetScreen()->GetPrimaryDisplay();
1033 EXPECT_EQ(1.0f, display.device_scale_factor());
1034 EXPECT_EQ("1280x850", display.bounds().size().ToString());
1037 TEST_F(DisplayManagerTest, UIScaleWithDisplayMode) {
1038 int display_id = 1000;
1040 // Setup the display modes with UI-scale.
1041 DisplayInfo native_display_info =
1042 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1280, 800));
1043 std::vector<DisplayMode> display_modes;
1044 const DisplayMode base_mode(gfx::Size(1280, 800), 60.0f, false, false);
1045 std::vector<DisplayMode> mode_list = CreateInternalDisplayModeList(base_mode);
1046 native_display_info.SetDisplayModes(mode_list);
1048 std::vector<DisplayInfo> display_info_list;
1049 display_info_list.push_back(native_display_info);
1050 display_manager()->OnNativeDisplaysChanged(display_info_list);
1052 DisplayMode expected_mode = base_mode;
1053 EXPECT_TRUE(expected_mode.IsEquivalent(
1054 display_manager()->GetActiveModeForDisplayId(display_id)));
1056 test::ScopedSetInternalDisplayId set_internal(display_id);
1058 SetDisplayUIScale(display_id, 1.5f);
1059 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
1060 EXPECT_TRUE(expected_mode.IsEquivalent(
1061 display_manager()->GetActiveModeForDisplayId(display_id)));
1062 SetDisplayUIScale(display_id, 1.25f);
1063 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale());
1064 EXPECT_TRUE(expected_mode.IsEquivalent(
1065 display_manager()->GetActiveModeForDisplayId(display_id)));
1066 SetDisplayUIScale(display_id, 1.125f);
1067 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale());
1068 expected_mode.ui_scale = 1.125f;
1069 EXPECT_TRUE(expected_mode.IsEquivalent(
1070 display_manager()->GetActiveModeForDisplayId(display_id)));
1071 SetDisplayUIScale(display_id, 0.8f);
1072 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
1073 expected_mode.ui_scale = 0.8f;
1074 EXPECT_TRUE(expected_mode.IsEquivalent(
1075 display_manager()->GetActiveModeForDisplayId(display_id)));
1076 SetDisplayUIScale(display_id, 0.75f);
1077 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale());
1078 EXPECT_TRUE(expected_mode.IsEquivalent(
1079 display_manager()->GetActiveModeForDisplayId(display_id)));
1080 SetDisplayUIScale(display_id, 0.625f);
1081 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
1082 expected_mode.ui_scale = 0.625f;
1083 EXPECT_TRUE(expected_mode.IsEquivalent(
1084 display_manager()->GetActiveModeForDisplayId(display_id)));
1085 SetDisplayUIScale(display_id, 0.6f);
1086 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale());
1087 EXPECT_TRUE(expected_mode.IsEquivalent(
1088 display_manager()->GetActiveModeForDisplayId(display_id)));
1089 SetDisplayUIScale(display_id, 0.5f);
1090 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale());
1091 expected_mode.ui_scale = 0.5f;
1092 EXPECT_TRUE(expected_mode.IsEquivalent(
1093 display_manager()->GetActiveModeForDisplayId(display_id)));
1096 TEST_F(DisplayManagerTest, Use125DSFForUIScaling) {
1097 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id();
1098 test::ScopedSetInternalDisplayId set_internal(display_id);
1100 UpdateDisplay("1920x1080*1.25");
1101 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor());
1102 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1104 SetDisplayUIScale(display_id, 0.8f);
1105 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor());
1106 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1107 EXPECT_EQ("1536x864", GetDisplayForId(display_id).size().ToString());
1109 SetDisplayUIScale(display_id, 0.5f);
1110 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor());
1111 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1112 EXPECT_EQ("960x540", GetDisplayForId(display_id).size().ToString());
1114 SetDisplayUIScale(display_id, 1.25f);
1115 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor());
1116 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).GetEffectiveUIScale());
1117 EXPECT_EQ("2400x1350", GetDisplayForId(display_id).size().ToString());
1120 TEST_F(DisplayManagerTest, ResolutionChangeInUnifiedMode) {
1121 if (!SupportsMultipleDisplays())
1122 return;
1123 // Don't check root window destruction in unified mode.
1124 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1126 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1127 display_manager->SetUnifiedDesktopEnabled(true);
1129 UpdateDisplay("200x200, 400x400");
1131 int64 unified_id = Shell::GetScreen()->GetPrimaryDisplay().id();
1132 DisplayInfo info = display_manager->GetDisplayInfo(unified_id);
1133 ASSERT_EQ(2u, info.display_modes().size());
1134 EXPECT_EQ("400x200", info.display_modes()[0].size.ToString());
1135 EXPECT_TRUE(info.display_modes()[0].native);
1136 EXPECT_EQ("800x400", info.display_modes()[1].size.ToString());
1137 EXPECT_FALSE(info.display_modes()[1].native);
1138 EXPECT_EQ("400x200",
1139 Shell::GetScreen()->GetPrimaryDisplay().size().ToString());
1140 DisplayMode active_mode =
1141 display_manager->GetActiveModeForDisplayId(unified_id);
1142 EXPECT_EQ(1.0f, active_mode.ui_scale);
1143 EXPECT_EQ("400x200", active_mode.size.ToString());
1145 EXPECT_TRUE(test::SetDisplayResolution(unified_id, gfx::Size(800, 400)));
1146 EXPECT_EQ("800x400",
1147 Shell::GetScreen()->GetPrimaryDisplay().size().ToString());
1149 active_mode = display_manager->GetActiveModeForDisplayId(unified_id);
1150 EXPECT_EQ(1.0f, active_mode.ui_scale);
1151 EXPECT_EQ("800x400", active_mode.size.ToString());
1153 // resolution change will not persist in unified desktop mode.
1154 UpdateDisplay("600x600, 200x200");
1155 EXPECT_EQ("1200x600",
1156 Shell::GetScreen()->GetPrimaryDisplay().size().ToString());
1157 active_mode = display_manager->GetActiveModeForDisplayId(unified_id);
1158 EXPECT_EQ(1.0f, active_mode.ui_scale);
1159 EXPECT_TRUE(active_mode.native);
1160 EXPECT_EQ("1200x600", active_mode.size.ToString());
1163 #if defined(OS_WIN)
1164 // TODO(scottmg): RootWindow doesn't get resized on Windows
1165 // Ash. http://crbug.com/247916.
1166 #define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom
1167 #else
1168 #define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom
1169 #endif
1171 TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) {
1172 // Make sure just rotating will not change native location.
1173 UpdateDisplay("300x200,200x150");
1174 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1175 aura::Env* env = aura::Env::GetInstance();
1177 ui::test::EventGenerator generator1(root_windows[0]);
1178 ui::test::EventGenerator generator2(root_windows[1]);
1180 // Test on 1st display.
1181 generator1.MoveMouseToInHost(150, 50);
1182 EXPECT_EQ("150,50", env->last_mouse_location().ToString());
1183 UpdateDisplay("300x200/r,200x150");
1184 EXPECT_EQ("50,149", env->last_mouse_location().ToString());
1186 // Test on 2nd display.
1187 generator2.MoveMouseToInHost(50, 100);
1188 EXPECT_EQ("250,100", env->last_mouse_location().ToString());
1189 UpdateDisplay("300x200/r,200x150/l");
1190 EXPECT_EQ("249,50", env->last_mouse_location().ToString());
1192 // The native location is now outside, so move to the center
1193 // of closest display.
1194 UpdateDisplay("300x200/r,100x50/l");
1195 EXPECT_EQ("225,50", env->last_mouse_location().ToString());
1197 // Make sure just zooming will not change native location.
1198 UpdateDisplay("600x400*2,400x300");
1200 // Test on 1st display.
1201 generator1.MoveMouseToInHost(200, 300);
1202 EXPECT_EQ("100,150", env->last_mouse_location().ToString());
1203 UpdateDisplay("600x400*2@1.5,400x300");
1204 EXPECT_EQ("150,225", env->last_mouse_location().ToString());
1206 // Test on 2nd display.
1207 UpdateDisplay("600x400,400x300*2");
1208 generator2.MoveMouseToInHost(200, 250);
1209 EXPECT_EQ("700,125", env->last_mouse_location().ToString());
1210 UpdateDisplay("600x400,400x300*2@1.5");
1211 EXPECT_EQ("750,187", env->last_mouse_location().ToString());
1213 // The native location is now outside, so move to the
1214 // center of closest display.
1215 UpdateDisplay("600x400,400x200*2@1.5");
1216 EXPECT_EQ("750,75", env->last_mouse_location().ToString());
1219 class TestDisplayObserver : public gfx::DisplayObserver {
1220 public:
1221 TestDisplayObserver() : changed_(false) {}
1222 ~TestDisplayObserver() override {}
1224 // gfx::DisplayObserver overrides:
1225 void OnDisplayMetricsChanged(const gfx::Display&, uint32_t) override {}
1226 void OnDisplayAdded(const gfx::Display& new_display) override {
1227 // Mirror window should already be delete before restoring
1228 // the external display.
1229 EXPECT_FALSE(test_api.GetHost());
1230 changed_ = true;
1232 void OnDisplayRemoved(const gfx::Display& old_display) override {
1233 // Mirror window should not be created until the external display
1234 // is removed.
1235 EXPECT_FALSE(test_api.GetHost());
1236 changed_ = true;
1239 bool changed_and_reset() {
1240 bool changed = changed_;
1241 changed_ = false;
1242 return changed;
1245 private:
1246 test::MirrorWindowTestApi test_api;
1247 bool changed_;
1249 DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver);
1252 TEST_F(DisplayManagerTest, SoftwareMirroring) {
1253 if (!SupportsMultipleDisplays())
1254 return;
1256 UpdateDisplay("300x400,400x500");
1258 test::MirrorWindowTestApi test_api;
1259 EXPECT_EQ(NULL, test_api.GetHost());
1261 TestDisplayObserver display_observer;
1262 Shell::GetScreen()->AddObserver(&display_observer);
1264 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1265 display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
1266 display_manager->UpdateDisplays();
1267 RunAllPendingInMessageLoop();
1268 EXPECT_TRUE(display_observer.changed_and_reset());
1269 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1270 EXPECT_EQ("0,0 300x400",
1271 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
1272 EXPECT_EQ("400x500", test_api.GetHost()->GetBounds().size().ToString());
1273 EXPECT_EQ("300x400",
1274 test_api.GetHost()->window()->bounds().size().ToString());
1275 EXPECT_TRUE(display_manager->IsInMirrorMode());
1277 display_manager->SetMirrorMode(false);
1278 EXPECT_TRUE(display_observer.changed_and_reset());
1279 EXPECT_EQ(NULL, test_api.GetHost());
1280 EXPECT_EQ(2U, display_manager->GetNumDisplays());
1281 EXPECT_FALSE(display_manager->IsInMirrorMode());
1283 // Make sure the mirror window has the pixel size of the
1284 // source display.
1285 display_manager->SetMirrorMode(true);
1286 EXPECT_TRUE(display_observer.changed_and_reset());
1288 UpdateDisplay("300x400@0.5,400x500");
1289 EXPECT_FALSE(display_observer.changed_and_reset());
1290 EXPECT_EQ("300x400",
1291 test_api.GetHost()->window()->bounds().size().ToString());
1293 UpdateDisplay("310x410*2,400x500");
1294 EXPECT_FALSE(display_observer.changed_and_reset());
1295 EXPECT_EQ("310x410",
1296 test_api.GetHost()->window()->bounds().size().ToString());
1298 UpdateDisplay("320x420/r,400x500");
1299 EXPECT_FALSE(display_observer.changed_and_reset());
1300 EXPECT_EQ("320x420",
1301 test_api.GetHost()->window()->bounds().size().ToString());
1303 UpdateDisplay("330x440/r,400x500");
1304 EXPECT_FALSE(display_observer.changed_and_reset());
1305 EXPECT_EQ("330x440",
1306 test_api.GetHost()->window()->bounds().size().ToString());
1308 // Overscan insets are ignored.
1309 UpdateDisplay("400x600/o,600x800/o");
1310 EXPECT_FALSE(display_observer.changed_and_reset());
1311 EXPECT_EQ("400x600",
1312 test_api.GetHost()->window()->bounds().size().ToString());
1314 Shell::GetScreen()->RemoveObserver(&display_observer);
1317 TEST_F(DisplayManagerTest, SingleDisplayToSoftwareMirroring) {
1318 if (!SupportsMultipleDisplays())
1319 return;
1320 UpdateDisplay("600x400");
1322 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1323 display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
1324 UpdateDisplay("600x400,600x400");
1326 EXPECT_TRUE(display_manager->IsInMirrorMode());
1327 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1328 WindowTreeHostManager* window_tree_host_manager =
1329 ash::Shell::GetInstance()->window_tree_host_manager();
1330 EXPECT_TRUE(
1331 window_tree_host_manager->mirror_window_controller()->GetWindow());
1333 UpdateDisplay("600x400");
1334 EXPECT_FALSE(display_manager->IsInMirrorMode());
1335 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1336 EXPECT_FALSE(
1337 window_tree_host_manager->mirror_window_controller()->GetWindow());
1340 #if defined(OS_CHROMEOS)
1341 // Make sure this does not cause any crashes. See http://crbug.com/412910
1342 // This test is limited to OS_CHROMEOS because CursorCompositingEnabled is only
1343 // for ChromeOS.
1344 TEST_F(DisplayManagerTest, SoftwareMirroringWithCompositingCursor) {
1345 if (!SupportsMultipleDisplays())
1346 return;
1348 UpdateDisplay("300x400,400x500");
1350 test::MirrorWindowTestApi test_api;
1351 EXPECT_EQ(NULL, test_api.GetHost());
1353 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1354 DisplayInfo secondary_info = display_manager->GetDisplayInfo(
1355 ScreenUtil::GetSecondaryDisplay().id());
1357 display_manager->SetSoftwareMirroring(true);
1358 display_manager->UpdateDisplays();
1360 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1361 EXPECT_FALSE(root_windows[0]->Contains(test_api.GetCursorWindow()));
1363 Shell::GetInstance()->SetCursorCompositingEnabled(true);
1365 EXPECT_TRUE(root_windows[0]->Contains(test_api.GetCursorWindow()));
1367 // Removes the first display and keeps the second one.
1368 display_manager->SetSoftwareMirroring(false);
1369 std::vector<DisplayInfo> new_info_list;
1370 new_info_list.push_back(secondary_info);
1371 display_manager->OnNativeDisplaysChanged(new_info_list);
1373 root_windows = Shell::GetAllRootWindows();
1374 EXPECT_TRUE(root_windows[0]->Contains(test_api.GetCursorWindow()));
1376 Shell::GetInstance()->SetCursorCompositingEnabled(false);
1378 #endif // OS_CHROMEOS
1380 TEST_F(DisplayManagerTest, MirroredLayout) {
1381 if (!SupportsMultipleDisplays())
1382 return;
1384 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1385 UpdateDisplay("500x500,400x400");
1386 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored);
1387 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1388 EXPECT_EQ(2U, display_manager->num_connected_displays());
1390 UpdateDisplay("1+0-500x500,1+0-500x500");
1391 EXPECT_TRUE(display_manager->GetCurrentDisplayLayout().mirrored);
1392 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
1393 EXPECT_EQ(2U, display_manager->num_connected_displays());
1395 UpdateDisplay("500x500,500x500");
1396 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored);
1397 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1398 EXPECT_EQ(2U, display_manager->num_connected_displays());
1401 TEST_F(DisplayManagerTest, InvertLayout) {
1402 EXPECT_EQ("left, 0",
1403 DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString());
1404 EXPECT_EQ("left, -100",
1405 DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString());
1406 EXPECT_EQ("left, 50",
1407 DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString());
1409 EXPECT_EQ("right, 0",
1410 DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString());
1411 EXPECT_EQ("right, -90",
1412 DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString());
1413 EXPECT_EQ("right, 60",
1414 DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString());
1416 EXPECT_EQ("bottom, 0",
1417 DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString());
1418 EXPECT_EQ("bottom, -80",
1419 DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString());
1420 EXPECT_EQ("bottom, 70",
1421 DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString());
1423 EXPECT_EQ("top, 0",
1424 DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString());
1425 EXPECT_EQ("top, -70",
1426 DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString());
1427 EXPECT_EQ("top, 80",
1428 DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
1431 TEST_F(DisplayManagerTest, NotifyPrimaryChange) {
1432 if (!SupportsMultipleDisplays())
1433 return;
1434 UpdateDisplay("500x500,500x500");
1435 ash::Shell::GetInstance()->window_tree_host_manager()->SwapPrimaryDisplay();
1436 reset();
1437 UpdateDisplay("500x500");
1438 EXPECT_FALSE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
1439 EXPECT_FALSE(changed_metrics() &
1440 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
1441 EXPECT_TRUE(changed_metrics() &
1442 gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY);
1444 UpdateDisplay("500x500,500x500");
1445 ash::Shell::GetInstance()->window_tree_host_manager()->SwapPrimaryDisplay();
1446 reset();
1447 UpdateDisplay("500x400");
1448 EXPECT_TRUE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
1449 EXPECT_TRUE(changed_metrics() &
1450 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
1451 EXPECT_TRUE(changed_metrics() &
1452 gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY);
1455 TEST_F(DisplayManagerTest, NotifyPrimaryChangeUndock) {
1456 if (!SupportsMultipleDisplays())
1457 return;
1458 // Assume the default display is an external display, and
1459 // emulates undocking by switching to another display.
1460 DisplayInfo another_display_info =
1461 CreateDisplayInfo(1, gfx::Rect(0, 0, 1280, 800));
1462 std::vector<DisplayInfo> info_list;
1463 info_list.push_back(another_display_info);
1464 reset();
1465 display_manager()->OnNativeDisplaysChanged(info_list);
1466 EXPECT_TRUE(changed_metrics() & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS);
1467 EXPECT_TRUE(changed_metrics() &
1468 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
1469 EXPECT_TRUE(changed_metrics() &
1470 gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY);
1473 #if defined(OS_WIN)
1474 // TODO(scottmg): RootWindow doesn't get resized on Windows
1475 // Ash. http://crbug.com/247916.
1476 #define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin
1477 #else
1478 #define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin
1479 #endif
1481 TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) {
1482 UpdateDisplay("100x200,300x400");
1483 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1484 aura::Window::Windows root_windows =
1485 Shell::GetInstance()->GetAllRootWindows();
1486 ASSERT_EQ(2U, root_windows.size());
1487 aura::WindowTreeHost* host0 = root_windows[0]->GetHost();
1488 aura::WindowTreeHost* host1 = root_windows[1]->GetHost();
1490 EXPECT_EQ("1,1", host0->GetBounds().origin().ToString());
1491 EXPECT_EQ("100x200", host0->GetBounds().size().ToString());
1492 // UpdateDisplay set the origin if it's not set.
1493 EXPECT_NE("1,1", host1->GetBounds().origin().ToString());
1494 EXPECT_EQ("300x400", host1->GetBounds().size().ToString());
1496 UpdateDisplay("100x200,200+300-300x400");
1497 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1498 EXPECT_EQ("0,0", host0->GetBounds().origin().ToString());
1499 EXPECT_EQ("100x200", host0->GetBounds().size().ToString());
1500 EXPECT_EQ("200,300", host1->GetBounds().origin().ToString());
1501 EXPECT_EQ("300x400", host1->GetBounds().size().ToString());
1503 UpdateDisplay("400+500-200x300,300x400");
1504 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1505 EXPECT_EQ("400,500", host0->GetBounds().origin().ToString());
1506 EXPECT_EQ("200x300", host0->GetBounds().size().ToString());
1507 EXPECT_EQ("0,0", host1->GetBounds().origin().ToString());
1508 EXPECT_EQ("300x400", host1->GetBounds().size().ToString());
1510 UpdateDisplay("100+200-100x200,300+500-200x300");
1511 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1512 EXPECT_EQ("100,200", host0->GetBounds().origin().ToString());
1513 EXPECT_EQ("100x200", host0->GetBounds().size().ToString());
1514 EXPECT_EQ("300,500", host1->GetBounds().origin().ToString());
1515 EXPECT_EQ("200x300", host1->GetBounds().size().ToString());
1518 TEST_F(DisplayManagerTest, UnifiedDesktopBasic) {
1519 if (!SupportsMultipleDisplays())
1520 return;
1522 // Don't check root window destruction in unified mode.
1523 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1525 UpdateDisplay("400x500,300x200");
1527 // Enable after extended mode.
1528 display_manager()->SetUnifiedDesktopEnabled(true);
1530 // Defaults to the unified desktop.
1531 gfx::Screen* screen =
1532 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
1533 // The 2nd display is scaled so that it has the same height as 1st display.
1534 // 300 * 500 / 200 + 400 = 1150.
1535 EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());
1537 display_manager()->SetMirrorMode(true);
1538 EXPECT_EQ("400x500", screen->GetPrimaryDisplay().size().ToString());
1540 display_manager()->SetMirrorMode(false);
1541 EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());
1543 // Switch to single desktop.
1544 UpdateDisplay("500x300");
1545 EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString());
1547 // Switch to unified desktop.
1548 UpdateDisplay("500x300,400x500");
1549 // 400 * 300 / 500 + 500 ~= 739.
1550 EXPECT_EQ("739x300", screen->GetPrimaryDisplay().size().ToString());
1552 // The default should fit to the internal display.
1553 std::vector<DisplayInfo> display_info_list;
1554 display_info_list.push_back(CreateDisplayInfo(10, gfx::Rect(0, 0, 500, 300)));
1555 display_info_list.push_back(
1556 CreateDisplayInfo(11, gfx::Rect(500, 0, 400, 500)));
1558 test::ScopedSetInternalDisplayId set_internal(11);
1559 display_manager()->OnNativeDisplaysChanged(display_info_list);
1560 // 500 * 500 / 300 + 400 ~= 1233.
1561 EXPECT_EQ("1233x500", screen->GetPrimaryDisplay().size().ToString());
1564 // Switch back to extended desktop.
1565 display_manager()->SetUnifiedDesktopEnabled(false);
1566 EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString());
1567 EXPECT_EQ("400x500", ScreenUtil::GetSecondaryDisplay().size().ToString());
1570 TEST_F(DisplayManagerTest, UnifiedDesktopEnabledWithExtended) {
1571 if (!SupportsMultipleDisplays())
1572 return;
1573 // Don't check root window destruction in unified mode.
1574 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1576 UpdateDisplay("400x500,300x200");
1577 DisplayIdPair pair = display_manager()->GetCurrentDisplayIdPair();
1578 DisplayLayout layout =
1579 display_manager()->layout_store()->GetRegisteredDisplayLayout(pair);
1580 layout.default_unified = false;
1581 display_manager()->layout_store()->RegisterLayoutForDisplayIdPair(
1582 pair.first, pair.second, layout);
1583 display_manager()->SetUnifiedDesktopEnabled(true);
1584 EXPECT_FALSE(display_manager()->IsInUnifiedMode());
1587 TEST_F(DisplayManagerTest, UnifiedDesktopWith2xDSF) {
1588 if (!SupportsMultipleDisplays())
1589 return;
1590 // Don't check root window destruction in unified mode.
1591 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1593 display_manager()->SetUnifiedDesktopEnabled(true);
1594 gfx::Screen* screen =
1595 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
1597 // 2nd display is 2x.
1598 UpdateDisplay("400x500,1000x800*2");
1599 DisplayInfo info =
1600 display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
1601 EXPECT_EQ(2u, info.display_modes().size());
1602 EXPECT_EQ("1640x800", info.display_modes()[0].size.ToString());
1603 EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor);
1604 EXPECT_EQ("1025x500", info.display_modes()[1].size.ToString());
1605 EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor);
1607 // For 1x, 400 + 500 / 800 * 100 = 1025.
1608 EXPECT_EQ("1025x500", screen->GetPrimaryDisplay().size().ToString());
1609 EXPECT_EQ("1025x500",
1610 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1611 accelerators::ZoomInternalDisplay(false);
1612 // (800 / 500 * 400 + 500) /2 = 820
1613 EXPECT_EQ("820x400", screen->GetPrimaryDisplay().size().ToString());
1614 EXPECT_EQ("820x400",
1615 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1617 // 1st display is 2x.
1618 UpdateDisplay("1200x800*2,1000x1000");
1619 info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
1620 EXPECT_EQ(2u, info.display_modes().size());
1621 EXPECT_EQ("2000x800", info.display_modes()[0].size.ToString());
1622 EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor);
1623 EXPECT_EQ("2500x1000", info.display_modes()[1].size.ToString());
1624 EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor);
1626 // For 2x, (800 / 1000 * 1000 + 1200) / 2 = 1000
1627 EXPECT_EQ("1000x400", screen->GetPrimaryDisplay().size().ToString());
1628 EXPECT_EQ("1000x400",
1629 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1630 accelerators::ZoomInternalDisplay(true);
1631 // 1000 / 800 * 1200 + 1000 = 2500
1632 EXPECT_EQ("2500x1000", screen->GetPrimaryDisplay().size().ToString());
1633 EXPECT_EQ("2500x1000",
1634 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1636 // Both displays are 2x.
1637 // 1st display is 2x.
1638 UpdateDisplay("1200x800*2,1000x1000*2");
1639 info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
1640 EXPECT_EQ(2u, info.display_modes().size());
1641 EXPECT_EQ("2000x800", info.display_modes()[0].size.ToString());
1642 EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor);
1643 EXPECT_EQ("2500x1000", info.display_modes()[1].size.ToString());
1644 EXPECT_EQ(2.0f, info.display_modes()[1].device_scale_factor);
1646 EXPECT_EQ("1000x400", screen->GetPrimaryDisplay().size().ToString());
1647 EXPECT_EQ("1000x400",
1648 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1649 accelerators::ZoomInternalDisplay(true);
1650 EXPECT_EQ("1250x500", screen->GetPrimaryDisplay().size().ToString());
1651 EXPECT_EQ("1250x500",
1652 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1654 // Both displays have the same physical height, with the first display
1655 // being 2x.
1656 UpdateDisplay("1000x800*2,300x800");
1657 info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
1658 EXPECT_EQ(2u, info.display_modes().size());
1659 EXPECT_EQ("1300x800", info.display_modes()[0].size.ToString());
1660 EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor);
1661 EXPECT_EQ("1300x800", info.display_modes()[1].size.ToString());
1662 EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor);
1664 EXPECT_EQ("650x400", screen->GetPrimaryDisplay().size().ToString());
1665 EXPECT_EQ("650x400",
1666 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1667 accelerators::ZoomInternalDisplay(true);
1668 EXPECT_EQ("1300x800", screen->GetPrimaryDisplay().size().ToString());
1669 EXPECT_EQ("1300x800",
1670 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1672 // Both displays have the same physical height, with the second display
1673 // being 2x.
1674 UpdateDisplay("1000x800,300x800*2");
1675 EXPECT_EQ(2u, info.display_modes().size());
1676 EXPECT_EQ("1300x800", info.display_modes()[0].size.ToString());
1677 EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor);
1678 EXPECT_EQ("1300x800", info.display_modes()[1].size.ToString());
1679 EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor);
1681 EXPECT_EQ("1300x800", screen->GetPrimaryDisplay().size().ToString());
1682 EXPECT_EQ("1300x800",
1683 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1684 accelerators::ZoomInternalDisplay(false);
1685 EXPECT_EQ("650x400", screen->GetPrimaryDisplay().size().ToString());
1686 EXPECT_EQ("650x400",
1687 Shell::GetPrimaryRootWindow()->bounds().size().ToString());
1690 // Updating displays again in unified desktop mode should not crash.
1691 // crbug.com/491094.
1692 TEST_F(DisplayManagerTest, ConfigureUnifiedTwice) {
1693 if (!SupportsMultipleDisplays())
1694 return;
1695 // Don't check root window destruction in unified mode.
1696 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1698 UpdateDisplay("300x200,400x500");
1699 // Mirror windows are created in a posted task.
1700 RunAllPendingInMessageLoop();
1702 UpdateDisplay("300x250,400x550");
1703 RunAllPendingInMessageLoop();
1706 TEST_F(DisplayManagerTest, NoRotateUnifiedDesktop) {
1707 if (!SupportsMultipleDisplays())
1708 return;
1709 display_manager()->SetUnifiedDesktopEnabled(true);
1711 // Don't check root window destruction in unified mode.
1712 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1714 UpdateDisplay("400x500,300x200");
1716 gfx::Screen* screen =
1717 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
1718 const gfx::Display& display = screen->GetPrimaryDisplay();
1719 EXPECT_EQ("1150x500", display.size().ToString());
1720 display_manager()->SetDisplayRotation(display.id(), gfx::Display::ROTATE_90,
1721 gfx::Display::ROTATION_SOURCE_ACTIVE);
1722 EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());
1723 display_manager()->SetDisplayRotation(display.id(), gfx::Display::ROTATE_0,
1724 gfx::Display::ROTATION_SOURCE_ACTIVE);
1725 EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());
1727 UpdateDisplay("400x500");
1728 EXPECT_EQ("400x500", screen->GetPrimaryDisplay().size().ToString());
1731 // Makes sure the transition from unified to single won't crash
1732 // with docked windows.
1733 TEST_F(DisplayManagerTest, UnifiedWithDockWindows) {
1734 if (!SupportsMultipleDisplays())
1735 return;
1736 display_manager()->SetUnifiedDesktopEnabled(true);
1738 // Don't check root window destruction in unified mode.
1739 Shell::GetPrimaryRootWindow()->RemoveObserver(this);
1741 UpdateDisplay("400x500,300x200");
1743 scoped_ptr<aura::Window> docked(
1744 CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 50, 50)));
1745 docked->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_DOCKED);
1746 ASSERT_TRUE(wm::GetWindowState(docked.get())->IsDocked());
1747 // 47 pixels reserved for launcher shelf height.
1748 EXPECT_EQ("0,0 250x453", docked->bounds().ToString());
1749 UpdateDisplay("300x300");
1750 // Make sure the window is still docked.
1751 EXPECT_TRUE(wm::GetWindowState(docked.get())->IsDocked());
1752 EXPECT_EQ("0,0 250x253", docked->bounds().ToString());
1755 class ScreenShutdownTest : public test::AshTestBase {
1756 public:
1757 ScreenShutdownTest() {
1759 ~ScreenShutdownTest() override {}
1761 void TearDown() override {
1762 gfx::Screen* orig_screen =
1763 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
1764 AshTestBase::TearDown();
1765 if (!SupportsMultipleDisplays())
1766 return;
1767 gfx::Screen* screen =
1768 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
1769 EXPECT_NE(orig_screen, screen);
1770 EXPECT_EQ(2, screen->GetNumDisplays());
1771 EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString());
1772 std::vector<gfx::Display> all = screen->GetAllDisplays();
1773 EXPECT_EQ("500x300", all[0].size().ToString());
1774 EXPECT_EQ("800x400", all[1].size().ToString());
1777 private:
1778 DISALLOW_COPY_AND_ASSIGN(ScreenShutdownTest);
1781 TEST_F(ScreenShutdownTest, ScreenAfterShutdown) {
1782 if (!SupportsMultipleDisplays())
1783 return;
1784 UpdateDisplay("500x300,800x400");
1788 #if defined(OS_CHROMEOS)
1789 namespace {
1791 // A helper class that sets the display configuration and starts ash.
1792 // This is to make sure the font configuration happens during ash
1793 // initialization process.
1794 class FontTestHelper : public test::AshTestBase {
1795 public:
1796 enum DisplayType {
1797 INTERNAL,
1798 EXTERNAL
1801 FontTestHelper(float scale, DisplayType display_type) {
1802 gfx::ClearFontRenderParamsCacheForTest();
1803 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
1804 if (display_type == INTERNAL)
1805 command_line->AppendSwitch(switches::kAshUseFirstDisplayAsInternal);
1806 command_line->AppendSwitchASCII(switches::kAshHostWindowBounds,
1807 StringPrintf("1000x800*%f", scale));
1808 SetUp();
1811 ~FontTestHelper() override { TearDown(); }
1813 // test::AshTestBase:
1814 void TestBody() override { NOTREACHED(); }
1816 private:
1817 DISALLOW_COPY_AND_ASSIGN(FontTestHelper);
1821 bool IsTextSubpixelPositioningEnabled() {
1822 gfx::FontRenderParams params =
1823 gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL);
1824 return params.subpixel_positioning;
1827 gfx::FontRenderParams::Hinting GetFontHintingParams() {
1828 gfx::FontRenderParams params =
1829 gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL);
1830 return params.hinting;
1833 } // namespace
1835 typedef testing::Test DisplayManagerFontTest;
1837 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf100Internal) {
1838 FontTestHelper helper(1.0f, FontTestHelper::INTERNAL);
1839 ASSERT_DOUBLE_EQ(
1840 1.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1841 EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
1842 EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1845 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf125Internal) {
1846 test::ScopedDisable125DSFForUIScaling disable;
1847 FontTestHelper helper(1.25f, FontTestHelper::INTERNAL);
1848 ASSERT_DOUBLE_EQ(
1849 1.25f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1850 EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
1851 EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1854 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf200Internal) {
1855 FontTestHelper helper(2.0f, FontTestHelper::INTERNAL);
1856 ASSERT_DOUBLE_EQ(
1857 2.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1858 EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
1859 EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1861 SetDisplayUIScale(Shell::GetScreen()->GetPrimaryDisplay().id(), 2.0f);
1863 ASSERT_DOUBLE_EQ(
1864 1.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1865 EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
1866 EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1869 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf100External) {
1870 FontTestHelper helper(1.0f, FontTestHelper::EXTERNAL);
1871 ASSERT_DOUBLE_EQ(
1872 1.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1873 EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
1874 EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1877 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf125External) {
1878 FontTestHelper helper(1.25f, FontTestHelper::EXTERNAL);
1879 ASSERT_DOUBLE_EQ(
1880 1.25f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1881 EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
1882 EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1885 TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf200External) {
1886 FontTestHelper helper(2.0f, FontTestHelper::EXTERNAL);
1887 ASSERT_DOUBLE_EQ(
1888 2.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1889 EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
1890 EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1893 TEST_F(DisplayManagerFontTest,
1894 TextSubpixelPositioningWithDsf125InternalWithScaling) {
1895 FontTestHelper helper(1.25f, FontTestHelper::INTERNAL);
1896 ASSERT_DOUBLE_EQ(
1897 1.0f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1898 EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
1899 EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1901 SetDisplayUIScale(Shell::GetScreen()->GetPrimaryDisplay().id(), 0.8f);
1903 ASSERT_DOUBLE_EQ(
1904 1.25f, Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
1905 EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
1906 EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
1909 TEST_F(DisplayManagerTest, CheckInitializationOfRotationProperty) {
1910 int64_t id = display_manager()->GetDisplayAt(0).id();
1911 display_manager()->RegisterDisplayProperty(id, gfx::Display::ROTATE_90, 1.0f,
1912 nullptr, gfx::Size(), 1.0f,
1913 ui::COLOR_PROFILE_STANDARD);
1915 const DisplayInfo& info = display_manager()->GetDisplayInfo(id);
1917 EXPECT_EQ(gfx::Display::ROTATE_90,
1918 info.GetRotation(gfx::Display::ROTATION_SOURCE_USER));
1919 EXPECT_EQ(gfx::Display::ROTATE_90,
1920 info.GetRotation(gfx::Display::ROTATION_SOURCE_ACTIVE));
1923 #endif // OS_CHROMEOS
1925 } // namespace ash