summaryrefslogtreecommitdiff
path: root/chromium/ash/display/resolution_notification_controller_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/display/resolution_notification_controller_unittest.cc')
-rw-r--r--chromium/ash/display/resolution_notification_controller_unittest.cc314
1 files changed, 314 insertions, 0 deletions
diff --git a/chromium/ash/display/resolution_notification_controller_unittest.cc b/chromium/ash/display/resolution_notification_controller_unittest.cc
new file mode 100644
index 00000000000..036cce0d85c
--- /dev/null
+++ b/chromium/ash/display/resolution_notification_controller_unittest.cc
@@ -0,0 +1,314 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/display/resolution_notification_controller.h"
+
+#include "ash/display/display_manager.h"
+#include "ash/screen_ash.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "base/bind.h"
+#include "ui/gfx/size.h"
+#include "ui/message_center/message_center.h"
+
+namespace ash {
+namespace internal {
+
+class ResolutionNotificationControllerTest : public ash::test::AshTestBase {
+ public:
+ ResolutionNotificationControllerTest()
+ : accept_count_(0) {
+ }
+
+ virtual ~ResolutionNotificationControllerTest() {}
+
+ protected:
+ virtual void SetUp() OVERRIDE {
+ ash::test::AshTestBase::SetUp();
+ ResolutionNotificationController::SuppressTimerForTest();
+ }
+
+ void SetDisplayResolutionAndNotify(const gfx::Display& display,
+ const gfx::Size& new_resolution) {
+ DisplayManager* display_manager = Shell::GetInstance()->display_manager();
+ const DisplayInfo& info = display_manager->GetDisplayInfo(display.id());
+ Shell::GetInstance()->resolution_notification_controller()->
+ SetDisplayResolutionAndNotify(
+ display.id(),
+ info.size_in_pixel(),
+ new_resolution,
+ base::Bind(&ResolutionNotificationControllerTest::OnAccepted,
+ base::Unretained(this)));
+
+ // OnConfigurationChanged event won't be emitted in the test environment,
+ // so invoke UpdateDisplay() to emit that event explicitly.
+ std::vector<DisplayInfo> info_list;
+ for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
+ int64 id = display_manager->GetDisplayAt(i).id();
+ DisplayInfo info = display_manager->GetDisplayInfo(id);
+ if (display.id() == id) {
+ gfx::Rect bounds = info.bounds_in_pixel();
+ bounds.set_size(new_resolution);
+ info.SetBounds(bounds);
+ }
+ info_list.push_back(info);
+ }
+ display_manager->OnNativeDisplaysChanged(info_list);
+ RunAllPendingInMessageLoop();
+ }
+
+ void ClickOnNotification() {
+ message_center::MessageCenter::Get()->ClickOnNotification(
+ ResolutionNotificationController::kNotificationId);
+ }
+
+ void ClickOnNotificationButton(int index) {
+ message_center::MessageCenter::Get()->ClickOnNotificationButton(
+ ResolutionNotificationController::kNotificationId, index);
+ }
+
+ void CloseNotification() {
+ message_center::MessageCenter::Get()->RemoveNotification(
+ ResolutionNotificationController::kNotificationId, true /* by_user */);
+ }
+
+ bool IsNotificationVisible() {
+ return message_center::MessageCenter::Get()->HasNotification(
+ ResolutionNotificationController::kNotificationId);
+ }
+
+ void TickTimer() {
+ controller()->OnTimerTick();
+ }
+
+ ResolutionNotificationController* controller() {
+ return Shell::GetInstance()->resolution_notification_controller();
+ }
+
+ int accept_count() const {
+ return accept_count_;
+ }
+
+ private:
+ void OnAccepted() {
+ EXPECT_FALSE(controller()->DoesNotificationTimeout());
+ accept_count_++;
+ }
+
+ int accept_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationControllerTest);
+};
+
+// Basic behaviors and verifies it doesn't cause crashes.
+TEST_F(ResolutionNotificationControllerTest, Basic) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
+ int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+ ASSERT_EQ(0, accept_count());
+ EXPECT_FALSE(IsNotificationVisible());
+
+ // Changes the resolution and apply the result.
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+ EXPECT_FALSE(controller()->DoesNotificationTimeout());
+ gfx::Size resolution;
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+
+ // Click the revert button, which reverts to the best resolution.
+ ClickOnNotificationButton(0);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(0, accept_count());
+ EXPECT_FALSE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+}
+
+TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
+ int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+ ASSERT_EQ(0, accept_count());
+ EXPECT_FALSE(IsNotificationVisible());
+
+ // Changes the resolution and apply the result.
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+ EXPECT_FALSE(controller()->DoesNotificationTimeout());
+ gfx::Size resolution;
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+
+ // Click the revert button, which reverts the resolution.
+ ClickOnNotification();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(1, accept_count());
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+}
+
+TEST_F(ResolutionNotificationControllerTest, AcceptButton) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+
+ UpdateDisplay("300x300#300x300|200x200");
+ const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
+ SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+
+ // If there's a single display only, it will have timeout and the first button
+ // becomes accept.
+ EXPECT_TRUE(controller()->DoesNotificationTimeout());
+ ClickOnNotificationButton(0);
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(1, accept_count());
+ gfx::Size resolution;
+ EXPECT_TRUE(display_manager->GetSelectedResolutionForDisplayId(
+ display.id(), &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+
+ // In that case the second button is revert.
+ UpdateDisplay("300x300#300x300|200x200");
+ SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+
+ EXPECT_TRUE(controller()->DoesNotificationTimeout());
+ ClickOnNotificationButton(1);
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(1, accept_count());
+ EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId(
+ display.id(), &resolution));
+}
+
+TEST_F(ResolutionNotificationControllerTest, Close) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("100x100,150x150#150x150|200x200");
+ int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+ ASSERT_EQ(0, accept_count());
+ EXPECT_FALSE(IsNotificationVisible());
+
+ // Changes the resolution and apply the result.
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+ EXPECT_FALSE(controller()->DoesNotificationTimeout());
+ gfx::Size resolution;
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+
+ // Close the notification (imitates clicking [x] button). Also verifies if
+ // this does not cause a crash. See crbug.com/271784
+ CloseNotification();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(1, accept_count());
+}
+
+TEST_F(ResolutionNotificationControllerTest, Timeout) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("300x300#300x300|200x200");
+ const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
+ SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
+
+ for (int i = 0; i < ResolutionNotificationController::kTimeoutInSec; ++i) {
+ EXPECT_TRUE(IsNotificationVisible()) << "notification is closed after "
+ << i << "-th timer tick";
+ TickTimer();
+ RunAllPendingInMessageLoop();
+ }
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(0, accept_count());
+ gfx::Size resolution;
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+ EXPECT_FALSE(display_manager->GetSelectedResolutionForDisplayId(
+ display.id(), &resolution));
+}
+
+TEST_F(ResolutionNotificationControllerTest, DisplayDisconnected) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("300x300#300x300|200x200,200x200#250x250|200x200|100x100");
+ int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(100, 100));
+ ASSERT_TRUE(IsNotificationVisible());
+
+ // Disconnects the secondary display and verifies it doesn't cause crashes.
+ UpdateDisplay("300x300#300x300|200x200");
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(0, accept_count());
+ gfx::Size resolution;
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+}
+
+TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200");
+ int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id();
+ ash::internal::DisplayManager* display_manager =
+ ash::Shell::GetInstance()->display_manager();
+
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200));
+ EXPECT_TRUE(IsNotificationVisible());
+ EXPECT_FALSE(controller()->DoesNotificationTimeout());
+ gfx::Size resolution;
+ EXPECT_TRUE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+ EXPECT_EQ("200x200", resolution.ToString());
+
+ // Invokes SetDisplayResolutionAndNotify during the previous notification is
+ // visible.
+ SetDisplayResolutionAndNotify(
+ ScreenAsh::GetSecondaryDisplay(), gfx::Size(250, 250));
+ EXPECT_FALSE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+
+ // Then, click the revert button. Although |old_resolution| for the second
+ // SetDisplayResolutionAndNotify is 200x200, it should revert to the original
+ // size 150x150.
+ ClickOnNotificationButton(0);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsNotificationVisible());
+ EXPECT_EQ(0, accept_count());
+ EXPECT_FALSE(
+ display_manager->GetSelectedResolutionForDisplayId(id2, &resolution));
+}
+
+} // namespace internal
+} // namespace ash