blob: 46e7f96932281a51687ec9efdf510b11fa7c4adc [file] [log] [blame]
// Copyright 2022 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 "input_sample.h"
#include <lib/async/cpp/task.h>
#include <lib/driver/component/cpp/service_client.h>
namespace input_sample {
zx::result<> InputSampleDriver::Start() {
// Start sending fake reports
input_report_readers_ =
std::make_shared<input_report_reader::InputReportReaderManager<SampleInputReport>>();
SendFakeReport();
// Initialize the driver compat service context.
compat::Context::ConnectAndCreate(
&context(), dispatcher(),
fit::bind_member<&InputSampleDriver::InitializeCompatService>(this));
return zx::ok();
}
// Initialize the driver compat context and export `fuchsia.input.report` to devfs.
void InputSampleDriver::InitializeCompatService(
zx::result<std::shared_ptr<compat::Context>> compat_result) {
if (!compat_result.is_ok()) {
FDF_SLOG(ERROR, "Failed to create compat context.",
KV("status", compat_result.status_string()));
node().reset();
return;
}
compat_context_ = std::move(*compat_result);
// Export to devfs.
zx::result connection = this->context().incoming()->Connect<fuchsia_device_fs::Exporter>();
if (connection.is_error()) {
FDF_SLOG(ERROR, "Failed to connect to fuchsia_device_fs::Exporter",
KV("status", connection.status_string()));
node().reset();
return;
}
fidl::WireSyncClient devfs_exporter{std::move(connection.value())};
zx::result connector = devfs_connector_.Bind(dispatcher());
if (connector.is_error()) {
FDF_SLOG(ERROR, "Failed to bind devfs_connector: %s", KV("status", connector.status_string()));
node().reset();
return;
}
fidl::WireResult export_result = devfs_exporter->ExportV2(
std::move(connector.value()),
fidl::StringView::FromExternal(compat_context_->TopologicalPath(name())), "input-report",
fuchsia_device_fs::ExportOptions());
if (!export_result.ok()) {
FDF_SLOG(ERROR, "Failed to export to devfs: %s", KV("status", export_result.status_string()));
node().reset();
return;
}
if (export_result.value().is_error()) {
FDF_SLOG(ERROR, "Failed to export to devfs: %s",
KV("status", zx_status_get_string(export_result.value().error_value())));
node().reset();
return;
}
}
// Periodically send a new input report with fake data.
void InputSampleDriver::SendFakeReport() {
// Update fake mouse report
report_.event_time = zx::time(zx_clock_get_monotonic());
report_.buttons++;
report_.rel_x++;
report_.rel_y++;
// Send fake mouse report
input_report_readers_->SendReportToAllReaders(report_);
// Run again in 1 second
async::PostDelayedTask(
dispatcher(), [this]() mutable { SendFakeReport(); }, zx::sec(1));
}
void InputSampleDriver::Serve(fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
InputSampleServer::BindDeviceClient(&logger(), dispatcher(), input_report_readers_,
std::move(request));
}
} // namespace input_sample
FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<input_sample::InputSampleDriver>);