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.
5 #include "base/debug/leak_annotations.h"
6 #include "base/strings/string_number_conversions.h"
7 #include "extensions/browser/api/system_display/display_info_provider.h"
8 #include "extensions/browser/api/system_display/system_display_api.h"
9 #include "extensions/browser/api_test_utils.h"
10 #include "extensions/common/api/system_display.h"
11 #include "extensions/shell/test/shell_apitest.h"
12 #include "ui/gfx/display.h"
13 #include "ui/gfx/display_observer.h"
14 #include "ui/gfx/screen.h"
16 namespace extensions
{
18 using core_api::system_display::Bounds
;
19 using core_api::system_display::DisplayUnitInfo
;
22 class MockScreen
: public Screen
{
25 for (int i
= 0; i
< 4; i
++) {
26 gfx::Rect
bounds(0, 0, 1280, 720);
27 gfx::Rect
work_area(0, 0, 960, 720);
28 gfx::Display
display(i
, bounds
);
29 display
.set_work_area(work_area
);
30 displays_
.push_back(display
);
33 ~MockScreen() override
{}
36 // Overridden from gfx::Screen:
37 gfx::Point
GetCursorScreenPoint() override
{ return gfx::Point(); }
38 gfx::NativeWindow
GetWindowUnderCursor() override
{
39 return gfx::NativeWindow();
41 gfx::NativeWindow
GetWindowAtScreenPoint(const gfx::Point
& point
) override
{
42 return gfx::NativeWindow();
44 int GetNumDisplays() const override
{
45 return static_cast<int>(displays_
.size());
47 std::vector
<gfx::Display
> GetAllDisplays() const override
{
50 gfx::Display
GetDisplayNearestWindow(gfx::NativeView window
) const override
{
51 return gfx::Display(0);
53 gfx::Display
GetDisplayNearestPoint(const gfx::Point
& point
) const override
{
54 return gfx::Display(0);
56 gfx::Display
GetDisplayMatching(const gfx::Rect
& match_rect
) const override
{
57 return gfx::Display(0);
59 gfx::Display
GetPrimaryDisplay() const override
{ return displays_
[0]; }
60 void AddObserver(gfx::DisplayObserver
* observer
) override
{}
61 void RemoveObserver(gfx::DisplayObserver
* observer
) override
{}
64 std::vector
<gfx::Display
> displays_
;
66 DISALLOW_COPY_AND_ASSIGN(MockScreen
);
69 class MockDisplayInfoProvider
: public DisplayInfoProvider
{
71 MockDisplayInfoProvider() {}
73 ~MockDisplayInfoProvider() override
{}
75 bool SetInfo(const std::string
& display_id
,
76 const core_api::system_display::DisplayProperties
& params
,
77 std::string
* error
) override
{
78 // Should get called only once per test case.
79 EXPECT_FALSE(set_info_value_
);
80 set_info_value_
= params
.ToValue();
81 set_info_display_id_
= display_id
;
85 gfx::Screen
* GetActiveScreen() override
{ return NULL
; }
87 scoped_ptr
<base::DictionaryValue
> GetSetInfoValue() {
88 return set_info_value_
.Pass();
91 std::string
GetSetInfoDisplayId() const { return set_info_display_id_
; }
94 // Update the content of the |unit| obtained for |display| using
95 // platform specific method.
96 void UpdateDisplayUnitInfoForPlatform(
97 const gfx::Display
& display
,
98 extensions::core_api::system_display::DisplayUnitInfo
* unit
) override
{
99 int64 id
= display
.id();
100 unit
->name
= "DISPLAY NAME FOR " + base::Int64ToString(id
);
102 unit
->mirroring_source_id
= "0";
103 unit
->is_primary
= id
== 0 ? true : false;
104 unit
->is_internal
= id
== 0 ? true : false;
105 unit
->is_enabled
= true;
106 unit
->rotation
= (90 * id
) % 360;
110 unit
->overscan
.left
= 20;
111 unit
->overscan
.top
= 40;
112 unit
->overscan
.right
= 60;
113 unit
->overscan
.bottom
= 80;
117 scoped_ptr
<base::DictionaryValue
> set_info_value_
;
118 std::string set_info_display_id_
;
120 DISALLOW_COPY_AND_ASSIGN(MockDisplayInfoProvider
);
123 class SystemDisplayApiTest
: public ShellApiTest
{
125 SystemDisplayApiTest()
126 : provider_(new MockDisplayInfoProvider
), screen_(new MockScreen
) {}
128 ~SystemDisplayApiTest() override
{}
130 void SetUpOnMainThread() override
{
131 ShellApiTest::SetUpOnMainThread();
132 ANNOTATE_LEAKING_OBJECT_PTR(
133 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE
));
134 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
135 DisplayInfoProvider::InitializeForTesting(provider_
.get());
139 scoped_ptr
<MockDisplayInfoProvider
> provider_
;
140 scoped_ptr
<gfx::Screen
> screen_
;
143 DISALLOW_COPY_AND_ASSIGN(SystemDisplayApiTest
);
146 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest
, GetDisplay
) {
147 ASSERT_TRUE(RunAppTest("system/display")) << message_
;
150 #if !defined(OS_CHROMEOS)
151 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest
, SetDisplay
) {
152 scoped_refptr
<SystemDisplaySetDisplayPropertiesFunction
> set_info_function(
153 new SystemDisplaySetDisplayPropertiesFunction());
155 set_info_function
->set_has_callback(true);
158 "Function available only on ChromeOS.",
159 api_test_utils::RunFunctionAndReturnError(
160 set_info_function
.get(), "[\"display_id\", {}]", browser_context()));
162 scoped_ptr
<base::DictionaryValue
> set_info
= provider_
->GetSetInfoValue();
163 EXPECT_FALSE(set_info
);
165 #endif // !defined(OS_CHROMEOS)
167 #if defined(OS_CHROMEOS)
168 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest
, SetDisplayNotKioskEnabled
) {
169 scoped_ptr
<base::DictionaryValue
> test_extension_value(
170 api_test_utils::ParseDictionary(
172 " \"name\": \"Test\",\n"
173 " \"version\": \"1.0\",\n"
175 " \"background\": {\n"
176 " \"scripts\": [\"background.js\"]\n"
180 scoped_refptr
<Extension
> test_extension(
181 api_test_utils::CreateExtension(test_extension_value
.get()));
183 scoped_refptr
<SystemDisplaySetDisplayPropertiesFunction
> set_info_function(
184 new SystemDisplaySetDisplayPropertiesFunction());
186 set_info_function
->set_extension(test_extension
.get());
187 set_info_function
->set_has_callback(true);
190 "The extension needs to be kiosk enabled to use the function.",
191 api_test_utils::RunFunctionAndReturnError(
192 set_info_function
.get(), "[\"display_id\", {}]", browser_context()));
194 scoped_ptr
<base::DictionaryValue
> set_info
= provider_
->GetSetInfoValue();
195 EXPECT_FALSE(set_info
);
198 IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest
, SetDisplayKioskEnabled
) {
199 scoped_ptr
<base::DictionaryValue
> test_extension_value(
200 api_test_utils::ParseDictionary(
202 " \"name\": \"Test\",\n"
203 " \"version\": \"1.0\",\n"
205 " \"background\": {\n"
206 " \"scripts\": [\"background.js\"]\n"
209 " \"kiosk_enabled\": true\n"
211 scoped_refptr
<Extension
> test_extension(
212 api_test_utils::CreateExtension(test_extension_value
.get()));
214 scoped_refptr
<SystemDisplaySetDisplayPropertiesFunction
> set_info_function(
215 new SystemDisplaySetDisplayPropertiesFunction());
217 set_info_function
->set_has_callback(true);
218 set_info_function
->set_extension(test_extension
.get());
220 ASSERT_TRUE(api_test_utils::RunFunction(
221 set_info_function
.get(),
222 "[\"display_id\", {\n"
223 " \"isPrimary\": true,\n"
224 " \"mirroringSourceId\": \"mirroringId\",\n"
225 " \"boundsOriginX\": 100,\n"
226 " \"boundsOriginY\": 200,\n"
227 " \"rotation\": 90,\n"
228 " \"overscan\": {\"left\": 1, \"top\": 2, \"right\": 3, \"bottom\": 4}\n"
232 scoped_ptr
<base::DictionaryValue
> set_info
= provider_
->GetSetInfoValue();
233 ASSERT_TRUE(set_info
);
234 EXPECT_TRUE(api_test_utils::GetBoolean(set_info
.get(), "isPrimary"));
235 EXPECT_EQ("mirroringId",
236 api_test_utils::GetString(set_info
.get(), "mirroringSourceId"));
237 EXPECT_EQ(100, api_test_utils::GetInteger(set_info
.get(), "boundsOriginX"));
238 EXPECT_EQ(200, api_test_utils::GetInteger(set_info
.get(), "boundsOriginY"));
239 EXPECT_EQ(90, api_test_utils::GetInteger(set_info
.get(), "rotation"));
240 base::DictionaryValue
* overscan
;
241 ASSERT_TRUE(set_info
->GetDictionary("overscan", &overscan
));
242 EXPECT_EQ(1, api_test_utils::GetInteger(overscan
, "left"));
243 EXPECT_EQ(2, api_test_utils::GetInteger(overscan
, "top"));
244 EXPECT_EQ(3, api_test_utils::GetInteger(overscan
, "right"));
245 EXPECT_EQ(4, api_test_utils::GetInteger(overscan
, "bottom"));
247 EXPECT_EQ("display_id", provider_
->GetSetInfoDisplayId());
249 #endif // defined(OS_CHROMEOS)
251 } // namespace extensions