#include "ash/system/audio/unified_volume_view.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/audio/unified_volume_slider_controller.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/system/unified/unified_system_tray_bubble.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/slider.h"
namespace ash {
constexpr float kVolumeStepChange = 0.04;
class UnifiedVolumeViewTest : public AshTestBase {
public:
UnifiedVolumeViewTest() = default;
UnifiedVolumeViewTest(const UnifiedVolumeViewTest&) = delete;
UnifiedVolumeViewTest& operator=(const UnifiedVolumeViewTest&) = delete;
~UnifiedVolumeViewTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
GetPrimaryUnifiedSystemTray()->ShowBubble();
}
void CheckSliderIcon(float level) {
const gfx::VectorIcon* icon = &GetIcon(level);
if (level <= 0.0) {
EXPECT_EQ(icon, UnifiedVolumeView::kQsVolumeLevelIcons[0]);
} else if (level <= 0.5) {
EXPECT_EQ(icon, UnifiedVolumeView::kQsVolumeLevelIcons[1]);
} else {
EXPECT_EQ(icon, UnifiedVolumeView::kQsVolumeLevelIcons[2]);
}
}
UnifiedVolumeSliderController* volume_slider_controller() {
return controller()->volume_slider_controller_.get();
}
UnifiedVolumeView* unified_volume_view() {
return static_cast<UnifiedVolumeView*>(controller()->unified_volume_view_);
}
views::Slider* slider() { return unified_volume_view()->slider(); }
IconButton* slider_button() { return unified_volume_view()->slider_button(); }
const gfx::VectorIcon& GetIcon(float level) {
return unified_volume_view()->GetVolumeIconForLevel(level);
}
UnifiedSystemTrayController* controller() {
return GetPrimaryUnifiedSystemTray()
->bubble()
->unified_system_tray_controller();
}
views::Button* more_button() { return unified_volume_view()->more_button(); }
};
TEST_F(UnifiedVolumeViewTest, SliderButtonComponents) {
EXPECT_EQ(unified_volume_view()->children()[0]->GetClassName(),
"QuickSettingsSlider");
auto* live_caption_button =
static_cast<IconButton*>(unified_volume_view()->children()[1]);
EXPECT_EQ(live_caption_button->GetClassName(), "IconButton");
EXPECT_EQ(live_caption_button->GetViewAccessibility().GetCachedName(),
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP,
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP)));
EXPECT_EQ(live_caption_button->GetTooltipText(),
u"Toggle Live Caption. Live Caption is off.");
auto* audio_subpage_drill_in_button =
static_cast<IconButton*>(unified_volume_view()->children()[2]);
EXPECT_EQ(audio_subpage_drill_in_button->GetClassName(), "IconButton");
EXPECT_EQ(
audio_subpage_drill_in_button->GetViewAccessibility().GetCachedName(),
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO));
EXPECT_EQ(audio_subpage_drill_in_button->GetTooltipText(), u"Audio settings");
EXPECT_FALSE(controller()->IsDetailedViewShown());
LeftClickOn(unified_volume_view()->children()[2]);
EXPECT_TRUE(controller()->showing_audio_detailed_view());
}
TEST_F(UnifiedVolumeViewTest, SliderIcon) {
const float levels[] = {0.0, 0.2, 0.25, 0.49, 0.5, 0.7, 0.75, 0.9, 1};
for (auto level : levels) {
volume_slider_controller()->SliderValueChanged(
slider(), level, slider()->GetValue(),
views::SliderChangeReason::kByUser);
CheckSliderIcon(level);
}
}
TEST_F(UnifiedVolumeViewTest, MoreButton) {
EXPECT_TRUE(more_button()->GetEnabled());
GetPrimaryUnifiedSystemTray()->CloseBubble();
std::unique_ptr<aura::Window> window(CreateTestWindow());
wm::ActivateWindow(window.get());
window_util::PinWindow(window.get(), true);
GetPrimaryUnifiedSystemTray()->ShowBubble();
EXPECT_FALSE(more_button()->GetEnabled());
GetPrimaryUnifiedSystemTray()->CloseBubble();
WindowState::Get(window.get())->Restore();
GetPrimaryUnifiedSystemTray()->ShowBubble();
EXPECT_TRUE(more_button()->GetEnabled());
}
TEST_F(UnifiedVolumeViewTest, VolumeMuteThenVolumeUp) {
const float level = 0.8;
volume_slider_controller()->SliderValueChanged(
slider(), level, slider()->GetValue(),
views::SliderChangeReason::kByUser);
EXPECT_EQ(slider()->GetValue(), level);
CheckSliderIcon(level);
const bool is_muted = CrasAudioHandler::Get()->IsOutputMuted();
PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_MUTE);
EXPECT_EQ(slider()->GetValue(), level);
CheckSliderIcon(level);
EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), !is_muted);
PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_UP);
const float new_level = level + kVolumeStepChange;
EXPECT_FLOAT_EQ(slider()->GetValue(), new_level);
CheckSliderIcon(new_level);
EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), is_muted);
}
TEST_F(UnifiedVolumeViewTest, VolumeMuteThenVolumeDown) {
const float level = 0.8;
volume_slider_controller()->SliderValueChanged(
slider(), level, slider()->GetValue(),
views::SliderChangeReason::kByUser);
EXPECT_EQ(slider()->GetValue(), level);
CheckSliderIcon(level);
const bool is_muted = CrasAudioHandler::Get()->IsOutputMuted();
PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_MUTE);
EXPECT_EQ(slider()->GetValue(), level);
CheckSliderIcon(level);
EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), !is_muted);
PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_DOWN);
const float new_level = level - kVolumeStepChange;
EXPECT_FLOAT_EQ(slider()->GetValue(), new_level);
CheckSliderIcon(new_level);
EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), !is_muted);
}
TEST_F(UnifiedVolumeViewTest, SliderFocusToggleMute) {
EXPECT_TRUE(slider()->IsFocusable());
EXPECT_FALSE(slider_button()->IsFocusable());
EXPECT_TRUE(
slider_button()->GetViewAccessibility().IsAccessibilityFocusable());
const float level = 0.8;
volume_slider_controller()->SliderValueChanged(
slider(), level, slider()->GetValue(),
views::SliderChangeReason::kByUser);
auto* generator = GetEventGenerator();
generator->PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB);
slider()->RequestFocus();
EXPECT_EQ(unified_volume_view()
->GetFocusManager()
->GetFocusedView()
->GetClassName(),
"QuickSettingsSlider");
const bool is_muted = CrasAudioHandler::Get()->IsOutputMuted();
generator->PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), !is_muted);
}
TEST_F(UnifiedVolumeViewTest, MultipleDisplay) {
UpdateDisplay("1280x1024,1980x1080");
const float level = 0.5;
volume_slider_controller()->SliderValueChanged(
slider(), level, slider()->GetValue(),
views::SliderChangeReason::kByUser);
EXPECT_EQ(slider()->GetValue(), level);
CheckSliderIcon(level);
PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_UP);
const float new_level = level + kVolumeStepChange;
EXPECT_FLOAT_EQ(slider()->GetValue(), new_level);
CheckSliderIcon(new_level);
}
}