blob: 3d70b7d3e0e45a2cfdcfbe783ca098719e721c71 [file] [log] [blame]
// 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/system/chromeos/screen_layout_observer.h"
#include "ash/common/system/chromeos/devicetype_utils.h"
#include "ash/common/system/tray/system_tray.h"
#include "ash/display/display_manager.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/display_manager_test_api.h"
#include "ash/test/test_system_tray_delegate.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/display/display.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
#include "ui/views/controls/label.h"
namespace ash {
base::string16 GetFirstDisplayName() {
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
return base::UTF8ToUTF16(display_manager->GetDisplayNameForId(
display_manager->first_display_id()));
}
base::string16 GetSecondDisplayName() {
return base::UTF8ToUTF16(
Shell::GetInstance()->display_manager()->GetDisplayNameForId(
ScreenUtil::GetSecondaryDisplay().id()));
}
base::string16 GetMirroringDisplayName() {
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
return base::UTF8ToUTF16(display_manager->GetDisplayNameForId(
display_manager->mirroring_display_id()));
}
class ScreenLayoutObserverTest : public test::AshTestBase {
public:
ScreenLayoutObserverTest();
~ScreenLayoutObserverTest() override;
protected:
ScreenLayoutObserver* GetScreenLayoutObserver();
void CheckUpdate();
void CloseNotification();
base::string16 GetDisplayNotificationText() const;
base::string16 GetDisplayNotificationAdditionalText() const;
private:
const message_center::Notification* GetDisplayNotification() const;
DISALLOW_COPY_AND_ASSIGN(ScreenLayoutObserverTest);
};
ScreenLayoutObserverTest::ScreenLayoutObserverTest() {}
ScreenLayoutObserverTest::~ScreenLayoutObserverTest() {}
ScreenLayoutObserver* ScreenLayoutObserverTest::GetScreenLayoutObserver() {
return Shell::GetInstance()->screen_layout_observer();
}
void ScreenLayoutObserverTest::CloseNotification() {
message_center::MessageCenter::Get()->RemoveNotification(
ScreenLayoutObserver::kNotificationId, false);
RunAllPendingInMessageLoop();
}
base::string16 ScreenLayoutObserverTest::GetDisplayNotificationText() const {
const message_center::Notification* notification = GetDisplayNotification();
return notification ? notification->title() : base::string16();
}
base::string16 ScreenLayoutObserverTest::GetDisplayNotificationAdditionalText()
const {
const message_center::Notification* notification = GetDisplayNotification();
return notification ? notification->message() : base::string16();
}
const message_center::Notification*
ScreenLayoutObserverTest::GetDisplayNotification() const {
const message_center::NotificationList::Notifications notifications =
message_center::MessageCenter::Get()->GetVisibleNotifications();
for (message_center::NotificationList::Notifications::const_iterator iter =
notifications.begin();
iter != notifications.end(); ++iter) {
if ((*iter)->id() == ScreenLayoutObserver::kNotificationId)
return *iter;
}
return NULL;
}
TEST_F(ScreenLayoutObserverTest, DisplayNotifications) {
test::TestSystemTrayDelegate* tray_delegate = GetSystemTrayDelegate();
tray_delegate->set_should_show_display_notification(true);
UpdateDisplay("400x400");
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
display::Display::SetInternalDisplayId(display_manager->first_display_id());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// rotation.
UpdateDisplay("400x400/r");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetFirstDisplayName(),
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
CloseNotification();
UpdateDisplay("400x400");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetFirstDisplayName(),
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_STANDARD_ORIENTATION)),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// UI-scale
CloseNotification();
UpdateDisplay("400x400@1.5");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
GetFirstDisplayName(), base::UTF8ToUTF16("600x600")),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// UI-scale to 1.0
CloseNotification();
UpdateDisplay("400x400");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
GetFirstDisplayName(), base::UTF8ToUTF16("400x400")),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// No-update
CloseNotification();
UpdateDisplay("400x400");
EXPECT_TRUE(GetDisplayNotificationText().empty());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
// Extended.
CloseNotification();
UpdateDisplay("400x400,200x200");
EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
GetSecondDisplayName()),
GetDisplayNotificationText());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
// Mirroring.
CloseNotification();
display_manager->SetSoftwareMirroring(true);
UpdateDisplay("400x400,200x200");
EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
GetMirroringDisplayName()),
GetDisplayNotificationText());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
// Back to extended.
CloseNotification();
display_manager->SetSoftwareMirroring(false);
UpdateDisplay("400x400,200x200");
EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
GetSecondDisplayName()),
GetDisplayNotificationText());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
// Resize the first display.
UpdateDisplay("400x400@1.5,200x200");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
GetFirstDisplayName(), base::UTF8ToUTF16("600x600")),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// Rotate the second.
UpdateDisplay("400x400@1.5,200x200/r");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetSecondDisplayName(),
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
GetDisplayNotificationAdditionalText());
EXPECT_TRUE(GetDisplayNotificationText().empty());
// Enters closed lid mode.
UpdateDisplay("400x400@1.5,200x200");
display::Display::SetInternalDisplayId(
ScreenUtil::GetSecondaryDisplay().id());
UpdateDisplay("400x400@1.5");
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED),
GetDisplayNotificationText());
EXPECT_EQ(ash::SubstituteChromeOSDeviceType(
IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_DESCRIPTION),
GetDisplayNotificationAdditionalText());
}
// Verify that notification shows up when display is switched from dock mode to
// extend mode.
TEST_F(ScreenLayoutObserverTest, DisplayConfigurationChangedTwice) {
test::TestSystemTrayDelegate* tray_delegate = GetSystemTrayDelegate();
tray_delegate->set_should_show_display_notification(true);
UpdateDisplay("400x400,200x200");
EXPECT_EQ(l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL),
GetDisplayNotificationText());
// OnDisplayConfigurationChanged() may be called more than once for a single
// update display in case of primary is swapped or recovered from dock mode.
// Should not remove the notification in such case.
GetScreenLayoutObserver()->OnDisplayConfigurationChanged();
EXPECT_EQ(l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL),
GetDisplayNotificationText());
// Back to the single display. It SHOULD remove the notification since the
// information is stale.
UpdateDisplay("400x400");
EXPECT_TRUE(GetDisplayNotificationText().empty());
}
// Verify the notification message content when one of the 2 displays that
// connected to the device is rotated.
TEST_F(ScreenLayoutObserverTest, UpdateAfterSuppressDisplayNotification) {
UpdateDisplay("400x400,200x200");
test::TestSystemTrayDelegate* tray_delegate = GetSystemTrayDelegate();
tray_delegate->set_should_show_display_notification(true);
// rotate the second.
UpdateDisplay("400x400,200x200/r");
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetSecondDisplayName(),
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
GetDisplayNotificationAdditionalText());
}
// Verify that no notification is shown when overscan of a screen is changed.
TEST_F(ScreenLayoutObserverTest, OverscanDisplay) {
UpdateDisplay("400x400, 300x300");
test::TestSystemTrayDelegate* tray_delegate = GetSystemTrayDelegate();
tray_delegate->set_should_show_display_notification(true);
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
display::Display::SetInternalDisplayId(display_manager->first_display_id());
// /o creates the default overscan.
UpdateDisplay("400x400, 300x300/o");
EXPECT_TRUE(GetDisplayNotificationText().empty());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
// Reset the overscan.
Shell::GetInstance()->display_manager()->SetOverscanInsets(
ScreenUtil::GetSecondaryDisplay().id(), gfx::Insets());
EXPECT_TRUE(GetDisplayNotificationText().empty());
EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
}
} // namespace ash