Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(520)

Side by Side Diff: device/hid/hid_connection.cc

Issue 499713002: Don't pass buffers to HidConnection::Read because it knows the size. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed rockot@'s nits. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/hid/hid_connection.h ('k') | device/hid/hid_connection_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 namespace device { 9 namespace device {
10 10
11 namespace { 11 namespace {
12 12
13 // Functor used to filter collections by report ID. 13 // Functor used to filter collections by report ID.
14 struct CollectionHasReportId { 14 struct CollectionHasReportId {
15 explicit CollectionHasReportId(const uint8_t report_id) 15 explicit CollectionHasReportId(uint8_t report_id) : report_id_(report_id) {}
16 : report_id_(report_id) {}
17 16
18 bool operator()(const HidCollectionInfo& info) const { 17 bool operator()(const HidCollectionInfo& info) const {
19 if (info.report_ids.size() == 0 || 18 if (info.report_ids.size() == 0 ||
20 report_id_ == HidConnection::kNullReportId) 19 report_id_ == HidConnection::kNullReportId)
21 return false; 20 return false;
22 21
23 if (report_id_ == HidConnection::kAnyReportId) 22 if (report_id_ == HidConnection::kAnyReportId)
24 return true; 23 return true;
25 24
26 return std::find(info.report_ids.begin(), 25 return std::find(info.report_ids.begin(),
27 info.report_ids.end(), 26 info.report_ids.end(),
28 report_id_) != info.report_ids.end(); 27 report_id_) != info.report_ids.end();
29 } 28 }
30 29
31 private: 30 private:
32 const uint8_t report_id_; 31 const uint8_t report_id_;
33 }; 32 };
34 33
35 // Functor returning true if collection has a protected usage. 34 // Functor returning true if collection has a protected usage.
36 struct CollectionIsProtected { 35 struct CollectionIsProtected {
37 bool operator()(const HidCollectionInfo& info) const { 36 bool operator()(const HidCollectionInfo& info) const {
38 return info.usage.IsProtected(); 37 return info.usage.IsProtected();
39 } 38 }
40 }; 39 };
41 40
42 bool FindCollectionByReportId(const HidDeviceInfo& device_info, 41 bool FindCollectionByReportId(const HidDeviceInfo& device_info,
43 const uint8_t report_id, 42 uint8_t report_id,
44 HidCollectionInfo* collection_info) { 43 HidCollectionInfo* collection_info) {
45 std::vector<HidCollectionInfo>::const_iterator collection_iter = 44 std::vector<HidCollectionInfo>::const_iterator collection_iter =
46 std::find_if(device_info.collections.begin(), 45 std::find_if(device_info.collections.begin(),
47 device_info.collections.end(), 46 device_info.collections.end(),
48 CollectionHasReportId(report_id)); 47 CollectionHasReportId(report_id));
49 if (collection_iter != device_info.collections.end()) { 48 if (collection_iter != device_info.collections.end()) {
50 if (collection_info) { 49 if (collection_info) {
51 *collection_info = *collection_iter; 50 *collection_info = *collection_iter;
52 } 51 }
53 return true; 52 return true;
(...skipping 12 matching lines...) Expand all
66 65
67 HidConnection::HidConnection(const HidDeviceInfo& device_info) 66 HidConnection::HidConnection(const HidDeviceInfo& device_info)
68 : device_info_(device_info) { 67 : device_info_(device_info) {
69 has_protected_collection_ = HasProtectedCollection(device_info); 68 has_protected_collection_ = HasProtectedCollection(device_info);
70 } 69 }
71 70
72 HidConnection::~HidConnection() { 71 HidConnection::~HidConnection() {
73 DCHECK(thread_checker_.CalledOnValidThread()); 72 DCHECK(thread_checker_.CalledOnValidThread());
74 } 73 }
75 74
76 void HidConnection::Read(scoped_refptr<net::IOBufferWithSize> buffer, 75 void HidConnection::Read(const ReadCallback& callback) {
77 const IOCallback& callback) {
78 DCHECK(thread_checker_.CalledOnValidThread()); 76 DCHECK(thread_checker_.CalledOnValidThread());
79 if (device_info_.max_input_report_size == 0) { 77 if (device_info_.max_input_report_size == 0) {
80 // The device does not support input reports. 78 VLOG(1) << "This device does not support input reports.";
81 callback.Run(false, 0); 79 callback.Run(false, NULL, 0);
82 return;
83 }
84 int expected_buffer_size = device_info_.max_input_report_size;
85 if (device_info().has_report_id) {
86 expected_buffer_size++;
87 }
88 if (buffer->size() < expected_buffer_size) {
89 // Receive buffer is too small.
90 callback.Run(false, 0);
91 return; 80 return;
92 } 81 }
93 82
94 PlatformRead(buffer, callback); 83 PlatformRead(callback);
95 } 84 }
96 85
97 void HidConnection::Write(uint8_t report_id, 86 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer,
98 scoped_refptr<net::IOBufferWithSize> buffer, 87 size_t size,
99 const IOCallback& callback) { 88 const WriteCallback& callback) {
100 DCHECK(thread_checker_.CalledOnValidThread()); 89 DCHECK(thread_checker_.CalledOnValidThread());
101 if (device_info_.max_output_report_size == 0) { 90 if (device_info_.max_output_report_size == 0) {
102 // The device does not support output reports. 91 VLOG(1) << "This device does not support output reports.";
103 callback.Run(false, 0); 92 callback.Run(false);
93 return;
94 }
95 DCHECK_GE(size, 1u);
96 uint8_t report_id = buffer->data()[0];
97 if (device_info().has_report_id != (report_id != 0)) {
98 VLOG(1) << "Invalid output report ID.";
99 callback.Run(false);
104 return; 100 return;
105 } 101 }
106 if (IsReportIdProtected(report_id)) { 102 if (IsReportIdProtected(report_id)) {
107 callback.Run(false, 0); 103 VLOG(1) << "Attempt to set a protected output report.";
104 callback.Run(false);
108 return; 105 return;
109 } 106 }
110 107
111 PlatformWrite(report_id, buffer, callback); 108 PlatformWrite(buffer, size, callback);
112 } 109 }
113 110
114 void HidConnection::GetFeatureReport( 111 void HidConnection::GetFeatureReport(uint8_t report_id,
115 uint8_t report_id, 112 const ReadCallback& callback) {
116 scoped_refptr<net::IOBufferWithSize> buffer,
117 const IOCallback& callback) {
118 DCHECK(thread_checker_.CalledOnValidThread()); 113 DCHECK(thread_checker_.CalledOnValidThread());
119 if (device_info_.max_feature_report_size == 0) { 114 if (device_info_.max_feature_report_size == 0) {
120 // The device does not support feature reports. 115 VLOG(1) << "This device does not support feature reports.";
121 callback.Run(false, 0); 116 callback.Run(false, NULL, 0);
117 return;
118 }
119 if (device_info().has_report_id != (report_id != 0)) {
120 VLOG(1) << "Invalid feature report ID.";
121 callback.Run(false, NULL, 0);
122 return; 122 return;
123 } 123 }
124 if (IsReportIdProtected(report_id)) { 124 if (IsReportIdProtected(report_id)) {
125 callback.Run(false, 0); 125 VLOG(1) << "Attempt to get a protected feature report.";
126 return; 126 callback.Run(false, NULL, 0);
127 }
128 int expected_buffer_size = device_info_.max_feature_report_size;
129 if (device_info().has_report_id) {
130 expected_buffer_size++;
131 }
132 if (buffer->size() < expected_buffer_size) {
133 // Receive buffer is too small.
134 callback.Run(false, 0);
135 return; 127 return;
136 } 128 }
137 129
138 PlatformGetFeatureReport(report_id, buffer, callback); 130 PlatformGetFeatureReport(report_id, callback);
139 } 131 }
140 132
141 void HidConnection::SendFeatureReport( 133 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
142 uint8_t report_id, 134 size_t size,
143 scoped_refptr<net::IOBufferWithSize> buffer, 135 const WriteCallback& callback) {
144 const IOCallback& callback) {
145 DCHECK(thread_checker_.CalledOnValidThread()); 136 DCHECK(thread_checker_.CalledOnValidThread());
146 if (device_info_.max_feature_report_size == 0) { 137 if (device_info_.max_feature_report_size == 0) {
147 // The device does not support feature reports. 138 VLOG(1) << "This device does not support feature reports.";
148 callback.Run(false, 0); 139 callback.Run(false);
140 return;
141 }
142 DCHECK_GE(size, 1u);
143 uint8_t report_id = buffer->data()[0];
144 if (device_info().has_report_id != (report_id != 0)) {
145 VLOG(1) << "Invalid feature report ID.";
146 callback.Run(false);
149 return; 147 return;
150 } 148 }
151 if (IsReportIdProtected(report_id)) { 149 if (IsReportIdProtected(report_id)) {
152 callback.Run(false, 0); 150 VLOG(1) << "Attempt to set a protected feature report.";
151 callback.Run(false);
153 return; 152 return;
154 } 153 }
155 154
156 PlatformSendFeatureReport(report_id, buffer, callback); 155 PlatformSendFeatureReport(buffer, size, callback);
157 } 156 }
158 157
159 bool HidConnection::CompleteRead(scoped_refptr<net::IOBufferWithSize> buffer, 158 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer,
160 int bytes_read, 159 size_t size,
161 const IOCallback& callback) { 160 const ReadCallback& callback) {
162 DCHECK_LE(bytes_read, buffer->size()); 161 DCHECK_GE(size, 1u);
163 162 uint8_t report_id = buffer->data()[0];
164 if (bytes_read == 0 || IsReportIdProtected(buffer->data()[0])) { 163 if (IsReportIdProtected(report_id)) {
164 VLOG(1) << "Filtered a protected input report.";
165 return false; 165 return false;
166 } 166 }
167 167
168 callback.Run(true, bytes_read); 168 callback.Run(true, buffer, size);
169 return true; 169 return true;
170 } 170 }
171 171
172 bool HidConnection::IsReportIdProtected(const uint8_t report_id) { 172 bool HidConnection::IsReportIdProtected(uint8_t report_id) {
173 HidCollectionInfo collection_info; 173 HidCollectionInfo collection_info;
174 if (FindCollectionByReportId(device_info_, report_id, &collection_info)) { 174 if (FindCollectionByReportId(device_info_, report_id, &collection_info)) {
175 return collection_info.usage.IsProtected(); 175 return collection_info.usage.IsProtected();
176 } 176 }
177 177
178 return has_protected_collection(); 178 return has_protected_collection();
179 } 179 }
180 180
181 PendingHidReport::PendingHidReport() {} 181 PendingHidReport::PendingHidReport() {}
182 182
183 PendingHidReport::~PendingHidReport() {} 183 PendingHidReport::~PendingHidReport() {}
184 184
185 PendingHidRead::PendingHidRead() {} 185 PendingHidRead::PendingHidRead() {}
186 186
187 PendingHidRead::~PendingHidRead() {} 187 PendingHidRead::~PendingHidRead() {}
188 188
189 } // namespace device 189 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_connection.h ('k') | device/hid/hid_connection_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698