Home | History | Annotate | Download | only in extensions
      1 // Copyright 2014 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 "extensions/browser/api/system_display/display_info_provider.h"
      6 
      7 #include "ash/display/display_controller.h"
      8 #include "ash/display/display_manager.h"
      9 #include "ash/screen_util.h"
     10 #include "ash/shell.h"
     11 #include "ash/test/ash_test_base.h"
     12 #include "ash/test/display_manager_test_api.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "extensions/common/api/system_display.h"
     16 #include "ui/gfx/display.h"
     17 #include "ui/gfx/rect.h"
     18 
     19 namespace extensions {
     20 namespace {
     21 
     22 class DisplayInfoProviderChromeosTest : public ash::test::AshTestBase {
     23  public:
     24   DisplayInfoProviderChromeosTest() {}
     25 
     26   virtual ~DisplayInfoProviderChromeosTest() {}
     27 
     28  protected:
     29   void CallSetDisplayUnitInfo(
     30       const std::string& display_id,
     31       const core_api::system_display::DisplayProperties& info,
     32       bool* success,
     33       std::string* error) {
     34     // Reset error messsage.
     35     (*error).clear();
     36     *success = DisplayInfoProvider::Get()->SetInfo(display_id, info, error);
     37   }
     38 
     39   bool DisplayExists(int64 display_id) const {
     40     const gfx::Display& display =
     41         GetDisplayManager()->GetDisplayForId(display_id);
     42     return display.id() != gfx::Display::kInvalidDisplayID;
     43   }
     44 
     45   ash::DisplayManager* GetDisplayManager() const {
     46     return ash::Shell::GetInstance()->display_manager();
     47   }
     48 
     49   ash::DisplayController* GetDisplayController() const {
     50     return ash::Shell::GetInstance()->display_controller();
     51   }
     52 
     53   std::string SystemInfoDisplayInsetsToString(
     54       const core_api::system_display::Insets& insets) const {
     55     // Order to match gfx::Insets::ToString().
     56     return base::StringPrintf(
     57         "%d,%d,%d,%d", insets.top, insets.left, insets.bottom, insets.right);
     58   }
     59 
     60   std::string SystemInfoDisplayBoundsToString(
     61       const core_api::system_display::Bounds& bounds) const {
     62     // Order to match gfx::Rect::ToString().
     63     return base::StringPrintf(
     64         "%d,%d %dx%d", bounds.left, bounds.top, bounds.width, bounds.height);
     65   }
     66 
     67  private:
     68   DISALLOW_COPY_AND_ASSIGN(DisplayInfoProviderChromeosTest);
     69 };
     70 
     71 TEST_F(DisplayInfoProviderChromeosTest, GetBasic) {
     72   UpdateDisplay("500x600,400x520");
     73   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
     74 
     75   ASSERT_EQ(2u, result.size());
     76 
     77   int64 display_id;
     78   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
     79       << "Display id must be convertable to integer: " << result[0]->id;
     80 
     81   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
     82   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
     83   EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0]->overscan));
     84   EXPECT_EQ(0, result[0]->rotation);
     85   EXPECT_TRUE(result[0]->is_primary);
     86   EXPECT_EQ(96, result[0]->dpi_x);
     87   EXPECT_EQ(96, result[0]->dpi_y);
     88   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
     89   EXPECT_TRUE(result[0]->is_enabled);
     90 
     91   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id))
     92       << "Display id must be convertable to integer: " << result[0]->id;
     93 
     94   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
     95   EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id),
     96             result[1]->name);
     97   // The second display is positioned left of the primary display, whose width
     98   // is 500.
     99   EXPECT_EQ("500,0 400x520",
    100             SystemInfoDisplayBoundsToString(result[1]->bounds));
    101   EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1]->overscan));
    102   EXPECT_EQ(0, result[1]->rotation);
    103   EXPECT_FALSE(result[1]->is_primary);
    104   EXPECT_EQ(96, result[1]->dpi_x);
    105   EXPECT_EQ(96, result[1]->dpi_y);
    106   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    107   EXPECT_TRUE(result[1]->is_enabled);
    108 }
    109 
    110 TEST_F(DisplayInfoProviderChromeosTest, GetRotation) {
    111   UpdateDisplay("500x600/r");
    112   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    113 
    114   ASSERT_EQ(1u, result.size());
    115 
    116   int64 display_id;
    117   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
    118       << "Display id must be convertable to integer: " << result[0]->id;
    119 
    120   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    121   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0]->bounds));
    122   EXPECT_EQ(90, result[0]->rotation);
    123 
    124   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_270);
    125 
    126   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    127 
    128   ASSERT_EQ(1u, result.size());
    129 
    130   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    131   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0]->bounds));
    132   EXPECT_EQ(270, result[0]->rotation);
    133 
    134   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_180);
    135 
    136   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    137 
    138   ASSERT_EQ(1u, result.size());
    139 
    140   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    141   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    142   EXPECT_EQ(180, result[0]->rotation);
    143 
    144   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_0);
    145 
    146   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    147 
    148   ASSERT_EQ(1u, result.size());
    149 
    150   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    151   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    152   EXPECT_EQ(0, result[0]->rotation);
    153 }
    154 
    155 TEST_F(DisplayInfoProviderChromeosTest, GetHiDPI) {
    156   UpdateDisplay("500x600,400x520*2");
    157   DisplayInfo result;
    158   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    159 
    160   ASSERT_EQ(2u, result.size());
    161 
    162   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    163   EXPECT_EQ(96, result[0]->dpi_x);
    164   EXPECT_EQ(96, result[0]->dpi_y);
    165 
    166   EXPECT_EQ("500,0 200x260",
    167             SystemInfoDisplayBoundsToString(result[1]->bounds));
    168   EXPECT_EQ(2 * 96, result[1]->dpi_x);
    169   EXPECT_EQ(2 * 96, result[1]->dpi_y);
    170 
    171   GetDisplayController()->SwapPrimaryDisplay();
    172 
    173   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    174 
    175   ASSERT_EQ(2u, result.size());
    176 
    177   EXPECT_EQ("-500,0 500x600",
    178             SystemInfoDisplayBoundsToString(result[0]->bounds));
    179   EXPECT_EQ(96, result[0]->dpi_x);
    180   EXPECT_EQ(96, result[0]->dpi_y);
    181 
    182   EXPECT_EQ("0,0 200x260", SystemInfoDisplayBoundsToString(result[1]->bounds));
    183   EXPECT_EQ(2 * 96, result[1]->dpi_x);
    184   EXPECT_EQ(2 * 96, result[1]->dpi_y);
    185 }
    186 
    187 TEST_F(DisplayInfoProviderChromeosTest, GetVisibleArea) {
    188   UpdateDisplay("640x720*2/o, 400x520/o");
    189   DisplayInfo result;
    190   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    191 
    192   ASSERT_EQ(2u, result.size());
    193 
    194   int64 display_id;
    195   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id))
    196       << "Display id must be convertable to integer: " << result[1]->id;
    197   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    198 
    199   // Default overscan is 5%.
    200   EXPECT_EQ("304,0 380x494",
    201             SystemInfoDisplayBoundsToString(result[1]->bounds));
    202   EXPECT_EQ("13,10,13,10",
    203             SystemInfoDisplayInsetsToString(result[1]->overscan));
    204 
    205   GetDisplayManager()->SetOverscanInsets(display_id,
    206                                          gfx::Insets(20, 30, 50, 60));
    207   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    208 
    209   ASSERT_EQ(2u, result.size());
    210 
    211   EXPECT_EQ(base::Int64ToString(display_id), result[1]->id);
    212   EXPECT_EQ("304,0 310x450",
    213             SystemInfoDisplayBoundsToString(result[1]->bounds));
    214   EXPECT_EQ("20,30,50,60",
    215             SystemInfoDisplayInsetsToString(result[1]->overscan));
    216 
    217   // Set insets for the primary screen. Note that it has 2x scale.
    218   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
    219       << "Display id must be convertable to integer: " << result[0]->id;
    220   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    221 
    222   EXPECT_EQ("0,0 304x342", SystemInfoDisplayBoundsToString(result[0]->bounds));
    223   EXPECT_EQ("9,8,9,8", SystemInfoDisplayInsetsToString(result[0]->overscan));
    224 
    225   GetDisplayManager()->SetOverscanInsets(display_id,
    226                                          gfx::Insets(10, 20, 30, 40));
    227   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    228 
    229   ASSERT_EQ(2u, result.size());
    230 
    231   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    232   EXPECT_EQ("0,0 260x320", SystemInfoDisplayBoundsToString(result[0]->bounds));
    233   EXPECT_EQ("10,20,30,40",
    234             SystemInfoDisplayInsetsToString(result[0]->overscan));
    235 }
    236 
    237 TEST_F(DisplayInfoProviderChromeosTest, GetMirroring) {
    238   UpdateDisplay("600x600, 400x520/o");
    239   DisplayInfo result;
    240   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    241 
    242   ASSERT_EQ(2u, result.size());
    243 
    244   int64 display_id_primary;
    245   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id_primary))
    246       << "Display id must be convertable to integer: " << result[0]->id;
    247   ASSERT_TRUE(DisplayExists(display_id_primary)) << display_id_primary
    248                                                  << " not found";
    249 
    250   int64 display_id_secondary;
    251   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id_secondary))
    252       << "Display id must be convertable to integer: " << result[1]->id;
    253   ASSERT_TRUE(DisplayExists(display_id_secondary)) << display_id_secondary
    254                                                    << " not found";
    255 
    256   ASSERT_FALSE(GetDisplayManager()->IsMirrored());
    257   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
    258   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    259 
    260   GetDisplayManager()->SetMirrorMode(true);
    261   ASSERT_TRUE(GetDisplayManager()->IsMirrored());
    262 
    263   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    264 
    265   ASSERT_EQ(1u, result.size());
    266   EXPECT_EQ(base::Int64ToString(display_id_primary), result[0]->id);
    267   EXPECT_EQ(base::Int64ToString(display_id_secondary),
    268             result[0]->mirroring_source_id);
    269 
    270   GetDisplayManager()->SetMirrorMode(false);
    271   ASSERT_FALSE(GetDisplayManager()->IsMirrored());
    272 
    273   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    274 
    275   ASSERT_EQ(2u, result.size());
    276   EXPECT_EQ(base::Int64ToString(display_id_primary), result[0]->id);
    277   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
    278   EXPECT_EQ(base::Int64ToString(display_id_secondary), result[1]->id);
    279   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    280 }
    281 
    282 TEST_F(DisplayInfoProviderChromeosTest, GetBounds) {
    283   UpdateDisplay("600x600, 400x520");
    284   GetDisplayManager()->SetLayoutForCurrentDisplays(
    285       ash::DisplayLayout::FromInts(ash::DisplayLayout::LEFT, -40));
    286 
    287   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    288 
    289   ASSERT_EQ(2u, result.size());
    290   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    291   EXPECT_EQ("-400,-40 400x520",
    292             SystemInfoDisplayBoundsToString(result[1]->bounds));
    293 
    294   GetDisplayManager()->SetLayoutForCurrentDisplays(
    295       ash::DisplayLayout::FromInts(ash::DisplayLayout::TOP, 40));
    296 
    297   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    298 
    299   ASSERT_EQ(2u, result.size());
    300   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    301   EXPECT_EQ("40,-520 400x520",
    302             SystemInfoDisplayBoundsToString(result[1]->bounds));
    303 
    304   GetDisplayManager()->SetLayoutForCurrentDisplays(
    305       ash::DisplayLayout::FromInts(ash::DisplayLayout::BOTTOM, 80));
    306 
    307   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    308   ASSERT_EQ(2u, result.size());
    309   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    310   EXPECT_EQ("80,600 400x520",
    311             SystemInfoDisplayBoundsToString(result[1]->bounds));
    312 }
    313 
    314 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftExact) {
    315   UpdateDisplay("1200x600,520x400");
    316 
    317   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    318   core_api::system_display::DisplayProperties info;
    319   info.bounds_origin_x.reset(new int(-520));
    320   info.bounds_origin_y.reset(new int(50));
    321 
    322   bool success = false;
    323   std::string error;
    324   CallSetDisplayUnitInfo(
    325       base::Int64ToString(secondary.id()), info, &success, &error);
    326 
    327   ASSERT_TRUE(success);
    328   ASSERT_TRUE(error.empty());
    329 
    330   EXPECT_EQ("-520,50 520x400", secondary.bounds().ToString());
    331 }
    332 
    333 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightExact) {
    334   UpdateDisplay("1200x600,520x400");
    335 
    336   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    337   core_api::system_display::DisplayProperties info;
    338   info.bounds_origin_x.reset(new int(1200));
    339   info.bounds_origin_y.reset(new int(100));
    340 
    341   bool success = false;
    342   std::string error;
    343   CallSetDisplayUnitInfo(
    344       base::Int64ToString(secondary.id()), info, &success, &error);
    345 
    346   ASSERT_TRUE(success);
    347   ASSERT_TRUE(error.empty());
    348 
    349   EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
    350 }
    351 
    352 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopExact) {
    353   UpdateDisplay("1200x600,520x400");
    354 
    355   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    356   core_api::system_display::DisplayProperties info;
    357   info.bounds_origin_x.reset(new int(1100));
    358   info.bounds_origin_y.reset(new int(-400));
    359 
    360   bool success = false;
    361   std::string error;
    362   CallSetDisplayUnitInfo(
    363       base::Int64ToString(secondary.id()), info, &success, &error);
    364 
    365   ASSERT_TRUE(success);
    366   ASSERT_TRUE(error.empty());
    367 
    368   EXPECT_EQ("1100,-400 520x400", secondary.bounds().ToString());
    369 }
    370 
    371 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginBottomExact) {
    372   UpdateDisplay("1200x600,520x400");
    373 
    374   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    375   core_api::system_display::DisplayProperties info;
    376   info.bounds_origin_x.reset(new int(-350));
    377   info.bounds_origin_y.reset(new int(600));
    378 
    379   bool success = false;
    380   std::string error;
    381   CallSetDisplayUnitInfo(
    382       base::Int64ToString(secondary.id()), info, &success, &error);
    383 
    384   ASSERT_TRUE(success);
    385   ASSERT_TRUE(error.empty());
    386 
    387   EXPECT_EQ("-350,600 520x400", secondary.bounds().ToString());
    388 }
    389 
    390 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSameCenter) {
    391   UpdateDisplay("1200x600,520x400");
    392 
    393   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    394   core_api::system_display::DisplayProperties info;
    395   info.bounds_origin_x.reset(new int(340));
    396   info.bounds_origin_y.reset(new int(100));
    397 
    398   bool success = false;
    399   std::string error;
    400   CallSetDisplayUnitInfo(
    401       base::Int64ToString(secondary.id()), info, &success, &error);
    402 
    403   ASSERT_TRUE(success);
    404   ASSERT_TRUE(error.empty());
    405 
    406   EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
    407 }
    408 
    409 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftOutside) {
    410   UpdateDisplay("1200x600,520x400");
    411 
    412   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    413   core_api::system_display::DisplayProperties info;
    414   info.bounds_origin_x.reset(new int(-1040));
    415   info.bounds_origin_y.reset(new int(100));
    416 
    417   bool success = false;
    418   std::string error;
    419   CallSetDisplayUnitInfo(
    420       base::Int64ToString(secondary.id()), info, &success, &error);
    421 
    422   ASSERT_TRUE(success);
    423   ASSERT_TRUE(error.empty());
    424 
    425   EXPECT_EQ("-520,100 520x400", secondary.bounds().ToString());
    426 }
    427 
    428 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopOutside) {
    429   UpdateDisplay("1200x600,520x400");
    430 
    431   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    432   core_api::system_display::DisplayProperties info;
    433   info.bounds_origin_x.reset(new int(-360));
    434   info.bounds_origin_y.reset(new int(-301));
    435 
    436   bool success = false;
    437   std::string error;
    438   CallSetDisplayUnitInfo(
    439       base::Int64ToString(secondary.id()), info, &success, &error);
    440 
    441   ASSERT_TRUE(success);
    442   ASSERT_TRUE(error.empty());
    443 
    444   EXPECT_EQ("-360,-400 520x400", secondary.bounds().ToString());
    445 }
    446 
    447 TEST_F(DisplayInfoProviderChromeosTest,
    448        SetBoundsOriginLeftButSharesBottomSide) {
    449   UpdateDisplay("1200x600,1000x100");
    450 
    451   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    452   core_api::system_display::DisplayProperties info;
    453   info.bounds_origin_x.reset(new int(-650));
    454   info.bounds_origin_y.reset(new int(700));
    455 
    456   bool success = false;
    457   std::string error;
    458   CallSetDisplayUnitInfo(
    459       base::Int64ToString(secondary.id()), info, &success, &error);
    460 
    461   ASSERT_TRUE(success);
    462   ASSERT_TRUE(error.empty());
    463 
    464   EXPECT_EQ("-650,600 1000x100", secondary.bounds().ToString());
    465 }
    466 
    467 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightButSharesTopSide) {
    468   UpdateDisplay("1200x600,1000x100");
    469 
    470   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    471   core_api::system_display::DisplayProperties info;
    472   info.bounds_origin_x.reset(new int(850));
    473   info.bounds_origin_y.reset(new int(-150));
    474 
    475   bool success = false;
    476   std::string error;
    477   CallSetDisplayUnitInfo(
    478       base::Int64ToString(secondary.id()), info, &success, &error);
    479 
    480   ASSERT_TRUE(success);
    481   ASSERT_TRUE(error.empty());
    482 
    483   EXPECT_EQ("850,-100 1000x100", secondary.bounds().ToString());
    484 }
    485 
    486 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopButSharesLeftSide) {
    487   UpdateDisplay("1200x600,1000x100/l");
    488 
    489   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    490   core_api::system_display::DisplayProperties info;
    491   info.bounds_origin_x.reset(new int(-150));
    492   info.bounds_origin_y.reset(new int(-650));
    493 
    494   bool success = false;
    495   std::string error;
    496   CallSetDisplayUnitInfo(
    497       base::Int64ToString(secondary.id()), info, &success, &error);
    498 
    499   ASSERT_TRUE(success);
    500   ASSERT_TRUE(error.empty());
    501 
    502   EXPECT_EQ("-100,-650 100x1000", secondary.bounds().ToString());
    503 }
    504 
    505 TEST_F(DisplayInfoProviderChromeosTest,
    506        SetBoundsOriginBottomButSharesRightSide) {
    507   UpdateDisplay("1200x600,1000x100/l");
    508 
    509   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    510   core_api::system_display::DisplayProperties info;
    511   info.bounds_origin_x.reset(new int(1350));
    512   info.bounds_origin_y.reset(new int(450));
    513 
    514   bool success = false;
    515   std::string error;
    516   CallSetDisplayUnitInfo(
    517       base::Int64ToString(secondary.id()), info, &success, &error);
    518 
    519   ASSERT_TRUE(success);
    520   ASSERT_TRUE(error.empty());
    521 
    522   EXPECT_EQ("1200,450 100x1000", secondary.bounds().ToString());
    523 }
    524 
    525 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginPrimaryHiDPI) {
    526   UpdateDisplay("1200x600*2,500x500");
    527 
    528   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    529   core_api::system_display::DisplayProperties info;
    530   info.bounds_origin_x.reset(new int(250));
    531   info.bounds_origin_y.reset(new int(-100));
    532 
    533   bool success = false;
    534   std::string error;
    535   CallSetDisplayUnitInfo(
    536       base::Int64ToString(secondary.id()), info, &success, &error);
    537 
    538   ASSERT_TRUE(success);
    539   ASSERT_TRUE(error.empty());
    540 
    541   EXPECT_EQ("600,-100 500x500", secondary.bounds().ToString());
    542 }
    543 
    544 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSecondaryHiDPI) {
    545   UpdateDisplay("1200x600,600x1000*2");
    546 
    547   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    548   core_api::system_display::DisplayProperties info;
    549   info.bounds_origin_x.reset(new int(450));
    550   info.bounds_origin_y.reset(new int(-100));
    551 
    552   bool success = false;
    553   std::string error;
    554   CallSetDisplayUnitInfo(
    555       base::Int64ToString(secondary.id()), info, &success, &error);
    556 
    557   ASSERT_TRUE(success);
    558   ASSERT_TRUE(error.empty());
    559 
    560   EXPECT_EQ("450,-500 300x500", secondary.bounds().ToString());
    561 }
    562 
    563 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBounds) {
    564   UpdateDisplay("1200x600,600x1000*2");
    565 
    566   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    567   core_api::system_display::DisplayProperties info;
    568   info.bounds_origin_x.reset(new int(0x200001));
    569   info.bounds_origin_y.reset(new int(-100));
    570 
    571   bool success = false;
    572   std::string error;
    573   CallSetDisplayUnitInfo(
    574       base::Int64ToString(secondary.id()), info, &success, &error);
    575 
    576   ASSERT_FALSE(success);
    577   ASSERT_EQ("Bounds origin x out of bounds.", error);
    578 
    579   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    580 }
    581 
    582 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBoundsNegative) {
    583   UpdateDisplay("1200x600,600x1000*2");
    584 
    585   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    586   core_api::system_display::DisplayProperties info;
    587   info.bounds_origin_x.reset(new int(300));
    588   info.bounds_origin_y.reset(new int(-0x200001));
    589 
    590   bool success = false;
    591   std::string error;
    592   CallSetDisplayUnitInfo(
    593       base::Int64ToString(secondary.id()), info, &success, &error);
    594 
    595   ASSERT_FALSE(success);
    596   ASSERT_EQ("Bounds origin y out of bounds.", error);
    597 
    598   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    599 }
    600 
    601 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginMaxValues) {
    602   UpdateDisplay("1200x4600,600x1000*2");
    603 
    604   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    605   core_api::system_display::DisplayProperties info;
    606   info.bounds_origin_x.reset(new int(200000));
    607   info.bounds_origin_y.reset(new int(10));
    608 
    609   bool success = false;
    610   std::string error;
    611   CallSetDisplayUnitInfo(
    612       base::Int64ToString(secondary.id()), info, &success, &error);
    613 
    614   ASSERT_TRUE(success);
    615   EXPECT_TRUE(error.empty());
    616 
    617   EXPECT_EQ("1200,10 300x500", secondary.bounds().ToString());
    618 }
    619 
    620 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOnPrimary) {
    621   UpdateDisplay("1200x600,600x1000*2");
    622 
    623   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    624   core_api::system_display::DisplayProperties info;
    625   info.bounds_origin_x.reset(new int(300));
    626   info.is_primary.reset(new bool(true));
    627 
    628   bool success = false;
    629   std::string error;
    630   CallSetDisplayUnitInfo(
    631       base::Int64ToString(secondary.id()), info, &success, &error);
    632 
    633   ASSERT_FALSE(success);
    634   ASSERT_EQ("Bounds origin not allowed for the primary display.", error);
    635 
    636   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    637   // The operation failed because the primary property would be set before
    638   // setting bounds. The primary display shouldn't have been changed, though.
    639   EXPECT_NE(ash::Shell::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
    640 }
    641 
    642 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginWithMirroring) {
    643   UpdateDisplay("1200x600,600x1000*2");
    644 
    645   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    646   const gfx::Display& primary = ash::Shell::GetScreen()->GetPrimaryDisplay();
    647 
    648   core_api::system_display::DisplayProperties info;
    649   info.bounds_origin_x.reset(new int(300));
    650   info.mirroring_source_id.reset(
    651       new std::string(base::Int64ToString(primary.id())));
    652 
    653   bool success = false;
    654   std::string error;
    655   CallSetDisplayUnitInfo(
    656       base::Int64ToString(secondary.id()), info, &success, &error);
    657 
    658   ASSERT_FALSE(success);
    659   ASSERT_EQ("No other parameter should be set alongside mirroringSourceId.",
    660             error);
    661 }
    662 
    663 TEST_F(DisplayInfoProviderChromeosTest, SetRotation) {
    664   UpdateDisplay("1200x600,600x1000*2");
    665 
    666   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    667   core_api::system_display::DisplayProperties info;
    668   info.rotation.reset(new int(90));
    669 
    670   bool success = false;
    671   std::string error;
    672   CallSetDisplayUnitInfo(
    673       base::Int64ToString(secondary.id()), info, &success, &error);
    674 
    675   ASSERT_TRUE(success);
    676   EXPECT_TRUE(error.empty());
    677 
    678   EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
    679   EXPECT_EQ(gfx::Display::ROTATE_90, secondary.rotation());
    680 
    681   info.rotation.reset(new int(270));
    682   CallSetDisplayUnitInfo(
    683       base::Int64ToString(secondary.id()), info, &success, &error);
    684 
    685   ASSERT_TRUE(success);
    686   EXPECT_TRUE(error.empty());
    687 
    688   EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
    689   EXPECT_EQ(gfx::Display::ROTATE_270, secondary.rotation());
    690 
    691   info.rotation.reset(new int(180));
    692   // Switch primary display.
    693   info.is_primary.reset(new bool(true));
    694   CallSetDisplayUnitInfo(
    695       base::Int64ToString(secondary.id()), info, &success, &error);
    696 
    697   ASSERT_TRUE(success);
    698   EXPECT_TRUE(error.empty());
    699 
    700   EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
    701   EXPECT_EQ(gfx::Display::ROTATE_180, secondary.rotation());
    702   EXPECT_EQ(ash::Shell::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
    703 
    704   info.rotation.reset(new int(0));
    705   CallSetDisplayUnitInfo(
    706       base::Int64ToString(secondary.id()), info, &success, &error);
    707 
    708   ASSERT_TRUE(success);
    709   EXPECT_TRUE(error.empty());
    710 
    711   EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
    712   EXPECT_EQ(gfx::Display::ROTATE_0, secondary.rotation());
    713   EXPECT_EQ(ash::Shell::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
    714 }
    715 
    716 TEST_F(DisplayInfoProviderChromeosTest, SetInvalidRotation) {
    717   UpdateDisplay("1200x600,600x1000*2");
    718 
    719   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    720   core_api::system_display::DisplayProperties info;
    721   info.rotation.reset(new int(91));
    722 
    723   bool success = false;
    724   std::string error;
    725   CallSetDisplayUnitInfo(
    726       base::Int64ToString(secondary.id()), info, &success, &error);
    727 
    728   ASSERT_FALSE(success);
    729   EXPECT_EQ("Invalid rotation.", error);
    730 }
    731 
    732 TEST_F(DisplayInfoProviderChromeosTest, SetNegativeOverscan) {
    733   UpdateDisplay("1200x600,600x1000*2");
    734 
    735   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    736   core_api::system_display::DisplayProperties info;
    737   info.overscan.reset(new core_api::system_display::Insets);
    738   info.overscan->left = -10;
    739 
    740   bool success = false;
    741   std::string error;
    742   CallSetDisplayUnitInfo(
    743       base::Int64ToString(secondary.id()), info, &success, &error);
    744 
    745   ASSERT_FALSE(success);
    746   EXPECT_EQ("Negative overscan not allowed.", error);
    747 
    748   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    749 
    750   info.overscan->left = 0;
    751   info.overscan->right = -200;
    752 
    753   CallSetDisplayUnitInfo(
    754       base::Int64ToString(secondary.id()), info, &success, &error);
    755 
    756   ASSERT_FALSE(success);
    757   EXPECT_EQ("Negative overscan not allowed.", error);
    758 
    759   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    760 
    761   info.overscan->right = 0;
    762   info.overscan->top = -300;
    763 
    764   CallSetDisplayUnitInfo(
    765       base::Int64ToString(secondary.id()), info, &success, &error);
    766 
    767   ASSERT_FALSE(success);
    768   EXPECT_EQ("Negative overscan not allowed.", error);
    769 
    770   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    771 
    772   info.overscan->right = 0;
    773   info.overscan->top = -1000;
    774 
    775   CallSetDisplayUnitInfo(
    776       base::Int64ToString(secondary.id()), info, &success, &error);
    777 
    778   ASSERT_FALSE(success);
    779   EXPECT_EQ("Negative overscan not allowed.", error);
    780 
    781   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    782 
    783   info.overscan->right = 0;
    784   info.overscan->top = 0;
    785 
    786   CallSetDisplayUnitInfo(
    787       base::Int64ToString(secondary.id()), info, &success, &error);
    788 
    789   ASSERT_TRUE(success);
    790   EXPECT_TRUE(error.empty());
    791 
    792   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
    793 }
    794 
    795 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanHorizontalBounds) {
    796   UpdateDisplay("1200x600,600x1000*2");
    797 
    798   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    799   core_api::system_display::DisplayProperties info;
    800   info.overscan.reset(new core_api::system_display::Insets);
    801   // Horizontal overscan is 151, which would make the bounds width 149.
    802   info.overscan->left = 50;
    803   info.overscan->top = 10;
    804   info.overscan->right = 101;
    805   info.overscan->bottom = 20;
    806 
    807   bool success = false;
    808   std::string error;
    809   CallSetDisplayUnitInfo(
    810       base::Int64ToString(secondary.id()), info, &success, &error);
    811 
    812   ASSERT_FALSE(success);
    813   EXPECT_EQ("Horizontal overscan is more than half of the screen width.",
    814             error);
    815 }
    816 
    817 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanVerticalBounds) {
    818   UpdateDisplay("1200x600,600x1000");
    819 
    820   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    821   core_api::system_display::DisplayProperties info;
    822   info.overscan.reset(new core_api::system_display::Insets);
    823   // Vertical overscan is 501, which would make the bounds height 499.
    824   info.overscan->left = 20;
    825   info.overscan->top = 250;
    826   info.overscan->right = 101;
    827   info.overscan->bottom = 251;
    828 
    829   bool success = false;
    830   std::string error;
    831   CallSetDisplayUnitInfo(
    832       base::Int64ToString(secondary.id()), info, &success, &error);
    833 
    834   ASSERT_FALSE(success);
    835   EXPECT_EQ("Vertical overscan is more than half of the screen height.", error);
    836 }
    837 
    838 TEST_F(DisplayInfoProviderChromeosTest, SetOverscan) {
    839   UpdateDisplay("1200x600,600x1000*2");
    840 
    841   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    842   core_api::system_display::DisplayProperties info;
    843   info.overscan.reset(new core_api::system_display::Insets);
    844   info.overscan->left = 20;
    845   info.overscan->top = 199;
    846   info.overscan->right = 130;
    847   info.overscan->bottom = 51;
    848 
    849   bool success = false;
    850   std::string error;
    851   CallSetDisplayUnitInfo(
    852       base::Int64ToString(secondary.id()), info, &success, &error);
    853 
    854   ASSERT_TRUE(success);
    855   EXPECT_TRUE(error.empty());
    856 
    857   EXPECT_EQ("1200,0 150x250", secondary.bounds().ToString());
    858   const gfx::Insets overscan =
    859       GetDisplayManager()->GetOverscanInsets(secondary.id());
    860 
    861   EXPECT_EQ(20, overscan.left());
    862   EXPECT_EQ(199, overscan.top());
    863   EXPECT_EQ(130, overscan.right());
    864   EXPECT_EQ(51, overscan.bottom());
    865 }
    866 
    867 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanForInternal) {
    868   UpdateDisplay("1200x600,600x1000*2");
    869   const int64 internal_display_id =
    870       ash::test::DisplayManagerTestApi(GetDisplayManager())
    871           .SetFirstDisplayAsInternalDisplay();
    872 
    873   core_api::system_display::DisplayProperties info;
    874   info.overscan.reset(new core_api::system_display::Insets);
    875   // Vertical overscan is 501, which would make the bounds height 499.
    876   info.overscan->left = 20;
    877   info.overscan->top = 20;
    878   info.overscan->right = 20;
    879   info.overscan->bottom = 20;
    880 
    881   bool success = false;
    882   std::string error;
    883   CallSetDisplayUnitInfo(
    884       base::Int64ToString(internal_display_id), info, &success, &error);
    885 
    886   ASSERT_FALSE(success);
    887   EXPECT_EQ("Overscan changes not allowed for the internal monitor.", error);
    888 }
    889 
    890 }  // namespace
    891 }  // namespace extensions
    892