- add sources.
[platform/framework/web/crosswalk.git] / src / ash / display / resolution_notification_controller_unittest.cc
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 "ash/display/resolution_notification_controller.h"
6
7 #include "ash/display/display_manager.h"
8 #include "ash/screen_ash.h"
9 #include "ash/shell.h"
10 #include "ash/test/ash_test_base.h"
11 #include "base/bind.h"
12 #include "ui/gfx/size.h"
13 #include "ui/message_center/message_center.h"
14
15 namespace ash {
16 namespace internal {
17
18 class ResolutionNotificationControllerTest : public ash::test::AshTestBase {
19  public:
20   ResolutionNotificationControllerTest()
21       : accept_count_(0) {
22   }
23
24   virtual ~ResolutionNotificationControllerTest() {}
25
26  protected:
27   virtual void SetUp() OVERRIDE {
28     ash::test::AshTestBase::SetUp();
29     ResolutionNotificationController::SuppressTimerForTest();
30   }
31
32   void SetDisplayResolutionAndNotify(const gfx::Display& display,
33                                      const gfx::Size& new_resolution) {
34     DisplayManager* display_manager = Shell::GetInstance()->display_manager();
35     const DisplayInfo& info = display_manager->GetDisplayInfo(display.id());
36     Shell::GetInstance()->resolution_notification_controller()->
37         SetDisplayResolutionAndNotify(
38             display.id(),
39             info.size_in_pixel(),
40             new_resolution,
41             base::Bind(&ResolutionNotificationControllerTest::OnAccepted,
42                        base::Unretained(this)));
43
44     // OnConfigurationChanged event won't be emitted in the test environment,
45     // so invoke UpdateDisplay() to emit that event explicitly.
46     std::vector<DisplayInfo> info_list;
47     for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
48       int64 id = display_manager->GetDisplayAt(i).id();
49       DisplayInfo info = display_manager->GetDisplayInfo(id);
50       if (display.id() == id) {
51         gfx::Rect bounds = info.bounds_in_native();
52         bounds.set_size(new_resolution);
53         info.SetBounds(bounds);
54       }
55       info_list.push_back(info);
56     }
57     display_manager->OnNativeDisplaysChanged(info_list);
58     RunAllPendingInMessageLoop();
59   }
60
61   void ClickOnNotification() {
62     message_center::MessageCenter::Get()->ClickOnNotification(
63         ResolutionNotificationController::kNotificationId);
64   }
65
66   void ClickOnNotificationButton(int index) {
67     message_center::MessageCenter::Get()->ClickOnNotificationButton(
68         ResolutionNotificationController::kNotificationId, index);
69   }
70
71   void CloseNotification() {
72     message_center::MessageCenter::Get()->RemoveNotification(
73         ResolutionNotificationController::kNotificationId, true /* by_user */);
74   }
75
76   bool IsNotificationVisible() {
77     return message_center::MessageCenter::Get()->HasNotification(
78         ResolutionNotificationController::kNotificationId);
79   }
80
81   void TickTimer() {
82     controller()->OnTimerTick();
83   }
84
85   ResolutionNotificationController* controller() {
86     return Shell::GetInstance()->resolution_notification_controller();
87   }
88
89   int accept_count() const {
90     return accept_count_;
91   }
92
93  private:
94   void OnAccepted() {
95     EXPECT_FALSE(controller()->DoesNotificationTimeout());
96     accept_count_++;
97   }
98
99   int accept_count_;
100
101   DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationControllerTest);
102 };
103
104 // Basic behaviors and verifies it doesn't cause crashes.
105 TEST_F(ResolutionNotificationControllerTest, Basic) {
106   if (!SupportsMultipleDisplays())
107     return;
108
109   UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
110   int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
111   ash::internal::DisplayManager* display_manager =
112       ash::Shell::GetInstance()->display_manager();
113   ASSERT_EQ(0, accept_count());
114   EXPECT_FALSE(IsNotificationVisible());
115
116   // Changes the resolution and apply the result.
117   SetDisplayResolutionAndNotify(
118       ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
119   EXPECT_TRUE(IsNotificationVisible());
120   EXPECT_FALSE(controller()->DoesNotificationTimeout());
121   gfx::Size resolution;
122   EXPECT_TRUE(
123       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
124   EXPECT_EQ("200x200", resolution.ToString());
125
126   // Click the revert button, which reverts to the best resolution.
127   ClickOnNotificationButton(0);
128   RunAllPendingInMessageLoop();
129   EXPECT_FALSE(IsNotificationVisible());
130   EXPECT_EQ(0, accept_count());
131   EXPECT_FALSE(
132       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
133 }
134
135 TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) {
136   if (!SupportsMultipleDisplays())
137     return;
138
139   UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
140   int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
141   ash::internal::DisplayManager* display_manager =
142       ash::Shell::GetInstance()->display_manager();
143   ASSERT_EQ(0, accept_count());
144   EXPECT_FALSE(IsNotificationVisible());
145
146   // Changes the resolution and apply the result.
147   SetDisplayResolutionAndNotify(
148       ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
149   EXPECT_TRUE(IsNotificationVisible());
150   EXPECT_FALSE(controller()->DoesNotificationTimeout());
151   gfx::Size resolution;
152   EXPECT_TRUE(
153       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
154   EXPECT_EQ("200x200", resolution.ToString());
155
156   // Click the revert button, which reverts the resolution.
157   ClickOnNotification();
158   RunAllPendingInMessageLoop();
159   EXPECT_FALSE(IsNotificationVisible());
160   EXPECT_EQ(1, accept_count());
161   EXPECT_TRUE(
162       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
163   EXPECT_EQ("200x200", resolution.ToString());
164 }
165
166 TEST_F(ResolutionNotificationControllerTest, AcceptButton) {
167   if (!SupportsMultipleDisplays())
168     return;
169
170   ash::internal::DisplayManager* display_manager =
171       ash::Shell::GetInstance()->display_manager();
172
173   UpdateDisplay("300x300#300x300|200x200");
174   const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
175   SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
176   EXPECT_TRUE(IsNotificationVisible());
177
178   // If there's a single display only, it will have timeout and the first button
179   // becomes accept.
180   EXPECT_TRUE(controller()->DoesNotificationTimeout());
181   ClickOnNotificationButton(0);
182   EXPECT_FALSE(IsNotificationVisible());
183   EXPECT_EQ(1, accept_count());
184   gfx::Size resolution;
185   EXPECT_TRUE(display_manager->GetSelectedResolutionForDisplayId(
186       display.id(), &resolution));
187   EXPECT_EQ("200x200", resolution.ToString());
188
189   // In that case the second button is revert.
190   UpdateDisplay("300x300#300x300|200x200");
191   SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
192   EXPECT_TRUE(IsNotificationVisible());
193
194   EXPECT_TRUE(controller()->DoesNotificationTimeout());
195   ClickOnNotificationButton(1);
196   EXPECT_FALSE(IsNotificationVisible());
197   EXPECT_EQ(1, accept_count());
198   EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId(
199       display.id(), &resolution));
200 }
201
202 TEST_F(ResolutionNotificationControllerTest, Close) {
203   if (!SupportsMultipleDisplays())
204     return;
205
206   UpdateDisplay("100x100,150x150#150x150|200x200");
207   int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
208   ash::internal::DisplayManager* display_manager =
209       ash::Shell::GetInstance()->display_manager();
210   ASSERT_EQ(0, accept_count());
211   EXPECT_FALSE(IsNotificationVisible());
212
213   // Changes the resolution and apply the result.
214   SetDisplayResolutionAndNotify(
215       ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
216   EXPECT_TRUE(IsNotificationVisible());
217   EXPECT_FALSE(controller()->DoesNotificationTimeout());
218   gfx::Size resolution;
219   EXPECT_TRUE(
220       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
221   EXPECT_EQ("200x200", resolution.ToString());
222
223   // Close the notification (imitates clicking [x] button). Also verifies if
224   // this does not cause a crash.  See crbug.com/271784
225   CloseNotification();
226   RunAllPendingInMessageLoop();
227   EXPECT_FALSE(IsNotificationVisible());
228   EXPECT_EQ(1, accept_count());
229 }
230
231 TEST_F(ResolutionNotificationControllerTest, Timeout) {
232   if (!SupportsMultipleDisplays())
233     return;
234
235   UpdateDisplay("300x300#300x300|200x200");
236   const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
237   SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
238
239   for (int i = 0; i < ResolutionNotificationController::kTimeoutInSec; ++i) {
240     EXPECT_TRUE(IsNotificationVisible()) << "notification is closed after "
241                                          << i << "-th timer tick";
242     TickTimer();
243     RunAllPendingInMessageLoop();
244   }
245   EXPECT_FALSE(IsNotificationVisible());
246   EXPECT_EQ(0, accept_count());
247   gfx::Size resolution;
248   ash::internal::DisplayManager* display_manager =
249       ash::Shell::GetInstance()->display_manager();
250   EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId(
251       display.id(), &resolution));
252 }
253
254 TEST_F(ResolutionNotificationControllerTest, DisplayDisconnected) {
255   if (!SupportsMultipleDisplays())
256     return;
257
258   UpdateDisplay("300x300#300x300|200x200,200x200#250x250|200x200|100x100");
259   int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
260   ash::internal::DisplayManager* display_manager =
261       ash::Shell::GetInstance()->display_manager();
262   SetDisplayResolutionAndNotify(
263       ScreenAsh::GetSecondaryDisplay(), gfx::Size(100, 100));
264   ASSERT_TRUE(IsNotificationVisible());
265
266   // Disconnects the secondary display and verifies it doesn't cause crashes.
267   UpdateDisplay("300x300#300x300|200x200");
268   RunAllPendingInMessageLoop();
269   EXPECT_FALSE(IsNotificationVisible());
270   EXPECT_EQ(0, accept_count());
271   gfx::Size resolution;
272   EXPECT_TRUE(
273       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
274   EXPECT_EQ("200x200", resolution.ToString());
275 }
276
277 TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) {
278   if (!SupportsMultipleDisplays())
279     return;
280
281   UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
282   int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
283   ash::internal::DisplayManager* display_manager =
284       ash::Shell::GetInstance()->display_manager();
285
286   SetDisplayResolutionAndNotify(
287       ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
288   EXPECT_TRUE(IsNotificationVisible());
289   EXPECT_FALSE(controller()->DoesNotificationTimeout());
290   gfx::Size resolution;
291   EXPECT_TRUE(
292       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
293   EXPECT_EQ("200x200", resolution.ToString());
294
295   // Invokes SetDisplayResolutionAndNotify during the previous notification is
296   // visible.
297   SetDisplayResolutionAndNotify(
298       ScreenAsh::GetSecondaryDisplay(), gfx::Size(250, 250));
299   EXPECT_FALSE(
300       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
301
302   // Then, click the revert button. Although |old_resolution| for the second
303   // SetDisplayResolutionAndNotify is 200x200, it should revert to the original
304   // size 150x150.
305   ClickOnNotificationButton(0);
306   RunAllPendingInMessageLoop();
307   EXPECT_FALSE(IsNotificationVisible());
308   EXPECT_EQ(0, accept_count());
309   EXPECT_FALSE(
310       display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
311 }
312
313 }  // namespace internal
314 }  // namespace ash