| Index: device/hid/hid_connection.cc
|
| diff --git a/device/hid/hid_connection.cc b/device/hid/hid_connection.cc
|
| index c916d6aae72373e9202f302f93ba138b273d19e1..5df2a016bf80e3e9586f1e1852132caa64c87f91 100644
|
| --- a/device/hid/hid_connection.cc
|
| +++ b/device/hid/hid_connection.cc
|
| @@ -12,8 +12,7 @@ namespace {
|
|
|
| // Functor used to filter collections by report ID.
|
| struct CollectionHasReportId {
|
| - explicit CollectionHasReportId(const uint8_t report_id)
|
| - : report_id_(report_id) {}
|
| + explicit CollectionHasReportId(uint8_t report_id) : report_id_(report_id) {}
|
|
|
| bool operator()(const HidCollectionInfo& info) const {
|
| if (info.report_ids.size() == 0 ||
|
| @@ -40,7 +39,7 @@ struct CollectionIsProtected {
|
| };
|
|
|
| bool FindCollectionByReportId(const HidDeviceInfo& device_info,
|
| - const uint8_t report_id,
|
| + uint8_t report_id,
|
| HidCollectionInfo* collection_info) {
|
| std::vector<HidCollectionInfo>::const_iterator collection_iter =
|
| std::find_if(device_info.collections.begin(),
|
| @@ -73,103 +72,104 @@ HidConnection::~HidConnection() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| }
|
|
|
| -void HidConnection::Read(scoped_refptr<net::IOBufferWithSize> buffer,
|
| - const IOCallback& callback) {
|
| +void HidConnection::Read(const ReadCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| if (device_info_.max_input_report_size == 0) {
|
| - // The device does not support input reports.
|
| - callback.Run(false, 0);
|
| - return;
|
| - }
|
| - int expected_buffer_size = device_info_.max_input_report_size;
|
| - if (device_info().has_report_id) {
|
| - expected_buffer_size++;
|
| - }
|
| - if (buffer->size() < expected_buffer_size) {
|
| - // Receive buffer is too small.
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "This device does not support input reports.";
|
| + callback.Run(false, NULL, 0);
|
| return;
|
| }
|
|
|
| - PlatformRead(buffer, callback);
|
| + PlatformRead(callback);
|
| }
|
|
|
| -void HidConnection::Write(uint8_t report_id,
|
| - scoped_refptr<net::IOBufferWithSize> buffer,
|
| - const IOCallback& callback) {
|
| +void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer,
|
| + size_t size,
|
| + const WriteCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| if (device_info_.max_output_report_size == 0) {
|
| - // The device does not support output reports.
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "This device does not support output reports.";
|
| + callback.Run(false);
|
| + return;
|
| + }
|
| + DCHECK_GE(size, 1u);
|
| + uint8_t report_id = buffer->data()[0];
|
| + if (device_info().has_report_id != (report_id != 0)) {
|
| + VLOG(1) << "Invalid output report ID.";
|
| + callback.Run(false);
|
| return;
|
| }
|
| if (IsReportIdProtected(report_id)) {
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "Attempt to set a protected output report.";
|
| + callback.Run(false);
|
| return;
|
| }
|
|
|
| - PlatformWrite(report_id, buffer, callback);
|
| + PlatformWrite(buffer, size, callback);
|
| }
|
|
|
| -void HidConnection::GetFeatureReport(
|
| - uint8_t report_id,
|
| - scoped_refptr<net::IOBufferWithSize> buffer,
|
| - const IOCallback& callback) {
|
| +void HidConnection::GetFeatureReport(uint8_t report_id,
|
| + const ReadCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| if (device_info_.max_feature_report_size == 0) {
|
| - // The device does not support feature reports.
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "This device does not support feature reports.";
|
| + callback.Run(false, NULL, 0);
|
| return;
|
| }
|
| - if (IsReportIdProtected(report_id)) {
|
| - callback.Run(false, 0);
|
| + if (device_info().has_report_id != (report_id != 0)) {
|
| + VLOG(1) << "Invalid feature report ID.";
|
| + callback.Run(false, NULL, 0);
|
| return;
|
| }
|
| - int expected_buffer_size = device_info_.max_feature_report_size;
|
| - if (device_info().has_report_id) {
|
| - expected_buffer_size++;
|
| - }
|
| - if (buffer->size() < expected_buffer_size) {
|
| - // Receive buffer is too small.
|
| - callback.Run(false, 0);
|
| + if (IsReportIdProtected(report_id)) {
|
| + VLOG(1) << "Attempt to get a protected feature report.";
|
| + callback.Run(false, NULL, 0);
|
| return;
|
| }
|
|
|
| - PlatformGetFeatureReport(report_id, buffer, callback);
|
| + PlatformGetFeatureReport(report_id, callback);
|
| }
|
|
|
| -void HidConnection::SendFeatureReport(
|
| - uint8_t report_id,
|
| - scoped_refptr<net::IOBufferWithSize> buffer,
|
| - const IOCallback& callback) {
|
| +void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
|
| + size_t size,
|
| + const WriteCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| if (device_info_.max_feature_report_size == 0) {
|
| - // The device does not support feature reports.
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "This device does not support feature reports.";
|
| + callback.Run(false);
|
| + return;
|
| + }
|
| + DCHECK_GE(size, 1u);
|
| + uint8_t report_id = buffer->data()[0];
|
| + if (device_info().has_report_id != (report_id != 0)) {
|
| + VLOG(1) << "Invalid feature report ID.";
|
| + callback.Run(false);
|
| return;
|
| }
|
| if (IsReportIdProtected(report_id)) {
|
| - callback.Run(false, 0);
|
| + VLOG(1) << "Attempt to set a protected feature report.";
|
| + callback.Run(false);
|
| return;
|
| }
|
|
|
| - PlatformSendFeatureReport(report_id, buffer, callback);
|
| + PlatformSendFeatureReport(buffer, size, callback);
|
| }
|
|
|
| -bool HidConnection::CompleteRead(scoped_refptr<net::IOBufferWithSize> buffer,
|
| - int bytes_read,
|
| - const IOCallback& callback) {
|
| - DCHECK_LE(bytes_read, buffer->size());
|
| -
|
| - if (bytes_read == 0 || IsReportIdProtected(buffer->data()[0])) {
|
| +bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer,
|
| + size_t size,
|
| + const ReadCallback& callback) {
|
| + DCHECK_GE(size, 1u);
|
| + uint8_t report_id = buffer->data()[0];
|
| + if (IsReportIdProtected(report_id)) {
|
| + VLOG(1) << "Filtered a protected input report.";
|
| return false;
|
| }
|
|
|
| - callback.Run(true, bytes_read);
|
| + callback.Run(true, buffer, size);
|
| return true;
|
| }
|
|
|
| -bool HidConnection::IsReportIdProtected(const uint8_t report_id) {
|
| +bool HidConnection::IsReportIdProtected(uint8_t report_id) {
|
| HidCollectionInfo collection_info;
|
| if (FindCollectionByReportId(device_info_, report_id, &collection_info)) {
|
| return collection_info.usage.IsProtected();
|
|
|