blob: 4008d6023f861c427cbae973c660e723ec5276b2 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "src/ui/bin/root_presenter/media_buttons_handler.h"
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <cstdlib>
#include <gtest/gtest.h>
#include "src/lib/fxl/macros.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/lib/ui/input/input_device_impl.h"
#include "src/ui/testing/mock_input_device.h"
namespace root_presenter {
namespace {
// A mock for capturing events passed to the listener.
class MockListener : public fuchsia::ui::policy::MediaButtonsListener {
public:
MockListener(fidl::InterfaceRequest<fuchsia::ui::policy::MediaButtonsListener> listener_request)
: binding_(this, std::move(listener_request)) {}
void OnMediaButtonsEvent(fuchsia::ui::input::MediaButtonsEvent event) override {
if (!last_event_) {
last_event_ = std::make_unique<fuchsia::ui::input::MediaButtonsEvent>();
}
event.Clone(last_event_.get());
media_button_event_count_++;
}
fuchsia::ui::input::MediaButtonsEvent* GetLastEvent() { return last_event_.get(); }
uint32_t GetMediaButtonEventCount() { return media_button_event_count_; }
private:
fidl::Binding<fuchsia::ui::policy::MediaButtonsListener> binding_;
uint32_t media_button_event_count_ = 0;
std::unique_ptr<fuchsia::ui::input::MediaButtonsEvent> last_event_;
};
class MediaButtonsHandlerTest : public gtest::TestLoopFixture,
public ui_input::InputDeviceImpl::Listener {
public:
void SetUp() final {
handler = std::make_unique<MediaButtonsHandler>();
fuchsia::ui::input::DeviceDescriptor device_descriptor;
device_descriptor.media_buttons =
std::make_unique<fuchsia::ui::input::MediaButtonsDescriptor>();
int id = rand();
device = std::make_unique<ui_input::InputDeviceImpl>(id, std::move(device_descriptor),
input_device.NewRequest(), this);
device_added = false;
}
void OnDeviceDisconnected(ui_input::InputDeviceImpl* input_device){};
void OnReport(ui_input::InputDeviceImpl* input_device, fuchsia::ui::input::InputReport report) {
handler->OnReport(input_device->id(), std::move(report));
};
protected:
std::unique_ptr<MockListener> CreateListener() {
fidl::InterfaceHandle<fuchsia::ui::policy::MediaButtonsListener> listener_handle;
auto mock_listener = std::make_unique<MockListener>(listener_handle.NewRequest());
handler->RegisterListener(std::move(listener_handle));
RunLoopUntilIdle();
return mock_listener;
}
void DispatchReport(fuchsia::ui::input::MediaButtonsReport report) {
AddDevice();
std::unique_ptr<fuchsia::ui::input::MediaButtonsReport> media_buttons_report =
std::make_unique<fuchsia::ui::input::MediaButtonsReport>();
fidl::Clone(report, media_buttons_report.get());
fuchsia::ui::input::InputReport input_report;
input_report.media_buttons = std::move(media_buttons_report);
input_device->DispatchReport(std::move(input_report));
RunLoopUntilIdle();
}
fuchsia::ui::input::InputDevicePtr input_device;
std::unique_ptr<ui_input::InputDeviceImpl> device;
std::unique_ptr<MediaButtonsHandler> handler;
bool device_added;
private:
void AddDevice() {
if (device_added) {
return;
}
handler->OnDeviceAdded(device.get());
device_added = true;
}
};
// This test exercises delivering a report to handler after registration.
TEST_F(MediaButtonsHandlerTest, ReportAfterRegistration) {
auto listener = CreateListener();
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.volume_down = true;
DispatchReport(std::move(media_buttons));
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->volume() == -1);
}
// This test exercises delivering a report to handler before registration. Upon
// registration, the last report should be delivered to the handler.
TEST_F(MediaButtonsHandlerTest, ReportBeforeRegistration) {
{
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.mic_mute = false;
DispatchReport(std::move(media_buttons));
}
{
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.mic_mute = true;
DispatchReport(std::move(media_buttons));
}
auto listener = CreateListener();
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->mic_mute());
}
// This test ensures multiple listeners receive messages when dispatched by an
// input device.
TEST_F(MediaButtonsHandlerTest, MultipleListeners) {
auto listener = CreateListener();
auto listener2 = CreateListener();
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.volume_up = true;
DispatchReport(std::move(media_buttons));
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->volume() == 1);
EXPECT_TRUE(listener2->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener2->GetLastEvent()->volume() == 1);
}
// This test checks that pause is wired up correctly.
TEST_F(MediaButtonsHandlerTest, PauseButton) {
auto listener = CreateListener();
fuchsia::ui::input::MediaButtonsReport media_buttons = {};
media_buttons.pause = true;
DispatchReport(media_buttons);
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->pause());
media_buttons.pause = false;
DispatchReport(media_buttons);
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 2);
EXPECT_FALSE(listener->GetLastEvent()->pause());
}
// This test ensures that the camera button state is sent forward
// if the mic and camera are tied together.
TEST_F(MediaButtonsHandlerTest, MicCameraTogether) {
{
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.mic_mute = true;
media_buttons.camera_disable = true;
DispatchReport(std::move(media_buttons));
}
auto listener = CreateListener();
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->mic_mute());
EXPECT_TRUE(listener->GetLastEvent()->camera_disable());
}
// This test ensures that the camera button state is sent forward
// if the mic and camera are separately controlled.
TEST_F(MediaButtonsHandlerTest, MicCameraSeparate) {
{
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.mic_mute = true;
media_buttons.camera_disable = false;
DispatchReport(std::move(media_buttons));
}
auto listener = CreateListener();
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->mic_mute());
EXPECT_FALSE(listener->GetLastEvent()->camera_disable());
}
// This test ensures that the button state is delivered to media button
// listeners when FDR is active.
TEST_F(MediaButtonsHandlerTest, MediaButtonListeningDuringFDR) {
{
fuchsia::ui::input::MediaButtonsReport media_buttons;
media_buttons.reset = true;
media_buttons.volume_down = true;
DispatchReport(std::move(media_buttons));
}
auto listener = CreateListener();
EXPECT_TRUE(listener->GetMediaButtonEventCount() == 1);
EXPECT_TRUE(listener->GetLastEvent()->volume() == -1);
}
} // namespace
} // namespace root_presenter