Chromium Code Reviews| Index: device/hid/hid_connection.cc |
| diff --git a/device/hid/hid_connection.cc b/device/hid/hid_connection.cc |
| index c134bf2702e96aca40ca0cc58b376d9b151a1aa2..2f657d9f990272fe123efaa430249eadd9c33a89 100644 |
| --- a/device/hid/hid_connection.cc |
| +++ b/device/hid/hid_connection.cc |
| @@ -4,8 +4,197 @@ |
| #include "device/hid/hid_connection.h" |
| +#include <algorithm> |
| + |
| namespace device { |
| +namespace { |
| + |
| +const uint8_t kNullReportId = 0x00; |
| +const uint8_t kAnyReportId = 0xFF; |
|
Ken Rockot(use gerrit already)
2014/06/27 14:50:22
How about moving these constants to hid_connection
jracle (use Gerrit)
2014/06/27 20:07:06
Makes sense.
On 2014/06/27 14:50:22, Ken Rockot w
|
| + |
| +struct CollectionHasReportId { |
|
Ken Rockot(use gerrit already)
2014/06/27 14:50:22
Maybe a brief comment that this is a functor used
jracle (use Gerrit)
2014/06/27 20:07:06
Sure.
On 2014/06/27 14:50:22, Ken Rockot wrote:
|
| + explicit CollectionHasReportId(const uint8_t report_id) |
| + : report_id_(report_id) {} |
| + |
| + bool operator()(const HidCollectionInfo& info) const { |
| + if (info.report_ids.size() == 0 || report_id_ == kNullReportId) |
| + return false; |
| + |
| + if (report_id_ == kAnyReportId) |
| + return true; |
| + |
| + return std::find(info.report_ids.begin(), |
| + info.report_ids.end(), |
| + report_id_) != info.report_ids.end(); |
| + } |
| + |
| + private: |
| + const uint8_t report_id_; |
| +}; |
| + |
| +struct CollectionIsProtected { |
|
Ken Rockot(use gerrit already)
2014/06/27 14:50:22
Brief comment here as well.
jracle (use Gerrit)
2014/06/27 20:07:06
OK.
On 2014/06/27 14:50:22, Ken Rockot wrote:
|
| + bool operator()(const HidCollectionInfo& info) const { |
| + return info.usage.IsProtected(); |
| + } |
| +}; |
| + |
| +bool FindCollectionByReportId(const HidDeviceInfo& device_info, |
| + const uint8_t report_id, |
| + HidCollectionInfo* collection_info) { |
| + std::vector<HidCollectionInfo>::const_iterator collection_iter = |
| + std::find_if(device_info.collections.begin(), |
| + device_info.collections.end(), |
| + CollectionHasReportId(report_id)); |
| + if (collection_iter != device_info.collections.end()) { |
| + if (collection_info) { |
| + *collection_info = *collection_iter; |
| + } |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +bool HasReportId(const HidDeviceInfo& device_info) { |
| + return FindCollectionByReportId(device_info, kAnyReportId, NULL); |
| +} |
| + |
| +bool HasProtectedCollection(const HidDeviceInfo& device_info) { |
| + return std::find_if(device_info.collections.begin(), |
| + device_info.collections.end(), |
| + CollectionIsProtected()) != device_info.collections.end(); |
| +} |
| + |
| +} // namespace |
| + |
| +HidConnection::HidConnection(const HidDeviceInfo& device_info) |
| + : device_info_(device_info) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
|
Ken Rockot(use gerrit already)
2014/06/27 14:50:22
Actually I realize this was in the other implement
jracle (use Gerrit)
2014/06/27 20:07:06
Sorry, got it now..! Useless indeed
On 2014/06/27
|
| + has_protected_collection_ = HasProtectedCollection(device_info); |
| + has_report_id_ = HasReportId(device_info); |
| +} |
| + |
| +HidConnection::~HidConnection() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| +} |
| + |
| +void HidConnection::Read(scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& 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 (!has_report_id()) { |
| + expected_buffer_size--; |
| + } |
| + if (buffer->size() < expected_buffer_size) { |
| + // Receive buffer is too small. |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + |
| + PlatformRead(buffer, callback); |
| +} |
| + |
| +void HidConnection::Write(uint8_t report_id, |
| + scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& callback) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + if (device_info_.max_output_report_size == 0) { |
| + // The device does not support output reports. |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + if (IsReportIdProtected(report_id)) { |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + |
| + PlatformWrite(report_id, buffer, callback); |
| +} |
| + |
| +void HidConnection::GetFeatureReport( |
| + uint8_t report_id, |
| + scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& callback) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + if (device_info_.max_feature_report_size == 0) { |
| + // The device does not support feature reports. |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + if (IsReportIdProtected(report_id)) { |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + int expected_buffer_size = device_info_.max_feature_report_size; |
| + if (!has_report_id()) { |
| + expected_buffer_size--; |
| + } |
| + if (buffer->size() < expected_buffer_size) { |
| + // Receive buffer is too small. |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + |
| + PlatformGetFeatureReport(report_id, buffer, callback); |
| +} |
| + |
| +void HidConnection::SendFeatureReport( |
| + uint8_t report_id, |
| + scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& callback) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + if (device_info_.max_feature_report_size == 0) { |
| + // The device does not support feature reports. |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + if (IsReportIdProtected(report_id)) { |
| + callback.Run(false, 0); |
| + return; |
| + } |
| + |
| + PlatformSendFeatureReport(report_id, buffer, callback); |
| +} |
| + |
| +void HidConnection::CompleteRead(scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& callback) { |
| + if (FilterInputReport(buffer, callback)) { |
| + return; |
| + } |
| + |
| + callback.Run(true, buffer->size()); |
| +} |
| + |
| +bool HidConnection::FilterInputReport( |
| + scoped_refptr<net::IOBufferWithSize> buffer, |
| + const IOCallback& callback) { |
| + if (buffer->size() == 0) { |
| + return false; |
| + } |
| + |
| + if (IsReportIdProtected(buffer->data()[0])) { |
| + callback.Run(true, 0); |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +bool HidConnection::IsReportIdProtected(const uint8_t report_id) { |
| + HidCollectionInfo collection_info; |
| + if (FindCollectionByReportId(device_info_, report_id, &collection_info)) { |
| + return collection_info.usage.IsProtected(); |
| + } |
| + |
| + return has_protected_collection(); |
| +} |
| + |
| PendingHidReport::PendingHidReport() {} |
| PendingHidReport::~PendingHidReport() {} |
| @@ -14,9 +203,4 @@ PendingHidRead::PendingHidRead() {} |
| PendingHidRead::~PendingHidRead() {} |
| -HidConnection::HidConnection(const HidDeviceInfo& device_info) |
| - : device_info_(device_info) {} |
| - |
| -HidConnection::~HidConnection() {} |
| - |
| } // namespace device |