| // 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. |
| |
| #include "garnet/bin/ui/input_reader/buttons.h" |
| |
| #include <hid-parser/parser.h> |
| #include <hid-parser/report.h> |
| #include <hid-parser/units.h> |
| #include <hid-parser/usages.h> |
| #include <src/lib/fxl/logging.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| |
| #include <vector> |
| |
| namespace ui_input { |
| |
| bool Buttons::ParseReportDescriptor( |
| const hid::ReportDescriptor& report_descriptor, |
| Descriptor* device_descriptor) { |
| FXL_CHECK(device_descriptor); |
| |
| hid::Attributes volume_up = {}; |
| hid::Attributes volume_down = {}; |
| hid::Attributes reset = {}; |
| hid::Attributes phone_mute = {}; |
| uint32_t caps = 0; |
| |
| for (size_t i = 0; i < report_descriptor.input_count; i++) { |
| const hid::ReportField& field = report_descriptor.input_fields[i]; |
| |
| if (field.attr.usage == hid::USAGE(hid::usage::Page::kConsumer, |
| hid::usage::Consumer::kVolumeUp)) { |
| volume_up = field.attr; |
| caps |= Capabilities::VOLUME_UP; |
| } else if (field.attr.usage == |
| hid::USAGE(hid::usage::Page::kConsumer, |
| hid::usage::Consumer::kVolumeDown)) { |
| volume_down = field.attr; |
| caps |= Capabilities::VOLUME_DOWN; |
| } else if (field.attr.usage == hid::USAGE(hid::usage::Page::kConsumer, |
| hid::usage::Consumer::kReset)) { |
| reset = field.attr; |
| caps |= Capabilities::RESET; |
| } else if (field.attr.usage == |
| hid::USAGE(hid::usage::Page::kTelephony, |
| hid::usage::Telephony::kPhoneMute)) { |
| phone_mute = field.attr; |
| caps |= Capabilities::PHONE_MUTE; |
| } |
| } |
| |
| if (caps == 0) { |
| FXL_LOG(INFO) << "Buttons report descriptor: Buttons has no capabilities"; |
| return false; |
| } |
| |
| volume_up_ = volume_up; |
| volume_down_ = volume_down; |
| reset_ = reset; |
| phone_mute_ = phone_mute; |
| |
| report_size_ = report_descriptor.input_byte_sz; |
| report_id_ = report_descriptor.report_id; |
| capabilities_ = caps; |
| |
| // Set the device descriptor. |
| device_descriptor->protocol = Protocol::MediaButtons; |
| device_descriptor->has_media_buttons = true; |
| device_descriptor->buttons_descriptor = |
| fuchsia::ui::input::MediaButtonsDescriptor::New(); |
| if (caps & Capabilities::PHONE_MUTE) { |
| device_descriptor->buttons_descriptor->buttons |= |
| fuchsia::ui::input::kMicMute; |
| } |
| if (caps & Capabilities::VOLUME_UP) { |
| device_descriptor->buttons_descriptor->buttons |= |
| fuchsia::ui::input::kVolumeUp; |
| } |
| if (caps & Capabilities::VOLUME_DOWN) { |
| device_descriptor->buttons_descriptor->buttons |= |
| fuchsia::ui::input::kVolumeDown; |
| } |
| if (caps & Capabilities::RESET) { |
| device_descriptor->buttons_descriptor->buttons |= |
| fuchsia::ui::input::kReset; |
| } |
| return true; |
| } |
| |
| bool Buttons::ParseReport(const uint8_t* data, size_t len, |
| fuchsia::ui::input::InputReport* report) { |
| FXL_CHECK(report); |
| FXL_CHECK(report->media_buttons); |
| double volume_up = 0; |
| double volume_down = 0; |
| double reset = 0; |
| double mic_mute = 0; |
| |
| if (report_size_ != len) { |
| FXL_LOG(INFO) << "Sensor report: Expected size " << report_size_ |
| << "Received size " << len; |
| return false; |
| } |
| |
| if (capabilities_ & Capabilities::VOLUME_UP) { |
| if (!hid::ExtractAsUnit(data, len, volume_up_, &volume_up)) { |
| FXL_LOG(INFO) << "Sensor report: Failed to parse volume"; |
| return false; |
| } |
| } |
| if (capabilities_ & Capabilities::VOLUME_DOWN) { |
| if (!hid::ExtractAsUnit(data, len, volume_down_, &volume_down)) { |
| FXL_LOG(INFO) << "Sensor report: Failed to parse volume"; |
| return false; |
| } |
| } |
| if (capabilities_ & Capabilities::RESET) { |
| if (!hid::ExtractAsUnit(data, len, reset_, &reset)) { |
| FXL_LOG(INFO) << "Sensor report: Failed to parse reset"; |
| return false; |
| } |
| } |
| if (capabilities_ & Capabilities::PHONE_MUTE) { |
| if (!hid::ExtractAsUnit(data, len, phone_mute_, &mic_mute)) { |
| FXL_LOG(INFO) << "Sensor report: Failed to parse phone_mute"; |
| return false; |
| } |
| } |
| |
| report->media_buttons->mic_mute = 0; |
| report->media_buttons->volume_up = 0; |
| report->media_buttons->volume_down = 0; |
| report->media_buttons->reset = 0; |
| |
| if (capabilities_ & Capabilities::PHONE_MUTE) { |
| report->media_buttons->mic_mute = (mic_mute > 0); |
| } |
| if (capabilities_ & Capabilities::VOLUME_UP) { |
| report->media_buttons->volume_up = (volume_up > 0); |
| } |
| if (capabilities_ & Capabilities::VOLUME_DOWN) { |
| report->media_buttons->volume_down = (volume_down > 0); |
| } |
| if (capabilities_ & Capabilities::RESET) { |
| report->media_buttons->reset = (reset > 0); |
| } |
| |
| return true; |
| } |
| |
| } // namespace ui_input |