blob: 88dc581ce0386c8fd74c3e66b42f45d09ac794b8 [file] [log] [blame]
// Copyright 2020 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 <fuchsia/ui/activity/cpp/fidl.h>
#include <fuchsia/ui/activity/cpp/fidl_test_base.h>
#include <lib/async-loop/default.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include "src/ui/bin/headless_root_presenter/app.h"
namespace headless_root_presenter {
namespace testing {
class MockMediaButtonsListener : public fuchsia::ui::policy::MediaButtonsListener {
public:
void OnMediaButtonsEvent(fuchsia::ui::input::MediaButtonsEvent event) override {
last_event_ = std::make_unique<fuchsia::ui::input::MediaButtonsEvent>(std::move(event));
media_button_event_count_++;
}
int GetMediaButtonEventCount() { return media_button_event_count_; }
fuchsia::ui::input::MediaButtonsEvent* GetLastEvent() { return last_event_.get(); }
private:
uint32_t media_button_event_count_ = 0;
std::unique_ptr<fuchsia::ui::input::MediaButtonsEvent> last_event_;
};
class FakeActivityTracker : public fuchsia::ui::activity::testing::Tracker_TestBase {
public:
void NotImplemented_(const std::string& name) final { ZX_DEBUG_ASSERT_IMPLEMENTED; }
fidl::InterfaceRequestHandler<fuchsia::ui::activity::Tracker> GetHandler(
async_dispatcher_t* dispatcher = nullptr) {
return [this, dispatcher](fidl::InterfaceRequest<fuchsia::ui::activity::Tracker> request) {
binding_.Bind(std::move(request), dispatcher);
};
}
void ReportDiscreteActivity(fuchsia::ui::activity::DiscreteActivity activity,
zx_time_t event_time,
ReportDiscreteActivityCallback callback) override {
activities_.push_back(std::move(activity));
callback();
}
const std::vector<fuchsia::ui::activity::DiscreteActivity>& activities() const {
return activities_;
}
private:
std::vector<fuchsia::ui::activity::DiscreteActivity> activities_;
fidl::Binding<fuchsia::ui::activity::Tracker> binding_{this};
};
class AppUnitTest : public gtest::TestLoopFixture {
public:
AppUnitTest() : listener_binding_(&listener_) {
context_ = context_provider_.context();
context_provider_.service_directory_provider()->AddService(
fake_tracker_.GetHandler(dispatcher()));
app_ = std::make_unique<headless_root_presenter::App>(command_line_, &loop_,
context_provider_.TakeContext(),
/* driver-based input */ false);
SetupMockDevice();
}
void SetUp() override { TestLoopFixture::SetUp(); }
void SetupMockDevice() {
fuchsia::ui::input::DeviceDescriptor device_descriptor;
device_descriptor.media_buttons =
std::make_unique<fuchsia::ui::input::MediaButtonsDescriptor>();
fuchsia::ui::input::InputDeviceRegistryPtr inpReg;
context_provider_.ConnectToPublicService(inpReg.NewRequest());
inpReg->RegisterDevice(std::move(device_descriptor), input_device_.NewRequest());
}
void RegisterMockListener() {
fidl::InterfaceHandle<fuchsia::ui::policy::MediaButtonsListener> listener_handle;
listener_binding_.Bind(listener_handle.NewRequest());
fuchsia::ui::policy::DeviceListenerRegistryPtr dReg;
context_provider_.ConnectToPublicService(dReg.NewRequest());
dReg->RegisterMediaButtonsListener(std::move(listener_handle));
}
sys::testing::ComponentContextProvider context_provider_;
sys::ComponentContext* context_;
fuchsia::ui::input::InputDevicePtr input_device_;
MockMediaButtonsListener listener_;
fidl::Binding<fuchsia::ui::policy::MediaButtonsListener> listener_binding_;
const int argc_ = 1;
const char* argv_[1]{"headless_root_presenter"};
fxl::CommandLine command_line_{fxl::CommandLineFromArgcArgv(argc_, argv_)};
async::Loop loop_{&kAsyncLoopConfigNoAttachToCurrentThread};
std::unique_ptr<headless_root_presenter::App> app_;
FakeActivityTracker fake_tracker_;
};
fuchsia::ui::input::InputReport CreateOneReport() {
std::unique_ptr<fuchsia::ui::input::MediaButtonsReport> media_buttons_report =
std::make_unique<fuchsia::ui::input::MediaButtonsReport>();
media_buttons_report->volume_down = true;
fuchsia::ui::input::InputReport input_report;
input_report.media_buttons = std::move(media_buttons_report);
return input_report;
}
TEST_F(AppUnitTest, NormalFlowTest) {
RegisterMockListener();
RunLoopUntilIdle();
int current_count = listener_.GetMediaButtonEventCount();
//- inject media report via device
input_device_->DispatchReport(CreateOneReport());
RunLoopUntilIdle();
//- capture listener wakeup
EXPECT_TRUE(listener_.GetMediaButtonEventCount() == current_count + 1);
EXPECT_TRUE(listener_.GetLastEvent()->volume() == -1);
}
TEST_F(AppUnitTest, NoListenerTest) {
input_device_->DispatchReport(CreateOneReport());
RunLoopUntilIdle();
// listener should not wake up and test should not crash
EXPECT_TRUE(listener_.GetMediaButtonEventCount() == 0);
}
TEST_F(AppUnitTest, DisconnectTest) {
RegisterMockListener();
RunLoopUntilIdle();
int current_count = listener_.GetMediaButtonEventCount();
// disconnect
input_device_.Unbind();
RunLoopUntilIdle();
//- inject media report via device
input_device_->DispatchReport(CreateOneReport());
RunLoopUntilIdle();
//- expect listener not wakeup, and test not crash
EXPECT_TRUE(listener_.GetMediaButtonEventCount() == current_count);
}
} // namespace testing
} // namespace headless_root_presenter