Update Smart lock strings in chrome://settings.
[chromium-blink-merge.git] / device / hid / hid_connection.cc
blob5ff39f3f95e81ac1f99d67e8ec0dffd0a95233dd
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), closed_(false) {
68 has_protected_collection_ = HasProtectedCollection(device_info);
71 HidConnection::~HidConnection() {
72 DCHECK(thread_checker_.CalledOnValidThread());
73 DCHECK(closed_);
76 void HidConnection::Close() {
77 DCHECK(thread_checker_.CalledOnValidThread());
78 DCHECK(!closed_);
80 PlatformClose();
81 closed_ = true;
84 void HidConnection::Read(const ReadCallback& callback) {
85 DCHECK(thread_checker_.CalledOnValidThread());
86 if (device_info_.max_input_report_size == 0) {
87 VLOG(1) << "This device does not support input reports.";
88 callback.Run(false, NULL, 0);
89 return;
92 PlatformRead(callback);
95 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer,
96 size_t size,
97 const WriteCallback& callback) {
98 DCHECK(thread_checker_.CalledOnValidThread());
99 if (device_info_.max_output_report_size == 0) {
100 VLOG(1) << "This device does not support output reports.";
101 callback.Run(false);
102 return;
104 DCHECK_GE(size, 1u);
105 uint8_t report_id = buffer->data()[0];
106 if (device_info().has_report_id != (report_id != 0)) {
107 VLOG(1) << "Invalid output report ID.";
108 callback.Run(false);
109 return;
111 if (IsReportIdProtected(report_id)) {
112 VLOG(1) << "Attempt to set a protected output report.";
113 callback.Run(false);
114 return;
117 PlatformWrite(buffer, size, callback);
120 void HidConnection::GetFeatureReport(uint8_t report_id,
121 const ReadCallback& callback) {
122 DCHECK(thread_checker_.CalledOnValidThread());
123 if (device_info_.max_feature_report_size == 0) {
124 VLOG(1) << "This device does not support feature reports.";
125 callback.Run(false, NULL, 0);
126 return;
128 if (device_info().has_report_id != (report_id != 0)) {
129 VLOG(1) << "Invalid feature report ID.";
130 callback.Run(false, NULL, 0);
131 return;
133 if (IsReportIdProtected(report_id)) {
134 VLOG(1) << "Attempt to get a protected feature report.";
135 callback.Run(false, NULL, 0);
136 return;
139 PlatformGetFeatureReport(report_id, callback);
142 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
143 size_t size,
144 const WriteCallback& callback) {
145 DCHECK(thread_checker_.CalledOnValidThread());
146 if (device_info_.max_feature_report_size == 0) {
147 VLOG(1) << "This device does not support feature reports.";
148 callback.Run(false);
149 return;
151 DCHECK_GE(size, 1u);
152 uint8_t report_id = buffer->data()[0];
153 if (device_info().has_report_id != (report_id != 0)) {
154 VLOG(1) << "Invalid feature report ID.";
155 callback.Run(false);
156 return;
158 if (IsReportIdProtected(report_id)) {
159 VLOG(1) << "Attempt to set a protected feature report.";
160 callback.Run(false);
161 return;
164 PlatformSendFeatureReport(buffer, size, callback);
167 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer,
168 size_t size,
169 const ReadCallback& callback) {
170 DCHECK_GE(size, 1u);
171 uint8_t report_id = buffer->data()[0];
172 if (IsReportIdProtected(report_id)) {
173 VLOG(1) << "Filtered a protected input report.";
174 return false;
177 callback.Run(true, buffer, size);
178 return true;
181 bool HidConnection::IsReportIdProtected(uint8_t report_id) {
182 HidCollectionInfo collection_info;
183 if (FindCollectionByReportId(device_info_, report_id, &collection_info)) {
184 return collection_info.usage.IsProtected();
187 return has_protected_collection();
190 PendingHidReport::PendingHidReport() {}
192 PendingHidReport::~PendingHidReport() {}
194 PendingHidRead::PendingHidRead() {}
196 PendingHidRead::~PendingHidRead() {}
198 } // namespace device