blob: a0f04e67cfa4ca58fb0e6e1965eb76c9746fb640 [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_INPUT_LIB_HID_INPUT_REPORT_DEVICE_H_
#define SRC_UI_INPUT_LIB_HID_INPUT_REPORT_DEVICE_H_
#include <lib/hid-parser/parser.h>
#include <lib/hid-parser/report.h>
#include <lib/hid-parser/units.h>
#include <stddef.h>
#include <stdint.h>
#include "src/ui/input/lib/hid-input-report/axis.h"
namespace hid_input_report {
enum class ParseResult : uint32_t {
kOk = 0,
kNoMemory = 1,
kTooManyItems = 2,
kReportSizeMismatch = 3,
kNoCollection = 4,
kBadReport = 5,
kNotImplemented = 6,
kItemNotFound = 7,
};
inline const char* ParseResultGetString(ParseResult result) {
switch (result) {
case ParseResult::kOk:
return "kOk";
case ParseResult::kNoMemory:
return "kNoMemory";
case ParseResult::kTooManyItems:
return "kTooManyItems";
case ParseResult::kReportSizeMismatch:
return "kReportSizeMismatch";
case ParseResult::kNoCollection:
return "kNoCollection";
case ParseResult::kBadReport:
return "kBadReport";
case ParseResult::kNotImplemented:
return "kNotImplemented";
case ParseResult::kItemNotFound:
return "kItemNotFound";
default:
return "Unrecognized ParseResult";
}
}
enum class DeviceType : uint32_t {
kMouse = 1,
kSensor = 2,
kTouch = 3,
kKeyboard = 4,
kConsumerControl = 5,
};
template <typename T>
fidl::ObjectView<T> Extract(const uint8_t* data, size_t len, hid::Attributes attr,
fidl::AnyArena& allocator) {
double value;
if (!hid::ExtractAsUnitType(data, len, attr, &value)) {
return fidl::ObjectView<T>();
}
return fidl::ObjectView<T>(allocator, value);
}
class Device {
public:
virtual ~Device() = default;
virtual ParseResult ParseReportDescriptor(const hid::ReportDescriptor& hid_report_descriptor) = 0;
ParseResult SetOutputReport(const fuchsia_input_report::wire::OutputReport* report, uint8_t* data,
size_t data_size, size_t* data_out_size) {
return OutputReportId().has_value()
? SetOutputReportInternal(report, data, data_size, data_out_size)
: ParseResult::kNotImplemented;
}
virtual ParseResult CreateDescriptor(fidl::AnyArena& allocator,
fuchsia_input_report::wire::DeviceDescriptor& descriptor) {
return ParseResult::kNotImplemented;
}
ParseResult ParseFeatureReport(const uint8_t* data, size_t len, fidl::AnyArena& allocator,
fuchsia_input_report::wire::FeatureReport& feature_report) {
return FeatureReportId().has_value()
? ParseFeatureReportInternal(data, len, allocator, feature_report)
: ParseResult::kNotImplemented;
}
ParseResult SetFeatureReport(const fuchsia_input_report::wire::FeatureReport* report,
uint8_t* data, size_t data_size, size_t* data_out_size) {
return FeatureReportId().has_value()
? SetFeatureReportInternal(report, data, data_size, data_out_size)
: ParseResult::kNotImplemented;
}
ParseResult ParseInputReport(const uint8_t* data, size_t len, fidl::AnyArena& allocator,
fuchsia_input_report::wire::InputReport& input_report) {
return InputReportId().has_value()
? ParseInputReportInternal(data, len, allocator, input_report)
: ParseResult::kNotImplemented;
}
virtual std::optional<uint8_t> InputReportId() const { return std::nullopt; }
virtual std::optional<uint8_t> OutputReportId() const { return std::nullopt; }
virtual std::optional<uint8_t> FeatureReportId() const { return std::nullopt; }
virtual DeviceType GetDeviceType() const = 0;
private:
virtual ParseResult SetOutputReportInternal(
const fuchsia_input_report::wire::OutputReport* report, uint8_t* data, size_t data_size,
size_t* data_out_size) {
return ParseResult::kNotImplemented;
}
virtual ParseResult ParseFeatureReportInternal(
const uint8_t* data, size_t len, fidl::AnyArena& allocator,
fuchsia_input_report::wire::FeatureReport& feature_report) {
return ParseResult::kNotImplemented;
}
virtual ParseResult SetFeatureReportInternal(
const fuchsia_input_report::wire::FeatureReport* report, uint8_t* data, size_t data_size,
size_t* data_out_size) {
return ParseResult::kNotImplemented;
}
virtual ParseResult ParseInputReportInternal(
const uint8_t* data, size_t len, fidl::AnyArena& allocator,
fuchsia_input_report::wire::InputReport& input_report) {
return ParseResult::kNotImplemented;
}
};
// Create `out_device` from a HID descriptor. `out_device` is returned fully formed,
// it does not need any additional initialization.
ParseResult CreateDevice(const hid::ReportDescriptor* descriptor,
std::unique_ptr<Device>* out_device);
} // namespace hid_input_report
#endif // SRC_UI_INPUT_LIB_HID_INPUT_REPORT_DEVICE_H_