| // 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>); |