[input_sample] Update to DriverBase
Updates the input sample driver to the DriverBase library. Starts using
the driver::Connect to connect to parent compat service and removes the
custom function for it. General build dependency cleanup.
Bug: 110283, 110915
Tests: Ran the driver and confirmed seeing input report from tool
Change-Id: Iccd712fb84ae8ee443251fd1309c1d37b394031e
Reviewed-on: https://fuchsia-review.googlesource.com/c/sdk-samples/drivers/+/737669
Reviewed-by: David Gilhooley <dgilhooley@google.com>
Commit-Queue: Novin Changizi <novinc@google.com>
Reviewed-by: Renato Mangini Dias <mangini@google.com>
Reviewed-by: Suraj Malhotra <surajmalhotra@google.com>
Reviewed-by: Dave Smith <smithdave@google.com>
diff --git a/src/input_sample/BUILD.bazel b/src/input_sample/BUILD.bazel
index c6778ae..b71909d 100644
--- a/src/input_sample/BUILD.bazel
+++ b/src/input_sample/BUILD.bazel
@@ -14,7 +14,7 @@
name = "bind_bytecode",
output = "input_sample.bindbc",
rules = "input_sample.bind",
- deps = [ "@fuchsia_sdk//bind/fuchsia.acpi" ],
+ deps = ["@fuchsia_sdk//bind/fuchsia.acpi"],
)
cc_binary(
@@ -23,20 +23,17 @@
"driver_compat.h",
"input_sample.cc",
"input_sample.h",
+ "input_server.cc",
+ "input_server.h",
],
linkshared = True,
deps = [
"@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_llcpp_cc",
"@fuchsia_sdk//fidl/fuchsia.driver.compat:fuchsia.driver.compat_llcpp_cc",
"@fuchsia_sdk//fidl/fuchsia.input.report:fuchsia.input.report_llcpp_cc",
- "@fuchsia_sdk//fidl/zx:zx_cc",
"@fuchsia_sdk//pkg/async-cpp",
"@fuchsia_sdk//pkg/driver2_cpp",
- "@fuchsia_sdk//pkg/driver_runtime_cpp",
- "@fuchsia_sdk//pkg/fidl_cpp_wire",
"@fuchsia_sdk//pkg/input_report_reader",
- "@fuchsia_sdk//pkg/sys_component_cpp",
- "@fuchsia_sdk//pkg/zx",
],
)
diff --git a/src/input_sample/driver_compat.h b/src/input_sample/driver_compat.h
index a52e20c..c7fc2ce 100644
--- a/src/input_sample/driver_compat.h
+++ b/src/input_sample/driver_compat.h
@@ -10,16 +10,6 @@
namespace input_driver_compat {
-// Connect to parent device node using fuchsia.driver.compat.Service
-zx::status<fidl::ClientEnd<fuchsia_driver_compat::Device>> ConnectToParentDevice(
- const driver::Namespace* ns, std::string_view name) {
- auto result = ns->OpenService<fuchsia_driver_compat::Service>(name);
- if (result.is_error()) {
- return result.take_error();
- }
- return result.value().connect_device();
-}
-
// Connect to the fuchsia.devices.fs.Exporter protocol
zx::status<fidl::ClientEnd<fuchsia_device_fs::Exporter>> ConnectToDeviceExporter(
const driver::Namespace* ns) {
diff --git a/src/input_sample/input_sample.cc b/src/input_sample/input_sample.cc
index d224f2b..c94a36d 100644
--- a/src/input_sample/input_sample.cc
+++ b/src/input_sample/input_sample.cc
@@ -5,168 +5,33 @@
#include "input_sample.h"
#include <lib/async/cpp/task.h>
+#include <lib/driver2/service_client.h>
#include "driver_compat.h"
-namespace {
-
-constexpr uint8_t kMouseButtonCount = 3;
-
-// FIDL server implementation for the `fuchsia.input.report/InputDevice` protocol
-class InputSampleServer : public fidl::WireServer<fuchsia_input_report::InputDevice> {
- public:
- explicit InputSampleServer(
- driver::Namespace& ns, async_dispatcher_t* dispatcher,
- std::weak_ptr<input_report_reader::InputReportReaderManager<input_sample::SampleInputReport>>
- input_report_readers)
- : dispatcher_(dispatcher), input_report_readers_(input_report_readers) {
- auto logger_result = driver::Logger::Create(ns, dispatcher, "input-sample-server");
- ZX_ASSERT(logger_result.is_ok());
- logger_ = std::move(*logger_result);
- }
-
- // Handle incoming connection requests from FIDL clients
- static fidl::ServerBindingRef<fuchsia_input_report::InputDevice> BindDeviceClient(
- driver::Namespace& ns, async_dispatcher_t* dispatcher,
- std::weak_ptr<input_report_reader::InputReportReaderManager<input_sample::SampleInputReport>>
- input_report_readers,
- fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
- // Bind each connection request to a unique FIDL server instance
- auto server_impl = std::make_unique<InputSampleServer>(ns, dispatcher, input_report_readers);
- return fidl::BindServer(dispatcher, std::move(request), std::move(server_impl),
- std::mem_fn(&InputSampleServer::OnUnbound));
- }
-
- // This method is called when a server connection is torn down.
- void OnUnbound(fidl::UnbindInfo info,
- fidl::ServerEnd<fuchsia_input_report::InputDevice> server_end) {
- if (info.is_peer_closed()) {
- FDF_LOG(DEBUG, "Client disconnected");
- } else if (!info.is_user_initiated()) {
- FDF_LOG(ERROR, "Client connection unbound: %s", info.status_string());
- }
- }
-
- void GetInputReportsReader(GetInputReportsReaderRequestView request,
- GetInputReportsReaderCompleter::Sync& completer) override;
- void GetDescriptor(GetDescriptorCompleter::Sync& completer) override;
-
- void SendOutputReport(SendOutputReportRequestView request,
- SendOutputReportCompleter::Sync& completer) override {
- completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
- }
- void GetFeatureReport(GetFeatureReportCompleter::Sync& completer) override {
- completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
- }
- void SetFeatureReport(SetFeatureReportRequestView request,
- SetFeatureReportCompleter::Sync& completer) override {
- completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
- }
- void GetInputReport(GetInputReportRequestView request,
- GetInputReportCompleter::Sync& completer) override {
- completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
- }
-
- private:
- driver::Logger logger_;
- async_dispatcher_t* const dispatcher_;
- std::weak_ptr<input_report_reader::InputReportReaderManager<input_sample::SampleInputReport>>
- input_report_readers_;
-};
-
-// Protocol method for `fuchsia.input.report/InputDevice` to begin serving input reports
-void InputSampleServer::GetInputReportsReader(GetInputReportsReaderRequestView request,
- GetInputReportsReaderCompleter::Sync& completer) {
- auto reader_manager = input_report_readers_.lock();
- if (!reader_manager) {
- FDF_LOG(ERROR, "Unable to access InputReport reader manager.");
- request->reader.Close(ZX_ERR_BAD_STATE);
- return;
- }
-
- zx_status_t status = reader_manager->CreateReader(dispatcher_, std::move(request->reader));
- if (status != ZX_OK) {
- FDF_LOG(ERROR, "Could not create input report reader: %d", status);
- request->reader.Close(ZX_ERR_BAD_STATE);
- }
-}
-
-// Protocol method for `fuchsia.input.report/InputDevice` to return the device descriptor
-void InputSampleServer::GetDescriptor(GetDescriptorCompleter::Sync& completer) {
- fidl::Arena allocator;
- auto descriptor = fuchsia_input_report::wire::DeviceDescriptor::Builder(allocator);
-
- fuchsia_input_report::wire::DeviceInfo device_info;
- // We pick random VID/PIDs here, but these should be taken from the HID device,
- // or defined in fuchsia.input.report/device_ids.fidl
- device_info.vendor_id = 0x12345678;
- device_info.product_id = 0x87654321;
-
- fidl::VectorView<uint8_t> buttons(allocator, kMouseButtonCount);
- buttons[0] = 0x01;
- buttons[1] = 0x02;
- buttons[2] = 0x03;
-
- constexpr fuchsia_input_report::wire::Axis movement_x{
- .range = {.min = -127, .max = 127},
- .unit = {.type = fuchsia_input_report::wire::UnitType::kNone, .exponent = 0},
- };
- constexpr fuchsia_input_report::wire::Axis movement_y{
- .range = {.min = -127, .max = 127},
- .unit = {.type = fuchsia_input_report::wire::UnitType::kNone, .exponent = 0},
- };
-
- auto mouse_in_desc = fuchsia_input_report::wire::MouseInputDescriptor::Builder(allocator);
- mouse_in_desc.buttons(buttons);
- mouse_in_desc.movement_x(movement_x);
- mouse_in_desc.movement_y(movement_y);
-
- auto mouse_descriptor = fuchsia_input_report::wire::MouseDescriptor::Builder(allocator);
- mouse_descriptor.input(mouse_in_desc.Build());
- descriptor.mouse(mouse_descriptor.Build());
- descriptor.device_info(device_info);
-
- completer.Reply(descriptor.Build());
-}
-
-} // namespace
-
namespace input_sample {
-// static
-zx::status<std::unique_ptr<InputSampleDriver>> InputSampleDriver::Start(
- fuchsia_driver_framework::wire::DriverStartArgs& start_args, fdf::UnownedDispatcher dispatcher,
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
- driver::Logger logger) {
- auto driver = std::make_unique<InputSampleDriver>(dispatcher->async_dispatcher(), std::move(node),
- std::move(ns), std::move(logger));
- auto result = driver->Run(std::move(start_args.outgoing_dir()));
- if (result.is_error()) {
- return result.take_error();
- }
- return zx::ok(std::move(driver));
-}
-
-zx::status<> InputSampleDriver::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
+zx::status<> InputSampleDriver::Start() {
// Connect to the parent device node.
- auto parent = input_driver_compat::ConnectToParentDevice(&ns_, "default");
+ auto parent =
+ driver::Connect<fuchsia_driver_compat::Service::Device>(*context().incoming(), "default");
if (parent.status_value() != ZX_OK) {
FDF_SLOG(ERROR, "Failed to connect to parent", KV("status", parent.status_string()));
return parent.take_error();
}
// Add the fuchsia.input.report/InputDevice protocol to be served as "/svc/input-sample"
- auto result = outgoing_.AddProtocol<fuchsia_input_report::InputDevice>(
+ auto result = context().outgoing()->component().AddProtocol<fuchsia_input_report::InputDevice>(
[this](fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
- InputSampleServer::BindDeviceClient(ns_, dispatcher_, input_report_readers_,
+ InputSampleServer::BindDeviceClient(logger_, async_dispatcher(), input_report_readers_,
std::move(request));
},
- Name());
+ kName);
if (result.status_value() != ZX_OK) {
return result;
}
- auto service_dir = fidl::StringView::FromExternal(std::string("svc/").append(Name()));
+ auto service_dir = fidl::StringView::FromExternal(std::string("svc/").append(kName));
// Construct a devfs path that matches the device nodes topological path
auto path_result = fidl::WireCall(*parent)->GetTopologicalPath();
@@ -175,27 +40,22 @@
return zx::error(path_result.status());
}
std::string parent_path(path_result->path.data(), path_result->path.size());
- auto devfs_path = fidl::StringView::FromExternal(parent_path.append("/").append(Name()));
+ auto devfs_path = fidl::StringView::FromExternal(parent_path.append("/").append(kName));
// Export an entry to devfs for fuchsia.input.report as an input device class
- auto devfs_dir =
- input_driver_compat::ExportDevfsEntry(&ns_, service_dir, devfs_path, /* INPUT_REPORT */ 26);
+ auto devfs_dir = input_driver_compat::ExportDevfsEntry(context().incoming().get(), service_dir,
+ devfs_path, /* INPUT_REPORT */ 26);
if (devfs_dir.is_error()) {
FDF_SLOG(ERROR, "Failed to export service", KV("status", devfs_dir.status_string()));
return devfs_dir.take_error();
}
// Serve the driver's FIDL protocol to clients.
- auto status = outgoing_.Serve(std::move(devfs_dir.value()));
+ auto status = context().outgoing()->Serve(std::move(devfs_dir.value()));
if (status.is_error()) {
FDF_SLOG(ERROR, "Failed to serve devfs directory", KV("status", status.status_string()));
return status.take_error();
}
- status = outgoing_.Serve(std::move(outgoing_dir));
- if (status.is_error()) {
- FDF_SLOG(ERROR, "Failed to serve outgoing directory", KV("status", status.status_string()));
- return status.take_error();
- }
// Start sending fake reports
input_report_readers_ =
@@ -205,31 +65,6 @@
return zx::ok();
}
-// Convert local data structure to a `fuchsia.input.report/InputReport` format.
-void SampleInputReport::ToFidlInputReport(
- fidl::WireTableBuilder<::fuchsia_input_report::wire::InputReport>& input_report,
- fidl::AnyArena& arena) {
- std::vector<uint8_t> pressed_buttons;
- for (uint8_t i = 0; i < kMouseButtonCount; i++) {
- if (buttons & (1 << i)) {
- pressed_buttons.push_back(i + 1);
- }
- }
- fidl::VectorView<uint8_t> buttons_vec(arena, pressed_buttons.size());
- size_t idx = 0;
- for (const auto& button : pressed_buttons) {
- buttons_vec[idx++] = button;
- }
-
- auto mouse_input_rpt = fuchsia_input_report::wire::MouseInputReport::Builder(arena);
- mouse_input_rpt.pressed_buttons(buttons_vec);
- mouse_input_rpt.movement_x(rel_x);
- mouse_input_rpt.movement_y(rel_y);
-
- input_report.mouse(mouse_input_rpt.Build());
- input_report.event_time(event_time.get());
-}
-
// Periodically send a new input report with fake data.
void InputSampleDriver::SendFakeReport() {
// Update fake mouse report
@@ -243,9 +78,9 @@
// Run again in 1 second
async::PostDelayedTask(
- dispatcher_, [this]() mutable { SendFakeReport(); }, zx::sec(1));
+ async_dispatcher(), [this]() mutable { SendFakeReport(); }, zx::sec(1));
}
} // namespace input_sample
-FUCHSIA_DRIVER_RECORD_CPP_V1(input_sample::InputSampleDriver);
+FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<input_sample::InputSampleDriver>);
diff --git a/src/input_sample/input_sample.h b/src/input_sample/input_sample.h
index 05be5b1..41a6ab9 100644
--- a/src/input_sample/input_sample.h
+++ b/src/input_sample/input_sample.h
@@ -5,67 +5,26 @@
#ifndef FUCHSIA_SDK_EXAMPLES_CC_INPUT_SAMPLE_H_
#define FUCHSIA_SDK_EXAMPLES_CC_INPUT_SAMPLE_H_
-#include <fidl/fuchsia.device.fs/cpp/wire.h>
-#include <fidl/fuchsia.driver.framework/cpp/wire.h>
-#include <fidl/fuchsia.input.report/cpp/wire.h>
-#include <lib/async/dispatcher.h>
-#include <lib/driver2/namespace.h>
-#include <lib/driver2/record_cpp.h>
-#include <lib/driver2/structured_logger.h>
-#include <lib/fdf/cpp/dispatcher.h>
-#include <lib/input_report_reader/reader.h>
-#include <lib/sys/component/cpp/outgoing_directory.h>
-#include <lib/zx/status.h>
-#include <unistd.h>
+#include <lib/driver2/driver2_cpp.h>
-#include <memory>
-#include <mutex>
+#include "input_server.h"
namespace input_sample {
-// Used by the input report reader library to transform reports over FIDL
-struct SampleInputReport {
- zx::time event_time;
- uint8_t buttons = 0;
- int8_t rel_x = 0;
- int8_t rel_y = 0;
-
- void ToFidlInputReport(
- fidl::WireTableBuilder<::fuchsia_input_report::wire::InputReport>& input_report,
- fidl::AnyArena& arena);
-};
-
// Sample driver for a virtual input device that generates input reports.
-class InputSampleDriver {
+class InputSampleDriver : public driver::DriverBase {
+ static constexpr std::string_view kName = "input-sample";
+
public:
- InputSampleDriver(async_dispatcher_t* dispatcher,
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
- driver::Namespace ns, driver::Logger logger)
- : dispatcher_(dispatcher),
- outgoing_(component::OutgoingDirectory::Create(dispatcher)),
- node_(std::move(node)),
- ns_(std::move(ns)),
- logger_(std::move(logger)) {}
+ InputSampleDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
+ : driver::DriverBase(kName, std::move(start_args), std::move(driver_dispatcher)) {}
virtual ~InputSampleDriver() = default;
- static constexpr const char* Name() { return "input-sample"; }
-
- static zx::status<std::unique_ptr<InputSampleDriver>> Start(
- fuchsia_driver_framework::wire::DriverStartArgs& start_args,
- fdf::UnownedDispatcher dispatcher,
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
- driver::Logger logger);
+ zx::status<> Start() override;
private:
- zx::status<> Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir);
void SendFakeReport();
- async_dispatcher_t* const dispatcher_;
- component::OutgoingDirectory outgoing_;
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node_;
- driver::Namespace ns_;
- driver::Logger logger_;
-
std::shared_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
input_report_readers_;
SampleInputReport report_;
diff --git a/src/input_sample/input_server.cc b/src/input_sample/input_server.cc
new file mode 100644
index 0000000..81b4c30
--- /dev/null
+++ b/src/input_sample/input_server.cc
@@ -0,0 +1,112 @@
+// 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_server.h"
+
+namespace input_sample {
+
+// Convert local data structure to a `fuchsia.input.report/InputReport` format.
+void SampleInputReport::ToFidlInputReport(
+ fidl::WireTableBuilder<::fuchsia_input_report::wire::InputReport>& input_report,
+ fidl::AnyArena& arena) {
+ std::vector<uint8_t> pressed_buttons;
+ for (uint8_t i = 0; i < kMouseButtonCount; i++) {
+ if (buttons & (1 << i)) {
+ pressed_buttons.push_back(i + 1);
+ }
+ }
+ fidl::VectorView<uint8_t> buttons_vec(arena, pressed_buttons.size());
+ size_t idx = 0;
+ for (const auto& button : pressed_buttons) {
+ buttons_vec[idx++] = button;
+ }
+
+ auto mouse_input_rpt = fuchsia_input_report::wire::MouseInputReport::Builder(arena);
+ mouse_input_rpt.pressed_buttons(buttons_vec);
+ mouse_input_rpt.movement_x(rel_x);
+ mouse_input_rpt.movement_y(rel_y);
+
+ input_report.mouse(mouse_input_rpt.Build());
+ input_report.event_time(event_time.get());
+}
+
+// Static
+// Handle incoming connection requests from FIDL clients
+fidl::ServerBindingRef<fuchsia_input_report::InputDevice> InputSampleServer::BindDeviceClient(
+ driver::Logger& logger, async_dispatcher_t* dispatcher,
+ std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
+ input_report_readers,
+ fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
+ // Bind each connection request to a unique FIDL server instance
+ auto server_impl = std::make_unique<InputSampleServer>(logger, dispatcher, input_report_readers);
+ return fidl::BindServer(dispatcher, std::move(request), std::move(server_impl),
+ std::mem_fn(&InputSampleServer::OnUnbound));
+}
+
+// This method is called when a server connection is torn down.
+void InputSampleServer::OnUnbound(fidl::UnbindInfo info,
+ fidl::ServerEnd<fuchsia_input_report::InputDevice> server_end) {
+ if (info.is_peer_closed()) {
+ FDF_LOG(DEBUG, "Client disconnected");
+ } else if (!info.is_user_initiated()) {
+ FDF_LOG(ERROR, "Client connection unbound: %s", info.status_string());
+ }
+}
+
+// Protocol method for `fuchsia.input.report/InputDevice` to begin serving input reports
+void InputSampleServer::GetInputReportsReader(GetInputReportsReaderRequestView request,
+ GetInputReportsReaderCompleter::Sync& completer) {
+ auto reader_manager = input_report_readers_.lock();
+ if (!reader_manager) {
+ FDF_LOG(ERROR, "Unable to access InputReport reader manager.");
+ request->reader.Close(ZX_ERR_BAD_STATE);
+ return;
+ }
+
+ zx_status_t status = reader_manager->CreateReader(dispatcher_, std::move(request->reader));
+ if (status != ZX_OK) {
+ FDF_LOG(ERROR, "Could not create input report reader: %d", status);
+ request->reader.Close(ZX_ERR_BAD_STATE);
+ }
+}
+
+// Protocol method for `fuchsia.input.report/InputDevice` to return the device descriptor
+void InputSampleServer::GetDescriptor(GetDescriptorCompleter::Sync& completer) {
+ fidl::Arena allocator;
+ auto descriptor = fuchsia_input_report::wire::DeviceDescriptor::Builder(allocator);
+
+ fuchsia_input_report::wire::DeviceInfo device_info;
+ // We pick random VID/PIDs here, but these should be taken from the HID device,
+ // or defined in fuchsia.input.report/device_ids.fidl
+ device_info.vendor_id = 0x12345678;
+ device_info.product_id = 0x87654321;
+
+ fidl::VectorView<uint8_t> buttons(allocator, kMouseButtonCount);
+ buttons[0] = 0x01;
+ buttons[1] = 0x02;
+ buttons[2] = 0x03;
+
+ constexpr fuchsia_input_report::wire::Axis movement_x{
+ .range = {.min = -127, .max = 127},
+ .unit = {.type = fuchsia_input_report::wire::UnitType::kNone, .exponent = 0},
+ };
+ constexpr fuchsia_input_report::wire::Axis movement_y{
+ .range = {.min = -127, .max = 127},
+ .unit = {.type = fuchsia_input_report::wire::UnitType::kNone, .exponent = 0},
+ };
+
+ auto mouse_in_desc = fuchsia_input_report::wire::MouseInputDescriptor::Builder(allocator);
+ mouse_in_desc.buttons(buttons);
+ mouse_in_desc.movement_x(movement_x);
+ mouse_in_desc.movement_y(movement_y);
+
+ auto mouse_descriptor = fuchsia_input_report::wire::MouseDescriptor::Builder(allocator);
+ mouse_descriptor.input(mouse_in_desc.Build());
+ descriptor.mouse(mouse_descriptor.Build());
+ descriptor.device_info(device_info);
+
+ completer.Reply(descriptor.Build());
+}
+
+} // namespace input_sample
diff --git a/src/input_sample/input_server.h b/src/input_sample/input_server.h
new file mode 100644
index 0000000..de8e3b8
--- /dev/null
+++ b/src/input_sample/input_server.h
@@ -0,0 +1,77 @@
+// 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.
+
+#ifndef FUCHSIA_SDK_EXAMPLES_CC_INPUT_SAMPLE_INPUT_SERVER_H_
+#define FUCHSIA_SDK_EXAMPLES_CC_INPUT_SAMPLE_INPUT_SERVER_H_
+
+#include <fidl/fuchsia.input.report/cpp/wire.h>
+#include <lib/driver2/logger.h>
+#include <lib/input_report_reader/reader.h>
+
+namespace input_sample {
+
+constexpr uint8_t kMouseButtonCount = 3;
+
+// Used by the input report reader library to transform reports over FIDL
+struct SampleInputReport {
+ zx::time event_time;
+ uint8_t buttons = 0;
+ int8_t rel_x = 0;
+ int8_t rel_y = 0;
+
+ void ToFidlInputReport(
+ fidl::WireTableBuilder<::fuchsia_input_report::wire::InputReport>& input_report,
+ fidl::AnyArena& arena);
+};
+
+// FIDL server implementation for the `fuchsia.input.report/InputDevice` protocol
+class InputSampleServer : public fidl::WireServer<fuchsia_input_report::InputDevice> {
+ public:
+ InputSampleServer(driver::Logger& logger, async_dispatcher_t* dispatcher,
+ std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
+ input_report_readers)
+ : logger_(logger), dispatcher_(dispatcher), input_report_readers_(input_report_readers) {}
+
+ static fidl::ServerBindingRef<fuchsia_input_report::InputDevice> BindDeviceClient(
+ driver::Logger& logger, async_dispatcher_t* dispatcher,
+ std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
+ input_report_readers,
+ fidl::ServerEnd<fuchsia_input_report::InputDevice> request);
+
+ void OnUnbound(fidl::UnbindInfo info,
+ fidl::ServerEnd<fuchsia_input_report::InputDevice> server_end);
+
+ // fidl::WireServer<fuchsia_input_report::InputDevice>
+
+ void GetInputReportsReader(GetInputReportsReaderRequestView request,
+ GetInputReportsReaderCompleter::Sync& completer) override;
+
+ void GetDescriptor(GetDescriptorCompleter::Sync& completer) override;
+
+ void SendOutputReport(SendOutputReportRequestView request,
+ SendOutputReportCompleter::Sync& completer) override {
+ completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
+ }
+ void GetFeatureReport(GetFeatureReportCompleter::Sync& completer) override {
+ completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
+ }
+ void SetFeatureReport(SetFeatureReportRequestView request,
+ SetFeatureReportCompleter::Sync& completer) override {
+ completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
+ }
+ void GetInputReport(GetInputReportRequestView request,
+ GetInputReportCompleter::Sync& completer) override {
+ completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
+ }
+
+ private:
+ driver::Logger& logger_;
+ async_dispatcher_t* const dispatcher_;
+ std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
+ input_report_readers_;
+};
+
+} // namespace input_sample
+
+#endif // FUCHSIA_SDK_EXAMPLES_CC_INPUT_SAMPLE_INPUT_SERVER_H_