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