blob: 435b571467c5df46693f3ba794a90bccb3e42e87 [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.
#include "src/ui/lib/input_reader/buttons.h"
#include <stdint.h>
#include <stdio.h>
#include <vector>
#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"
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