blob: 79a6b103cfe1cea97cbdf085e952c245ac011116 [file] [log] [blame]
// Copyright 2016 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_READER_INPUT_INTERPRETER_H_
#define SRC_UI_LIB_INPUT_READER_INPUT_INTERPRETER_H_
#include <fuchsia/hardware/input/c/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <lib/zx/event.h>
#include <zircon/types.h>
#include <array>
#include <string>
#include <vector>
#include <hid/acer12.h>
#include "src/ui/lib/input_reader/buttons.h"
#include "src/ui/lib/input_reader/hardcoded.h"
#include "src/ui/lib/input_reader/hid_decoder.h"
#include "src/ui/lib/input_reader/keyboard.h"
#include "src/ui/lib/input_reader/pointer.h"
#include "src/ui/lib/input_reader/protocols.h"
#include "src/ui/lib/input_reader/sensor.h"
#include "src/ui/lib/input_reader/stylus.h"
#include "src/ui/lib/input_reader/touchpad.h"
#include "src/ui/lib/input_reader/touchscreen.h"
namespace ui_input {
// Each InputInterpreter instance observes and routes events coming in from one
// file descriptor under /dev/class/input. Each file descriptor may multiplex
// events from one or more physical devices, though typically there is a 1:1
// correspondence for input devices like keyboards and mice. Sensors are an
// atypical case, where many sensors have their events routed through one
// logical file descriptor, since they share a hardware FIFO queue.
class InputInterpreter {
public:
enum ReportType {
kKeyboard,
kMouse,
kStylus,
kTouchscreen,
};
static std::unique_ptr<InputInterpreter> Open(int dirfd, std::string filename,
fuchsia::ui::input::InputDeviceRegistry* registry);
InputInterpreter(std::unique_ptr<HidDecoder> hid_decoder,
fuchsia::ui::input::InputDeviceRegistry* registry);
~InputInterpreter();
bool Initialize();
bool Read(bool discard);
const std::string& name() const { return hid_decoder_->name(); }
zx_handle_t handle() { return event_.get(); }
private:
// Each InputDevice represents a logical device exposed by a HID device.
// Some HID devices have multiple InputDevices (e.g: A keyboard/mouse
// combo with a single USB cable).
struct InputDevice {
// The Device struct that parses the reports.
std::unique_ptr<Device> device;
// The structured report that is parsed by |device|.
fuchsia::ui::input::InputReportPtr report;
// Holds descriptions of what this device contains.
Device::Descriptor descriptor;
// The pointer where reports are sent to by this device.
fuchsia::ui::input::InputDevicePtr input_device;
};
Protocol ExtractProtocol(hid::Usage input);
// This function takes a ReportDescriptor that describes an input report.
// It will use the report descriptor to create a matching InputDevice. If it
// returns true then the |devices_| array will have been extended by one extra
// |InputDevice|.
bool ParseHidInputReportDescriptor(const hid::ReportDescriptor* input_desc);
// Takes in a ReportDescriptor representing a feature report and sends it
// to a the device. Should be called on each feature report descriptor in
// order to initialize the device. Returns true if the report descriptor
// doesn't match, or if it matches and successfully initializes the device.
// Only returns false if there is an error.
bool ParseHidFeatureReportDescriptor(const hid::ReportDescriptor& report_desc);
// Helper function called during Init() that determines which protocol
// is going to be used. It is responsible for reading the HID device's
// Report Descriptor and determining what type of device it is.
// If it returns true then either |protocol_| will have been set
// (if the device is a hardcoded device), or |devices_| array will contain
// the full list of generic devices the HID report descriptor describes.
bool ParseProtocol();
void NotifyRegistry();
// Dispatches the report in |device|.
void DispatchReport(InputDevice* device);
fuchsia::ui::input::InputDeviceRegistry* registry_;
zx::event event_;
// The array of Devices that are managed by this InputInterpreter.
std::vector<InputDevice> devices_;
std::unique_ptr<HidDecoder> hid_decoder_;
// The descriptor memory is owned by the hid library. The InputInterpreter is responsible for
// calling into the hid library to free |hid_descriptor_|.
hid::DeviceDescriptor* hid_descriptor_ = nullptr;
Protocol protocol_;
Hardcoded hardcoded_ = {};
uint32_t trace_id_ = 0;
uint32_t reports_read_ = 0;
};
} // namespace ui_input
#endif // SRC_UI_LIB_INPUT_READER_INPUT_INTERPRETER_H_