Home | History | Annotate | Download | only in system_display
      1 // Copyright 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 "chrome/browser/extensions/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 "ui/gfx/display.h"
     16 #include "ui/gfx/rect.h"
     17 
     18 namespace extensions {
     19 namespace {
     20 
     21 class DisplayInfoProviderChromeosTest : public ash::test::AshTestBase {
     22  public:
     23   DisplayInfoProviderChromeosTest() {}
     24 
     25   virtual ~DisplayInfoProviderChromeosTest() {}
     26 
     27  protected:
     28   void CallSetDisplayUnitInfo(
     29       const std::string& display_id,
     30       const api::system_display::DisplayProperties& info,
     31       bool* success,
     32       std::string* error) {
     33     // Reset error messsage.
     34     (*error).clear();
     35     *success = DisplayInfoProvider::Get()->SetInfo(display_id, info, error);
     36   }
     37 
     38   bool DisplayExists(int64 display_id) const {
     39     const gfx::Display& display =
     40         GetDisplayManager()->GetDisplayForId(display_id);
     41     return display.id() != gfx::Display::kInvalidDisplayID;
     42   }
     43 
     44   ash::DisplayManager* GetDisplayManager() const {
     45     return ash::Shell::GetInstance()->display_manager();
     46   }
     47 
     48   ash::DisplayController* GetDisplayController() const {
     49     return ash::Shell::GetInstance()->display_controller();
     50   }
     51 
     52   std::string SystemInfoDisplayInsetsToString(
     53       const api::system_display::Insets& insets) const {
     54     // Order to match gfx::Insets::ToString().
     55     return base::StringPrintf("%d,%d,%d,%d",
     56         insets.top,  insets.left, insets.bottom, insets.right);
     57   }
     58 
     59   std::string SystemInfoDisplayBoundsToString(
     60       const api::system_display::Bounds& bounds) const {
     61     // Order to match gfx::Rect::ToString().
     62     return base::StringPrintf("%d,%d %dx%d",
     63         bounds.left,  bounds.top, bounds.width, bounds.height);
     64   }
     65 
     66   DISALLOW_COPY_AND_ASSIGN(DisplayInfoProviderChromeosTest);
     67 };
     68 
     69 TEST_F(DisplayInfoProviderChromeosTest, GetBasic) {
     70   UpdateDisplay("500x600,400x520");
     71   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
     72 
     73   ASSERT_EQ(2u, result.size());
     74 
     75   int64 display_id;
     76   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
     77       << "Display id must be convertable to integer: " << result[0]->id;
     78 
     79   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
     80   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
     81   EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0]->overscan));
     82   EXPECT_EQ(0, result[0]->rotation);
     83   EXPECT_TRUE(result[0]->is_primary);
     84   EXPECT_EQ(96, result[0]->dpi_x);
     85   EXPECT_EQ(96, result[0]->dpi_y);
     86   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
     87   EXPECT_TRUE(result[0]->is_enabled);
     88 
     89   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id))
     90       << "Display id must be convertable to integer: " << result[0]->id;
     91 
     92   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
     93   EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id),
     94             result[1]->name);
     95   // The second display is positioned left of the primary display, whose width
     96   // is 500.
     97   EXPECT_EQ("500,0 400x520",
     98             SystemInfoDisplayBoundsToString(result[1]->bounds));
     99   EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1]->overscan));
    100   EXPECT_EQ(0, result[1]->rotation);
    101   EXPECT_FALSE(result[1]->is_primary);
    102   EXPECT_EQ(96, result[1]->dpi_x);
    103   EXPECT_EQ(96, result[1]->dpi_y);
    104   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    105   EXPECT_TRUE(result[1]->is_enabled);
    106 }
    107 
    108 TEST_F(DisplayInfoProviderChromeosTest, GetRotation) {
    109   UpdateDisplay("500x600/r");
    110   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    111 
    112   ASSERT_EQ(1u, result.size());
    113 
    114   int64 display_id;
    115   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
    116       << "Display id must be convertable to integer: " << result[0]->id;
    117 
    118   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    119   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0]->bounds));
    120   EXPECT_EQ(90, result[0]->rotation);
    121 
    122   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_270);
    123 
    124   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    125 
    126   ASSERT_EQ(1u, result.size());
    127 
    128   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    129   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0]->bounds));
    130   EXPECT_EQ(270, result[0]->rotation);
    131 
    132   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_180);
    133 
    134   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    135 
    136   ASSERT_EQ(1u, result.size());
    137 
    138   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    139   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    140   EXPECT_EQ(180, result[0]->rotation);
    141 
    142   GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_0);
    143 
    144   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    145 
    146   ASSERT_EQ(1u, result.size());
    147 
    148   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    149   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    150   EXPECT_EQ(0, result[0]->rotation);
    151 }
    152 
    153 TEST_F(DisplayInfoProviderChromeosTest, GetHiDPI) {
    154   UpdateDisplay("500x600,400x520*2");
    155   DisplayInfo result;
    156   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    157 
    158   ASSERT_EQ(2u, result.size());
    159 
    160   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    161   EXPECT_EQ(96, result[0]->dpi_x);
    162   EXPECT_EQ(96, result[0]->dpi_y);
    163 
    164   EXPECT_EQ("500,0 200x260",
    165             SystemInfoDisplayBoundsToString(result[1]->bounds));
    166   EXPECT_EQ(2 * 96, result[1]->dpi_x);
    167   EXPECT_EQ(2 * 96, result[1]->dpi_y);
    168 
    169   GetDisplayController()->SwapPrimaryDisplay();
    170 
    171   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    172 
    173   ASSERT_EQ(2u, result.size());
    174 
    175   EXPECT_EQ("-500,0 500x600",
    176             SystemInfoDisplayBoundsToString(result[0]->bounds));
    177   EXPECT_EQ(96, result[0]->dpi_x);
    178   EXPECT_EQ(96, result[0]->dpi_y);
    179 
    180   EXPECT_EQ("0,0 200x260", SystemInfoDisplayBoundsToString(result[1]->bounds));
    181   EXPECT_EQ(2 * 96, result[1]->dpi_x);
    182   EXPECT_EQ(2 * 96, result[1]->dpi_y);
    183 }
    184 
    185 TEST_F(DisplayInfoProviderChromeosTest, GetVisibleArea) {
    186   UpdateDisplay("640x720*2/o, 400x520/o");
    187   DisplayInfo result;
    188   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    189 
    190   ASSERT_EQ(2u, result.size());
    191 
    192   int64 display_id;
    193   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id))
    194       << "Display id must be convertable to integer: " << result[1]->id;
    195   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    196 
    197   // Default overscan is 5%.
    198   EXPECT_EQ("304,0 380x494",
    199             SystemInfoDisplayBoundsToString(result[1]->bounds));
    200   EXPECT_EQ("13,10,13,10",
    201             SystemInfoDisplayInsetsToString(result[1]->overscan));
    202 
    203   GetDisplayManager()->SetOverscanInsets(display_id,
    204                                          gfx::Insets(20, 30, 50, 60));
    205   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    206 
    207   ASSERT_EQ(2u, result.size());
    208 
    209   EXPECT_EQ(base::Int64ToString(display_id), result[1]->id);
    210   EXPECT_EQ("304,0 310x450",
    211             SystemInfoDisplayBoundsToString(result[1]->bounds));
    212   EXPECT_EQ("20,30,50,60",
    213             SystemInfoDisplayInsetsToString(result[1]->overscan));
    214 
    215   // Set insets for the primary screen. Note that it has 2x scale.
    216   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id))
    217       << "Display id must be convertable to integer: " << result[0]->id;
    218   ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found";
    219 
    220   EXPECT_EQ("0,0 304x342", SystemInfoDisplayBoundsToString(result[0]->bounds));
    221   EXPECT_EQ("9,8,9,8", SystemInfoDisplayInsetsToString(result[0]->overscan));
    222 
    223   GetDisplayManager()->SetOverscanInsets(display_id,
    224                                          gfx::Insets(10, 20, 30, 40));
    225   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    226 
    227   ASSERT_EQ(2u, result.size());
    228 
    229   EXPECT_EQ(base::Int64ToString(display_id), result[0]->id);
    230   EXPECT_EQ("0,0 260x320", SystemInfoDisplayBoundsToString(result[0]->bounds));
    231   EXPECT_EQ("10,20,30,40",
    232             SystemInfoDisplayInsetsToString(result[0]->overscan));
    233 }
    234 
    235 TEST_F(DisplayInfoProviderChromeosTest, GetMirroring) {
    236   UpdateDisplay("600x600, 400x520/o");
    237   DisplayInfo result;
    238   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    239 
    240   ASSERT_EQ(2u, result.size());
    241 
    242   int64 display_id_primary;
    243   ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id_primary))
    244       << "Display id must be convertable to integer: " << result[0]->id;
    245   ASSERT_TRUE(DisplayExists(display_id_primary))
    246       << display_id_primary << " not found";
    247 
    248   int64 display_id_secondary;
    249   ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id_secondary))
    250       << "Display id must be convertable to integer: " << result[1]->id;
    251   ASSERT_TRUE(DisplayExists(display_id_secondary))
    252       << display_id_secondary << " not found";
    253 
    254   ASSERT_FALSE(GetDisplayManager()->IsMirrored());
    255   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
    256   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    257 
    258   GetDisplayManager()->SetMirrorMode(true);
    259   ASSERT_TRUE(GetDisplayManager()->IsMirrored());
    260 
    261   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    262 
    263   ASSERT_EQ(1u, result.size());
    264   EXPECT_EQ(base::Int64ToString(display_id_primary), result[0]->id);
    265   EXPECT_EQ(base::Int64ToString(display_id_secondary),
    266             result[0]->mirroring_source_id);
    267 
    268   GetDisplayManager()->SetMirrorMode(false);
    269   ASSERT_FALSE(GetDisplayManager()->IsMirrored());
    270 
    271   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    272 
    273   ASSERT_EQ(2u, result.size());
    274   EXPECT_EQ(base::Int64ToString(display_id_primary), result[0]->id);
    275   EXPECT_TRUE(result[0]->mirroring_source_id.empty());
    276   EXPECT_EQ(base::Int64ToString(display_id_secondary), result[1]->id);
    277   EXPECT_TRUE(result[1]->mirroring_source_id.empty());
    278 }
    279 
    280 TEST_F(DisplayInfoProviderChromeosTest, GetBounds) {
    281   UpdateDisplay("600x600, 400x520");
    282   GetDisplayManager()->SetLayoutForCurrentDisplays(
    283       ash::DisplayLayout::FromInts(ash::DisplayLayout::LEFT, -40));
    284 
    285   DisplayInfo result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    286 
    287   ASSERT_EQ(2u, result.size());
    288   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    289   EXPECT_EQ("-400,-40 400x520",
    290             SystemInfoDisplayBoundsToString(result[1]->bounds));
    291 
    292   GetDisplayManager()->SetLayoutForCurrentDisplays(
    293       ash::DisplayLayout::FromInts(ash::DisplayLayout::TOP, 40));
    294 
    295   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    296 
    297   ASSERT_EQ(2u, result.size());
    298   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    299   EXPECT_EQ("40,-520 400x520",
    300             SystemInfoDisplayBoundsToString(result[1]->bounds));
    301 
    302   GetDisplayManager()->SetLayoutForCurrentDisplays(
    303       ash::DisplayLayout::FromInts(ash::DisplayLayout::BOTTOM, 80));
    304 
    305   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
    306   ASSERT_EQ(2u, result.size());
    307   EXPECT_EQ("0,0 600x600", SystemInfoDisplayBoundsToString(result[0]->bounds));
    308   EXPECT_EQ("80,600 400x520",
    309             SystemInfoDisplayBoundsToString(result[1]->bounds));
    310 }
    311 
    312 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftExact) {
    313   UpdateDisplay("1200x600,520x400");
    314 
    315   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    316   api::system_display::DisplayProperties info;
    317   info.bounds_origin_x.reset(new int(-520));
    318   info.bounds_origin_y.reset(new int(50));
    319 
    320   bool success = false;
    321   std::string error;
    322   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    323       &success, &error);
    324 
    325   ASSERT_TRUE(success);
    326   ASSERT_TRUE(error.empty());
    327 
    328   EXPECT_EQ("-520,50 520x400", secondary.bounds().ToString());
    329 }
    330 
    331 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightExact) {
    332   UpdateDisplay("1200x600,520x400");
    333 
    334   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    335   api::system_display::DisplayProperties info;
    336   info.bounds_origin_x.reset(new int(1200));
    337   info.bounds_origin_y.reset(new int(100));
    338 
    339   bool success = false;
    340   std::string error;
    341   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    342       &success, &error);
    343 
    344   ASSERT_TRUE(success);
    345   ASSERT_TRUE(error.empty());
    346 
    347   EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
    348 }
    349 
    350 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopExact) {
    351   UpdateDisplay("1200x600,520x400");
    352 
    353   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    354   api::system_display::DisplayProperties info;
    355   info.bounds_origin_x.reset(new int(1100));
    356   info.bounds_origin_y.reset(new int(-400));
    357 
    358   bool success = false;
    359   std::string error;
    360   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    361       &success, &error);
    362 
    363   ASSERT_TRUE(success);
    364   ASSERT_TRUE(error.empty());
    365 
    366   EXPECT_EQ("1100,-400 520x400", secondary.bounds().ToString());
    367 }
    368 
    369 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginBottomExact) {
    370   UpdateDisplay("1200x600,520x400");
    371 
    372   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    373   api::system_display::DisplayProperties info;
    374   info.bounds_origin_x.reset(new int(-350));
    375   info.bounds_origin_y.reset(new int(600));
    376 
    377   bool success = false;
    378   std::string error;
    379   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    380       &success, &error);
    381 
    382   ASSERT_TRUE(success);
    383   ASSERT_TRUE(error.empty());
    384 
    385   EXPECT_EQ("-350,600 520x400", secondary.bounds().ToString());
    386 }
    387 
    388 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSameCenter) {
    389   UpdateDisplay("1200x600,520x400");
    390 
    391   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    392   api::system_display::DisplayProperties info;
    393   info.bounds_origin_x.reset(new int(340));
    394   info.bounds_origin_y.reset(new int(100));
    395 
    396   bool success = false;
    397   std::string error;
    398   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    399       &success, &error);
    400 
    401   ASSERT_TRUE(success);
    402   ASSERT_TRUE(error.empty());
    403 
    404   EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
    405 }
    406 
    407 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftOutside) {
    408   UpdateDisplay("1200x600,520x400");
    409 
    410   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    411   api::system_display::DisplayProperties info;
    412   info.bounds_origin_x.reset(new int(-1040));
    413   info.bounds_origin_y.reset(new int(100));
    414 
    415   bool success = false;
    416   std::string error;
    417   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    418       &success, &error);
    419 
    420   ASSERT_TRUE(success);
    421   ASSERT_TRUE(error.empty());
    422 
    423   EXPECT_EQ("-520,100 520x400", secondary.bounds().ToString());
    424 }
    425 
    426 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopOutside) {
    427   UpdateDisplay("1200x600,520x400");
    428 
    429   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    430   api::system_display::DisplayProperties info;
    431   info.bounds_origin_x.reset(new int(-360));
    432   info.bounds_origin_y.reset(new int(-301));
    433 
    434   bool success = false;
    435   std::string error;
    436   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    437       &success, &error);
    438 
    439   ASSERT_TRUE(success);
    440   ASSERT_TRUE(error.empty());
    441 
    442   EXPECT_EQ("-360,-400 520x400", secondary.bounds().ToString());
    443 }
    444 
    445 TEST_F(DisplayInfoProviderChromeosTest,
    446        SetBoundsOriginLeftButSharesBottomSide) {
    447   UpdateDisplay("1200x600,1000x100");
    448 
    449   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    450   api::system_display::DisplayProperties info;
    451   info.bounds_origin_x.reset(new int(-650));
    452   info.bounds_origin_y.reset(new int(700));
    453 
    454   bool success = false;
    455   std::string error;
    456   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    457       &success, &error);
    458 
    459   ASSERT_TRUE(success);
    460   ASSERT_TRUE(error.empty());
    461 
    462   EXPECT_EQ("-650,600 1000x100", secondary.bounds().ToString());
    463 }
    464 
    465 TEST_F(DisplayInfoProviderChromeosTest,
    466        SetBoundsOriginRightButSharesTopSide) {
    467   UpdateDisplay("1200x600,1000x100");
    468 
    469   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    470   api::system_display::DisplayProperties info;
    471   info.bounds_origin_x.reset(new int(850));
    472   info.bounds_origin_y.reset(new int(-150));
    473 
    474   bool success = false;
    475   std::string error;
    476   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    477       &success, &error);
    478 
    479   ASSERT_TRUE(success);
    480   ASSERT_TRUE(error.empty());
    481 
    482   EXPECT_EQ("850,-100 1000x100", secondary.bounds().ToString());
    483 }
    484 
    485 TEST_F(DisplayInfoProviderChromeosTest,
    486        SetBoundsOriginTopButSharesLeftSide) {
    487   UpdateDisplay("1200x600,1000x100/l");
    488 
    489   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    490   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(base::Int64ToString(secondary.id()), info,
    497       &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   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(base::Int64ToString(secondary.id()), info,
    517       &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   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(base::Int64ToString(secondary.id()), info,
    536       &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   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(base::Int64ToString(secondary.id()), info,
    555       &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   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(base::Int64ToString(secondary.id()), info,
    574       &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   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(base::Int64ToString(secondary.id()), info,
    593       &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   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(base::Int64ToString(secondary.id()), info,
    612       &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   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(base::Int64ToString(secondary.id()), info,
    631       &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   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(base::Int64ToString(secondary.id()), info,
    656       &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   api::system_display::DisplayProperties info;
    668   info.rotation.reset(new int(90));
    669 
    670   bool success = false;
    671   std::string error;
    672   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    673       &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(base::Int64ToString(secondary.id()), info,
    683       &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(base::Int64ToString(secondary.id()), info,
    695       &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(base::Int64ToString(secondary.id()), info,
    706       &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   api::system_display::DisplayProperties info;
    721   info.rotation.reset(new int(91));
    722 
    723   bool success = false;
    724   std::string error;
    725   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    726       &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   api::system_display::DisplayProperties info;
    737   info.overscan.reset(new api::system_display::Insets);
    738   info.overscan->left= -10;
    739 
    740   bool success = false;
    741   std::string error;
    742   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    743       &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(base::Int64ToString(secondary.id()), info,
    754       &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(base::Int64ToString(secondary.id()), info,
    765       &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(base::Int64ToString(secondary.id()), info,
    776       &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(base::Int64ToString(secondary.id()), info,
    787       &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   api::system_display::DisplayProperties info;
    800   info.overscan.reset(new 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(base::Int64ToString(secondary.id()), info,
    810       &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   api::system_display::DisplayProperties info;
    822   info.overscan.reset(new 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(base::Int64ToString(secondary.id()), info,
    832       &success, &error);
    833 
    834   ASSERT_FALSE(success);
    835   EXPECT_EQ("Vertical overscan is more than half of the screen height.",
    836             error);
    837 }
    838 
    839 TEST_F(DisplayInfoProviderChromeosTest, SetOverscan) {
    840   UpdateDisplay("1200x600,600x1000*2");
    841 
    842   const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
    843   api::system_display::DisplayProperties info;
    844   info.overscan.reset(new api::system_display::Insets);
    845   info.overscan->left= 20;
    846   info.overscan->top = 199;
    847   info.overscan->right = 130;
    848   info.overscan->bottom = 51;
    849 
    850   bool success = false;
    851   std::string error;
    852   CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
    853       &success, &error);
    854 
    855   ASSERT_TRUE(success);
    856   EXPECT_TRUE(error.empty());
    857 
    858   EXPECT_EQ("1200,0 150x250", secondary.bounds().ToString());
    859   const gfx::Insets overscan =
    860       GetDisplayManager()->GetOverscanInsets(secondary.id());
    861 
    862   EXPECT_EQ(20, overscan.left());
    863   EXPECT_EQ(199, overscan.top());
    864   EXPECT_EQ(130, overscan.right());
    865   EXPECT_EQ(51, overscan.bottom());
    866 }
    867 
    868 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanForInternal) {
    869   UpdateDisplay("1200x600,600x1000*2");
    870   const int64 internal_display_id =
    871       ash::test::DisplayManagerTestApi(GetDisplayManager()).
    872       SetFirstDisplayAsInternalDisplay();
    873 
    874   api::system_display::DisplayProperties info;
    875   info.overscan.reset(new api::system_display::Insets);
    876   // Vertical overscan is 501, which would make the bounds height 499.
    877   info.overscan->left= 20;
    878   info.overscan->top = 20;
    879   info.overscan->right = 20;
    880   info.overscan->bottom = 20;
    881 
    882   bool success = false;
    883   std::string error;
    884   CallSetDisplayUnitInfo(base::Int64ToString(internal_display_id), info,
    885       &success, &error);
    886 
    887   ASSERT_FALSE(success);
    888   EXPECT_EQ("Overscan changes not allowed for the internal monitor.",
    889             error);
    890 }
    891 
    892 }  // namespace
    893 }  // namespace extensions
    894