blob: aa45942f21af79c9c102b9f2fd053215acb8f1a2 [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.
#ifndef SRC_UI_LIB_INPUT_REPORT_INSTANCE_DRIVER_INSTANCE_H_
#define SRC_UI_LIB_INPUT_REPORT_INSTANCE_DRIVER_INSTANCE_H_
#include <array>
#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/mutex.h>
#include <fbl/ring_buffer.h>
#include "src/ui/lib/hid-input-report/descriptors.h"
#include "src/ui/lib/hid-input-report/device.h"
#include "src/ui/lib/hid-input-report/fidl.h"
#include "src/ui/lib/hid-input-report/mouse.h"
namespace input_report_instance {
namespace fuchsia_input_report = ::llcpp::fuchsia::input::report;
class InputReportInstance;
class InputReportBase {
public:
virtual void RemoveInstanceFromList(InputReportInstance* instance) = 0;
virtual const hid_input_report::ReportDescriptor* GetDescriptors(size_t* size) = 0;
virtual zx_status_t SendOutputReport(fuchsia_input_report::OutputReport report) = 0;
};
using InstanceDeviceType = ddk::Device<InputReportInstance, ddk::Closable, ddk::Messageable>;
class InputReportInstance : public InstanceDeviceType,
fuchsia_input_report::InputDevice::Interface,
public fbl::DoublyLinkedListable<InputReportInstance*> {
public:
InputReportInstance(zx_device_t* parent) : InstanceDeviceType(parent) {}
// The |InputReportBase| is responsible for creating |InputReportInstance| and adding it to
// the LinkedList of instances that are owned by the base. The Instance is a child driver
// of the base and can not outlive the base. The Instance driver must remove itself from
// the LinkedList of it's Base driver during DdkClose.
zx_status_t Bind(InputReportBase* base);
zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);
void DdkRelease() { delete this; }
zx_status_t DdkClose(uint32_t flags);
void ReceiveReport(const hid_input_report::InputReport& input_report);
// FIDL functions.
void GetReportsEvent(GetReportsEventCompleter::Sync _completer);
void GetReports(GetReportsCompleter::Sync _completer);
void GetDescriptor(GetDescriptorCompleter::Sync _completer);
void SendOutputReport(::llcpp::fuchsia::input::report::OutputReport report,
SendOutputReportCompleter::Sync completer);
private:
fbl::Mutex report_lock_;
zx::event reports_event_ __TA_GUARDED(report_lock_);
// The ring buffer stores the hid reports as they are sent to the instance.
fbl::RingBuffer<hid_input_report::InputReport, fuchsia_input_report::MAX_DEVICE_REPORT_COUNT>
reports_data_ __TA_GUARDED(report_lock_);
// These two arrays store the information to build the FIDL tables.
std::array<hid_input_report::FidlInputReport, fuchsia_input_report::MAX_DEVICE_REPORT_COUNT>
reports_fidl_data_ __TA_GUARDED(report_lock_);
std::array<fuchsia_input_report::InputReport, fuchsia_input_report::MAX_DEVICE_REPORT_COUNT>
reports_ __TA_GUARDED(report_lock_);
InputReportBase* base_ = nullptr;
};
} // namespace input_report_instance
#endif // SRC_UI_LIB_INPUT_REPORT_INSTANCE_DRIVER_INSTANCE_H_