[SyncFS] Run RemoteToLocalSyncer as a background task
[chromium-blink-merge.git] / device / hid / hid_connection.cc
blob5df2a016bf80e3e9586f1e1852132caa64c87f91
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
3 // found in the LICENSE file.
5 #include "device/hid/hid_connection.h"
7 #include <algorithm>
9 namespace device {
11 namespace {
13 // Functor used to filter collections by report ID.
14 struct CollectionHasReportId {
15 explicit CollectionHasReportId(uint8_t report_id) : report_id_(report_id) {}
17 bool operator()(const HidCollectionInfo& info) const {
18 if (info.report_ids.size() == 0 ||
19 report_id_ == HidConnection::kNullReportId)
20 return false;
22 if (report_id_ == HidConnection::kAnyReportId)
23 return true;
25 return std::find(info.report_ids.begin(),
26 info.report_ids.end(),
27 report_id_) != info.report_ids.end();
30 private:
31 const uint8_t report_id_;
34 // Functor returning true if collection has a protected usage.
35 struct CollectionIsProtected {
36 bool operator()(const HidCollectionInfo& info) const {
37 return info.usage.IsProtected();
41 bool FindCollectionByReportId(const HidDeviceInfo& device_info,
42 uint8_t report_id,
43 HidCollectionInfo* collection_info) {
44 std::vector<HidCollectionInfo>::const_iterator collection_iter =
45 std::find_if(device_info.collections.begin(),
46 device_info.collections.end(),
47 CollectionHasReportId(report_id));
48 if (collection_iter != device_info.collections.end()) {
49 if (collection_info) {
50 *collection_info = *collection_iter;
52 return true;
55 return false;
58 bool HasProtectedCollection(const HidDeviceInfo& device_info) {
59 return std::find_if(device_info.collections.begin(),
60 device_info.collections.end(),
61 CollectionIsProtected()) != device_info.collections.end();
64 } // namespace
66 HidConnection::HidConnection(const HidDeviceInfo& device_info)
67 : device_info_(device_info) {
68 has_protected_collection_ = HasProtectedCollection(device_info);
71 HidConnection::~HidConnection() {
72 DCHECK(thread_checker_.CalledOnValidThread());
75 void HidConnection::Read(const ReadCallback& callback) {
76 DCHECK(thread_checker_.CalledOnValidThread());
77 if (device_info_.max_input_report_size == 0) {
78 VLOG(1) << "This device does not support input reports.";
79 callback.Run(false, NULL, 0);
80 return;
83 PlatformRead(callback);
86 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer,
87 size_t size,
88 const WriteCallback& callback) {
89 DCHECK(thread_checker_.CalledOnValidThread());
90 if (device_info_.max_output_report_size == 0) {
91 VLOG(1) << "This device does not support output reports.";
92 callback.Run(false);
93 return;
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);
100 return;
102 if (IsReportIdProtected(report_id)) {
103 VLOG(1) << "Attempt to set a protected output report.";
104 callback.Run(false);
105 return;
108 PlatformWrite(buffer, size, callback);
111 void HidConnection::GetFeatureReport(uint8_t report_id,
112 const ReadCallback& callback) {
113 DCHECK(thread_checker_.CalledOnValidThread());
114 if (device_info_.max_feature_report_size == 0) {
115 VLOG(1) << "This device does not support feature reports.";
116 callback.Run(false, NULL, 0);
117 return;
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;
124 if (IsReportIdProtected(report_id)) {
125 VLOG(1) << "Attempt to get a protected feature report.";
126 callback.Run(false, NULL, 0);
127 return;
130 PlatformGetFeatureReport(report_id, callback);
133 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
134 size_t size,
135 const WriteCallback& callback) {
136 DCHECK(thread_checker_.CalledOnValidThread());
137 if (device_info_.max_feature_report_size == 0) {
138 VLOG(1) << "This device does not support feature reports.";
139 callback.Run(false);
140 return;
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);
147 return;
149 if (IsReportIdProtected(report_id)) {
150 VLOG(1) << "Attempt to set a protected feature report.";
151 callback.Run(false);
152 return;
155 PlatformSendFeatureReport(buffer, size, callback);
158 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer,
159 size_t size,
160 const ReadCallback& callback) {
161 DCHECK_GE(size, 1u);
162 uint8_t report_id = buffer->data()[0];
163 if (IsReportIdProtected(report_id)) {
164 VLOG(1) << "Filtered a protected input report.";
165 return false;
168 callback.Run(true, buffer, size);
169 return true;
172 bool HidConnection::IsReportIdProtected(uint8_t report_id) {
173 HidCollectionInfo collection_info;
174 if (FindCollectionByReportId(device_info_, report_id, &collection_info)) {
175 return collection_info.usage.IsProtected();
178 return has_protected_collection();
181 PendingHidReport::PendingHidReport() {}
183 PendingHidReport::~PendingHidReport() {}
185 PendingHidRead::PendingHidRead() {}
187 PendingHidRead::~PendingHidRead() {}
189 } // namespace device