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 "base/debug/leak_annotations.h"
      6 #include "base/strings/string_number_conversions.h"
      7 #include "chrome/browser/extensions/extension_apitest.h"
      8 #include "chrome/browser/extensions/extension_function_test_utils.h"
      9 #include "extensions/browser/api/system_display/display_info_provider.h"
     10 #include "extensions/browser/api/system_display/system_display_api.h"
     11 #include "extensions/common/api/system_display.h"
     12 #include "ui/gfx/display.h"
     13 #include "ui/gfx/display_observer.h"
     14 #include "ui/gfx/screen.h"
     15 
     16 #if defined(OS_CHROMEOS)
     17 #include "ash/display/screen_ash.h"
     18 #include "ash/shell.h"
     19 #endif
     20 
     21 namespace utils = extension_function_test_utils;
     22 
     23 namespace extensions {
     24 
     25 using core_api::system_display::Bounds;
     26 using core_api::system_display::DisplayUnitInfo;
     27 using gfx::Screen;
     28 
     29 #if defined(OS_CHROMEOS)
     30 class MockScreen : public ash::ScreenAsh {
     31  public:
     32   MockScreen() {
     33     for (int i = 0; i < 4; i++) {
     34       gfx::Rect bounds(0, 0, 1280, 720);
     35       gfx::Rect work_area(0, 0, 960, 720);
     36       gfx::Display display(i, bounds);
     37       display.set_work_area(work_area);
     38       displays_.push_back(display);
     39     }
     40   }
     41   virtual ~MockScreen() {}
     42 
     43  protected:
     44   // Overridden from gfx::Screen:
     45   virtual int GetNumDisplays() const OVERRIDE {
     46     return displays_.size();
     47   }
     48   virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE {
     49     return displays_;
     50   }
     51   virtual gfx::Display GetPrimaryDisplay() const OVERRIDE {
     52     return displays_[0];
     53   }
     54 
     55  private:
     56   std::vector<gfx::Display> displays_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(MockScreen);
     59 };
     60 #else
     61 class MockScreen : public Screen {
     62  public:
     63   MockScreen() {
     64     for (int i = 0; i < 4; i++) {
     65       gfx::Rect bounds(0, 0, 1280, 720);
     66       gfx::Rect work_area(0, 0, 960, 720);
     67       gfx::Display display(i, bounds);
     68       display.set_work_area(work_area);
     69       displays_.push_back(display);
     70     }
     71   }
     72   virtual ~MockScreen() {}
     73 
     74  protected:
     75   // Overridden from gfx::Screen:
     76   virtual bool IsDIPEnabled() OVERRIDE { return true; }
     77   virtual gfx::Point GetCursorScreenPoint() OVERRIDE  { return gfx::Point(); }
     78   virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE {
     79     return gfx::NativeWindow();
     80   }
     81   virtual gfx::NativeWindow GetWindowAtScreenPoint(
     82       const gfx::Point& point) OVERRIDE {
     83     return gfx::NativeWindow();
     84   }
     85   virtual int GetNumDisplays() const OVERRIDE {
     86     return displays_.size();
     87   }
     88   virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE {
     89     return displays_;
     90   }
     91   virtual gfx::Display GetDisplayNearestWindow(
     92       gfx::NativeView window) const OVERRIDE {
     93     return gfx::Display(0);
     94   }
     95   virtual gfx::Display GetDisplayNearestPoint(
     96       const gfx::Point& point) const OVERRIDE {
     97     return gfx::Display(0);
     98   }
     99   virtual gfx::Display GetDisplayMatching(
    100       const gfx::Rect& match_rect) const OVERRIDE {
    101     return gfx::Display(0);
    102   }
    103   virtual gfx::Display GetPrimaryDisplay() const OVERRIDE {
    104     return displays_[0];
    105   }
    106   virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE {}
    107   virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE {}
    108 
    109  private:
    110   std::vector<gfx::Display> displays_;
    111 
    112   DISALLOW_COPY_AND_ASSIGN(MockScreen);
    113 };
    114 #endif
    115 
    116 class MockDisplayInfoProvider : public DisplayInfoProvider {
    117  public:
    118   MockDisplayInfoProvider() {}
    119 
    120   virtual ~MockDisplayInfoProvider() {}
    121 
    122   virtual bool SetInfo(
    123       const std::string& display_id,
    124       const core_api::system_display::DisplayProperties& params,
    125       std::string* error) OVERRIDE {
    126     // Should get called only once per test case.
    127     EXPECT_FALSE(set_info_value_);
    128     set_info_value_ = params.ToValue();
    129     set_info_display_id_ = display_id;
    130     return true;
    131   }
    132 
    133   virtual gfx::Screen* GetActiveScreen() OVERRIDE { return NULL; }
    134 
    135   scoped_ptr<base::DictionaryValue> GetSetInfoValue() {
    136     return set_info_value_.Pass();
    137   }
    138 
    139   std::string GetSetInfoDisplayId() const {
    140     return set_info_display_id_;
    141   }
    142 
    143  private:
    144   // Update the content of the |unit| obtained for |display| using
    145   // platform specific method.
    146   virtual void UpdateDisplayUnitInfoForPlatform(
    147       const gfx::Display& display,
    148       extensions::core_api::system_display::DisplayUnitInfo* unit) OVERRIDE {
    149     int64 id = display.id();
    150     unit->name = "DISPLAY NAME FOR " + base::Int64ToString(id);
    151     if (id == 1)
    152       unit->mirroring_source_id = "0";
    153     unit->is_primary = id == 0 ? true : false;
    154     unit->is_internal = id == 0 ? true : false;
    155     unit->is_enabled = true;
    156     unit->rotation = (90 * id) % 360;
    157     unit->dpi_x = 96.0;
    158     unit->dpi_y = 96.0;
    159     if (id == 0) {
    160       unit->overscan.left = 20;
    161       unit->overscan.top = 40;
    162       unit->overscan.right = 60;
    163       unit->overscan.bottom = 80;
    164     }
    165   }
    166 
    167   scoped_ptr<base::DictionaryValue> set_info_value_;
    168   std::string set_info_display_id_;
    169 
    170   DISALLOW_COPY_AND_ASSIGN(MockDisplayInfoProvider);
    171 };
    172 
    173 class SystemDisplayApiTest: public ExtensionApiTest {
    174  public:
    175   SystemDisplayApiTest() : provider_(new MockDisplayInfoProvider),
    176                            screen_(new MockScreen) {}
    177 
    178   virtual ~SystemDisplayApiTest() {}
    179 
    180   virtual void SetUpOnMainThread() OVERRIDE {
    181     ExtensionApiTest::SetUpOnMainThread();
    182     ANNOTATE_LEAKING_OBJECT_PTR(
    183         gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE));
    184     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
    185     DisplayInfoProvider::InitializeForTesting(provider_.get());
    186   }
    187 
    188   virtual void TearDownOnMainThread() OVERRIDE {
    189 #if defined(OS_CHROMEOS)
    190     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
    191                                    ash::Shell::GetScreen());
    192 #endif
    193     ExtensionApiTest::TearDownOnMainThread();
    194   }
    195 
    196  protected:
    197   scoped_ptr<MockDisplayInfoProvider> provider_;
    198   scoped_ptr<gfx::Screen> screen_;
    199 
    200  private:
    201   DISALLOW_COPY_AND_ASSIGN(SystemDisplayApiTest);
    202 };
    203 
    204 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, GetDisplay) {
    205   ASSERT_TRUE(RunPlatformAppTest("system/display")) << message_;
    206 }
    207 
    208 #if !defined(OS_CHROMEOS)
    209 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplay) {
    210   scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
    211       set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
    212 
    213   set_info_function->set_has_callback(true);
    214 
    215   EXPECT_EQ("Function available only on ChromeOS.",
    216             utils::RunFunctionAndReturnError(set_info_function.get(),
    217                                              "[\"display_id\", {}]",
    218                                              browser()));
    219 
    220   scoped_ptr<base::DictionaryValue> set_info = provider_->GetSetInfoValue();
    221   EXPECT_FALSE(set_info);
    222 }
    223 #endif  // !defined(OS_CHROMEOS)
    224 
    225 #if defined(OS_CHROMEOS)
    226 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplayNotKioskEnabled) {
    227   scoped_ptr<base::DictionaryValue> test_extension_value(utils::ParseDictionary(
    228       "{\n"
    229       "  \"name\": \"Test\",\n"
    230       "  \"version\": \"1.0\",\n"
    231       "  \"app\": {\n"
    232       "    \"background\": {\n"
    233       "      \"scripts\": [\"background.js\"]\n"
    234       "    }\n"
    235       "  }\n"
    236       "}"));
    237   scoped_refptr<Extension> test_extension(
    238       utils::CreateExtension(test_extension_value.get()));
    239 
    240   scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
    241       set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
    242 
    243   set_info_function->set_extension(test_extension.get());
    244   set_info_function->set_has_callback(true);
    245 
    246   EXPECT_EQ("The extension needs to be kiosk enabled to use the function.",
    247             utils::RunFunctionAndReturnError(set_info_function.get(),
    248                                              "[\"display_id\", {}]",
    249                                              browser()));
    250 
    251   scoped_ptr<base::DictionaryValue> set_info = provider_->GetSetInfoValue();
    252   EXPECT_FALSE(set_info);
    253 }
    254 
    255 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplayKioskEnabled) {
    256   scoped_ptr<base::DictionaryValue> test_extension_value(utils::ParseDictionary(
    257       "{\n"
    258       "  \"name\": \"Test\",\n"
    259       "  \"version\": \"1.0\",\n"
    260       "  \"app\": {\n"
    261       "    \"background\": {\n"
    262       "      \"scripts\": [\"background.js\"]\n"
    263       "    }\n"
    264       "  },\n"
    265       "  \"kiosk_enabled\": true\n"
    266       "}"));
    267   scoped_refptr<Extension> test_extension(
    268       utils::CreateExtension(test_extension_value.get()));
    269 
    270   scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
    271       set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
    272 
    273   set_info_function->set_has_callback(true);
    274   set_info_function->set_extension(test_extension.get());
    275 
    276   ASSERT_TRUE(utils::RunFunction(
    277       set_info_function.get(),
    278       "[\"display_id\", {\n"
    279       "  \"isPrimary\": true,\n"
    280       "  \"mirroringSourceId\": \"mirroringId\",\n"
    281       "  \"boundsOriginX\": 100,\n"
    282       "  \"boundsOriginY\": 200,\n"
    283       "  \"rotation\": 90,\n"
    284       "  \"overscan\": {\"left\": 1, \"top\": 2, \"right\": 3, \"bottom\": 4}\n"
    285       "}]",
    286       browser(),
    287       utils::NONE));
    288 
    289   scoped_ptr<base::DictionaryValue> set_info = provider_->GetSetInfoValue();
    290   ASSERT_TRUE(set_info);
    291   EXPECT_TRUE(utils::GetBoolean(set_info.get(), "isPrimary"));
    292   EXPECT_EQ("mirroringId",
    293             utils::GetString(set_info.get(), "mirroringSourceId"));
    294   EXPECT_EQ(100, utils::GetInteger(set_info.get(), "boundsOriginX"));
    295   EXPECT_EQ(200, utils::GetInteger(set_info.get(), "boundsOriginY"));
    296   EXPECT_EQ(90, utils::GetInteger(set_info.get(), "rotation"));
    297   base::DictionaryValue* overscan;
    298   ASSERT_TRUE(set_info->GetDictionary("overscan", &overscan));
    299   EXPECT_EQ(1, utils::GetInteger(overscan, "left"));
    300   EXPECT_EQ(2, utils::GetInteger(overscan, "top"));
    301   EXPECT_EQ(3, utils::GetInteger(overscan, "right"));
    302   EXPECT_EQ(4, utils::GetInteger(overscan, "bottom"));
    303 
    304   EXPECT_EQ("display_id", provider_->GetSetInfoDisplayId());
    305 }
    306 #endif  // defined(OS_CHROMEOS)
    307 
    308 }  // namespace extensions
    309