diff options
Diffstat (limited to 'chromium/ash/display/resolution_notification_controller_unittest.cc')
-rw-r--r-- | chromium/ash/display/resolution_notification_controller_unittest.cc | 314 |
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 |