| OLD | NEW |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/hid/hid_connection.h" | 5 #include "device/hid/hid_connection.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "components/device_event_log/device_event_log.h" |
| 10 |
| 9 namespace device { | 11 namespace device { |
| 10 | 12 |
| 11 namespace { | 13 namespace { |
| 12 | 14 |
| 13 // Functor used to filter collections by report ID. | 15 // Functor used to filter collections by report ID. |
| 14 struct CollectionHasReportId { | 16 struct CollectionHasReportId { |
| 15 explicit CollectionHasReportId(uint8_t report_id) : report_id_(report_id) {} | 17 explicit CollectionHasReportId(uint8_t report_id) : report_id_(report_id) {} |
| 16 | 18 |
| 17 bool operator()(const HidCollectionInfo& info) const { | 19 bool operator()(const HidCollectionInfo& info) const { |
| 18 if (info.report_ids.size() == 0 || | 20 if (info.report_ids.size() == 0 || |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 DCHECK(thread_checker_.CalledOnValidThread()); | 77 DCHECK(thread_checker_.CalledOnValidThread()); |
| 76 DCHECK(!closed_); | 78 DCHECK(!closed_); |
| 77 | 79 |
| 78 PlatformClose(); | 80 PlatformClose(); |
| 79 closed_ = true; | 81 closed_ = true; |
| 80 } | 82 } |
| 81 | 83 |
| 82 void HidConnection::Read(const ReadCallback& callback) { | 84 void HidConnection::Read(const ReadCallback& callback) { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 85 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 if (device_info_->max_input_report_size() == 0) { | 86 if (device_info_->max_input_report_size() == 0) { |
| 85 VLOG(1) << "This device does not support input reports."; | 87 HID_LOG(USER) << "This device does not support input reports."; |
| 86 callback.Run(false, NULL, 0); | 88 callback.Run(false, NULL, 0); |
| 87 return; | 89 return; |
| 88 } | 90 } |
| 89 | 91 |
| 90 PlatformRead(callback); | 92 PlatformRead(callback); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, | 95 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, |
| 94 size_t size, | 96 size_t size, |
| 95 const WriteCallback& callback) { | 97 const WriteCallback& callback) { |
| 96 DCHECK(thread_checker_.CalledOnValidThread()); | 98 DCHECK(thread_checker_.CalledOnValidThread()); |
| 97 if (device_info_->max_output_report_size() == 0) { | 99 if (device_info_->max_output_report_size() == 0) { |
| 98 VLOG(1) << "This device does not support output reports."; | 100 HID_LOG(USER) << "This device does not support output reports."; |
| 99 callback.Run(false); | 101 callback.Run(false); |
| 100 return; | 102 return; |
| 101 } | 103 } |
| 102 if (size > device_info_->max_output_report_size() + 1) { | 104 if (size > device_info_->max_output_report_size() + 1) { |
| 103 VLOG(1) << "Output report buffer too long (" << size << " > " | 105 HID_LOG(USER) << "Output report buffer too long (" << size << " > " |
| 104 << (device_info_->max_output_report_size() + 1) << ")."; | 106 << (device_info_->max_output_report_size() + 1) << ")."; |
| 105 callback.Run(false); | 107 callback.Run(false); |
| 106 return; | 108 return; |
| 107 } | 109 } |
| 108 DCHECK_GE(size, 1u); | 110 DCHECK_GE(size, 1u); |
| 109 uint8_t report_id = buffer->data()[0]; | 111 uint8_t report_id = buffer->data()[0]; |
| 110 if (device_info_->has_report_id() != (report_id != 0)) { | 112 if (device_info_->has_report_id() != (report_id != 0)) { |
| 111 VLOG(1) << "Invalid output report ID."; | 113 HID_LOG(USER) << "Invalid output report ID."; |
| 112 callback.Run(false); | 114 callback.Run(false); |
| 113 return; | 115 return; |
| 114 } | 116 } |
| 115 if (IsReportIdProtected(report_id)) { | 117 if (IsReportIdProtected(report_id)) { |
| 116 VLOG(1) << "Attempt to set a protected output report."; | 118 HID_LOG(USER) << "Attempt to set a protected output report."; |
| 117 callback.Run(false); | 119 callback.Run(false); |
| 118 return; | 120 return; |
| 119 } | 121 } |
| 120 | 122 |
| 121 PlatformWrite(buffer, size, callback); | 123 PlatformWrite(buffer, size, callback); |
| 122 } | 124 } |
| 123 | 125 |
| 124 void HidConnection::GetFeatureReport(uint8_t report_id, | 126 void HidConnection::GetFeatureReport(uint8_t report_id, |
| 125 const ReadCallback& callback) { | 127 const ReadCallback& callback) { |
| 126 DCHECK(thread_checker_.CalledOnValidThread()); | 128 DCHECK(thread_checker_.CalledOnValidThread()); |
| 127 if (device_info_->max_feature_report_size() == 0) { | 129 if (device_info_->max_feature_report_size() == 0) { |
| 128 VLOG(1) << "This device does not support feature reports."; | 130 HID_LOG(USER) << "This device does not support feature reports."; |
| 129 callback.Run(false, NULL, 0); | 131 callback.Run(false, NULL, 0); |
| 130 return; | 132 return; |
| 131 } | 133 } |
| 132 if (device_info_->has_report_id() != (report_id != 0)) { | 134 if (device_info_->has_report_id() != (report_id != 0)) { |
| 133 VLOG(1) << "Invalid feature report ID."; | 135 HID_LOG(USER) << "Invalid feature report ID."; |
| 134 callback.Run(false, NULL, 0); | 136 callback.Run(false, NULL, 0); |
| 135 return; | 137 return; |
| 136 } | 138 } |
| 137 if (IsReportIdProtected(report_id)) { | 139 if (IsReportIdProtected(report_id)) { |
| 138 VLOG(1) << "Attempt to get a protected feature report."; | 140 HID_LOG(USER) << "Attempt to get a protected feature report."; |
| 139 callback.Run(false, NULL, 0); | 141 callback.Run(false, NULL, 0); |
| 140 return; | 142 return; |
| 141 } | 143 } |
| 142 | 144 |
| 143 PlatformGetFeatureReport(report_id, callback); | 145 PlatformGetFeatureReport(report_id, callback); |
| 144 } | 146 } |
| 145 | 147 |
| 146 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer, | 148 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer, |
| 147 size_t size, | 149 size_t size, |
| 148 const WriteCallback& callback) { | 150 const WriteCallback& callback) { |
| 149 DCHECK(thread_checker_.CalledOnValidThread()); | 151 DCHECK(thread_checker_.CalledOnValidThread()); |
| 150 if (device_info_->max_feature_report_size() == 0) { | 152 if (device_info_->max_feature_report_size() == 0) { |
| 151 VLOG(1) << "This device does not support feature reports."; | 153 HID_LOG(USER) << "This device does not support feature reports."; |
| 152 callback.Run(false); | 154 callback.Run(false); |
| 153 return; | 155 return; |
| 154 } | 156 } |
| 155 DCHECK_GE(size, 1u); | 157 DCHECK_GE(size, 1u); |
| 156 uint8_t report_id = buffer->data()[0]; | 158 uint8_t report_id = buffer->data()[0]; |
| 157 if (device_info_->has_report_id() != (report_id != 0)) { | 159 if (device_info_->has_report_id() != (report_id != 0)) { |
| 158 VLOG(1) << "Invalid feature report ID."; | 160 HID_LOG(USER) << "Invalid feature report ID."; |
| 159 callback.Run(false); | 161 callback.Run(false); |
| 160 return; | 162 return; |
| 161 } | 163 } |
| 162 if (IsReportIdProtected(report_id)) { | 164 if (IsReportIdProtected(report_id)) { |
| 163 VLOG(1) << "Attempt to set a protected feature report."; | 165 HID_LOG(USER) << "Attempt to set a protected feature report."; |
| 164 callback.Run(false); | 166 callback.Run(false); |
| 165 return; | 167 return; |
| 166 } | 168 } |
| 167 | 169 |
| 168 PlatformSendFeatureReport(buffer, size, callback); | 170 PlatformSendFeatureReport(buffer, size, callback); |
| 169 } | 171 } |
| 170 | 172 |
| 171 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer, | 173 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer, |
| 172 size_t size, | 174 size_t size, |
| 173 const ReadCallback& callback) { | 175 const ReadCallback& callback) { |
| 174 DCHECK_GE(size, 1u); | 176 DCHECK_GE(size, 1u); |
| 175 uint8_t report_id = buffer->data()[0]; | 177 uint8_t report_id = buffer->data()[0]; |
| 176 if (IsReportIdProtected(report_id)) { | 178 if (IsReportIdProtected(report_id)) { |
| 177 VLOG(1) << "Filtered a protected input report."; | 179 HID_LOG(EVENT) << "Filtered a protected input report."; |
| 178 return false; | 180 return false; |
| 179 } | 181 } |
| 180 | 182 |
| 181 callback.Run(true, buffer, size); | 183 callback.Run(true, buffer, size); |
| 182 return true; | 184 return true; |
| 183 } | 185 } |
| 184 | 186 |
| 185 bool HidConnection::IsReportIdProtected(uint8_t report_id) { | 187 bool HidConnection::IsReportIdProtected(uint8_t report_id) { |
| 186 HidCollectionInfo collection_info; | 188 HidCollectionInfo collection_info; |
| 187 if (FindCollectionByReportId(device_info_->collections(), report_id, | 189 if (FindCollectionByReportId(device_info_->collections(), report_id, |
| 188 &collection_info)) { | 190 &collection_info)) { |
| 189 return collection_info.usage.IsProtected(); | 191 return collection_info.usage.IsProtected(); |
| 190 } | 192 } |
| 191 | 193 |
| 192 return has_protected_collection(); | 194 return has_protected_collection(); |
| 193 } | 195 } |
| 194 | 196 |
| 195 PendingHidReport::PendingHidReport() {} | 197 PendingHidReport::PendingHidReport() {} |
| 196 | 198 |
| 197 PendingHidReport::~PendingHidReport() {} | 199 PendingHidReport::~PendingHidReport() {} |
| 198 | 200 |
| 199 PendingHidRead::PendingHidRead() {} | 201 PendingHidRead::PendingHidRead() {} |
| 200 | 202 |
| 201 PendingHidRead::~PendingHidRead() {} | 203 PendingHidRead::~PendingHidRead() {} |
| 202 | 204 |
| 203 } // namespace device | 205 } // namespace device |
| OLD | NEW |