| 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 namespace device { | 9 namespace device { | 
| 10 | 10 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 31   const uint8_t report_id_; | 31   const uint8_t report_id_; | 
| 32 }; | 32 }; | 
| 33 | 33 | 
| 34 // Functor returning true if collection has a protected usage. | 34 // Functor returning true if collection has a protected usage. | 
| 35 struct CollectionIsProtected { | 35 struct CollectionIsProtected { | 
| 36   bool operator()(const HidCollectionInfo& info) const { | 36   bool operator()(const HidCollectionInfo& info) const { | 
| 37     return info.usage.IsProtected(); | 37     return info.usage.IsProtected(); | 
| 38   } | 38   } | 
| 39 }; | 39 }; | 
| 40 | 40 | 
| 41 bool FindCollectionByReportId(const HidDeviceInfo& device_info, | 41 bool FindCollectionByReportId(const std::vector<HidCollectionInfo>& collections, | 
| 42                               uint8_t report_id, | 42                               uint8_t report_id, | 
| 43                               HidCollectionInfo* collection_info) { | 43                               HidCollectionInfo* collection_info) { | 
| 44   std::vector<HidCollectionInfo>::const_iterator collection_iter = | 44   std::vector<HidCollectionInfo>::const_iterator collection_iter = std::find_if( | 
| 45       std::find_if(device_info.collections.begin(), | 45       collections.begin(), collections.end(), CollectionHasReportId(report_id)); | 
| 46                    device_info.collections.end(), | 46   if (collection_iter != collections.end()) { | 
| 47                    CollectionHasReportId(report_id)); |  | 
| 48   if (collection_iter != device_info.collections.end()) { |  | 
| 49     if (collection_info) { | 47     if (collection_info) { | 
| 50       *collection_info = *collection_iter; | 48       *collection_info = *collection_iter; | 
| 51     } | 49     } | 
| 52     return true; | 50     return true; | 
| 53   } | 51   } | 
| 54 | 52 | 
| 55   return false; | 53   return false; | 
| 56 } | 54 } | 
| 57 | 55 | 
| 58 bool HasProtectedCollection(const HidDeviceInfo& device_info) { | 56 bool HasProtectedCollection(const std::vector<HidCollectionInfo>& collections) { | 
| 59   return std::find_if(device_info.collections.begin(), | 57   return std::find_if(collections.begin(), collections.end(), | 
| 60                       device_info.collections.end(), | 58                       CollectionIsProtected()) != collections.end(); | 
| 61                       CollectionIsProtected()) != device_info.collections.end(); |  | 
| 62 } | 59 } | 
| 63 | 60 | 
| 64 }  // namespace | 61 }  // namespace | 
| 65 | 62 | 
| 66 HidConnection::HidConnection(const HidDeviceInfo& device_info) | 63 HidConnection::HidConnection(scoped_refptr<HidDeviceInfo> device_info) | 
| 67     : device_info_(device_info), closed_(false) { | 64     : device_info_(device_info), closed_(false) { | 
| 68   has_protected_collection_ = HasProtectedCollection(device_info); | 65   has_protected_collection_ = | 
|  | 66       HasProtectedCollection(device_info->collections()); | 
| 69 } | 67 } | 
| 70 | 68 | 
| 71 HidConnection::~HidConnection() { | 69 HidConnection::~HidConnection() { | 
| 72   DCHECK(thread_checker_.CalledOnValidThread()); | 70   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 73   DCHECK(closed_); | 71   DCHECK(closed_); | 
| 74 } | 72 } | 
| 75 | 73 | 
| 76 void HidConnection::Close() { | 74 void HidConnection::Close() { | 
| 77   DCHECK(thread_checker_.CalledOnValidThread()); | 75   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 78   DCHECK(!closed_); | 76   DCHECK(!closed_); | 
| 79 | 77 | 
| 80   PlatformClose(); | 78   PlatformClose(); | 
| 81   closed_ = true; | 79   closed_ = true; | 
| 82 } | 80 } | 
| 83 | 81 | 
| 84 void HidConnection::Read(const ReadCallback& callback) { | 82 void HidConnection::Read(const ReadCallback& callback) { | 
| 85   DCHECK(thread_checker_.CalledOnValidThread()); | 83   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 86   if (device_info_.max_input_report_size == 0) { | 84   if (device_info_->max_input_report_size() == 0) { | 
| 87     VLOG(1) << "This device does not support input reports."; | 85     VLOG(1) << "This device does not support input reports."; | 
| 88     callback.Run(false, NULL, 0); | 86     callback.Run(false, NULL, 0); | 
| 89     return; | 87     return; | 
| 90   } | 88   } | 
| 91 | 89 | 
| 92   PlatformRead(callback); | 90   PlatformRead(callback); | 
| 93 } | 91 } | 
| 94 | 92 | 
| 95 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, | 93 void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, | 
| 96                           size_t size, | 94                           size_t size, | 
| 97                           const WriteCallback& callback) { | 95                           const WriteCallback& callback) { | 
| 98   DCHECK(thread_checker_.CalledOnValidThread()); | 96   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 99   if (device_info_.max_output_report_size == 0) { | 97   if (device_info_->max_output_report_size() == 0) { | 
| 100     VLOG(1) << "This device does not support output reports."; | 98     VLOG(1) << "This device does not support output reports."; | 
| 101     callback.Run(false); | 99     callback.Run(false); | 
| 102     return; | 100     return; | 
| 103   } | 101   } | 
| 104   DCHECK_GE(size, 1u); | 102   DCHECK_GE(size, 1u); | 
| 105   uint8_t report_id = buffer->data()[0]; | 103   uint8_t report_id = buffer->data()[0]; | 
| 106   if (device_info().has_report_id != (report_id != 0)) { | 104   if (device_info_->has_report_id() != (report_id != 0)) { | 
| 107     VLOG(1) << "Invalid output report ID."; | 105     VLOG(1) << "Invalid output report ID."; | 
| 108     callback.Run(false); | 106     callback.Run(false); | 
| 109     return; | 107     return; | 
| 110   } | 108   } | 
| 111   if (IsReportIdProtected(report_id)) { | 109   if (IsReportIdProtected(report_id)) { | 
| 112     VLOG(1) << "Attempt to set a protected output report."; | 110     VLOG(1) << "Attempt to set a protected output report."; | 
| 113     callback.Run(false); | 111     callback.Run(false); | 
| 114     return; | 112     return; | 
| 115   } | 113   } | 
| 116 | 114 | 
| 117   PlatformWrite(buffer, size, callback); | 115   PlatformWrite(buffer, size, callback); | 
| 118 } | 116 } | 
| 119 | 117 | 
| 120 void HidConnection::GetFeatureReport(uint8_t report_id, | 118 void HidConnection::GetFeatureReport(uint8_t report_id, | 
| 121                                      const ReadCallback& callback) { | 119                                      const ReadCallback& callback) { | 
| 122   DCHECK(thread_checker_.CalledOnValidThread()); | 120   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 123   if (device_info_.max_feature_report_size == 0) { | 121   if (device_info_->max_feature_report_size() == 0) { | 
| 124     VLOG(1) << "This device does not support feature reports."; | 122     VLOG(1) << "This device does not support feature reports."; | 
| 125     callback.Run(false, NULL, 0); | 123     callback.Run(false, NULL, 0); | 
| 126     return; | 124     return; | 
| 127   } | 125   } | 
| 128   if (device_info().has_report_id != (report_id != 0)) { | 126   if (device_info_->has_report_id() != (report_id != 0)) { | 
| 129     VLOG(1) << "Invalid feature report ID."; | 127     VLOG(1) << "Invalid feature report ID."; | 
| 130     callback.Run(false, NULL, 0); | 128     callback.Run(false, NULL, 0); | 
| 131     return; | 129     return; | 
| 132   } | 130   } | 
| 133   if (IsReportIdProtected(report_id)) { | 131   if (IsReportIdProtected(report_id)) { | 
| 134     VLOG(1) << "Attempt to get a protected feature report."; | 132     VLOG(1) << "Attempt to get a protected feature report."; | 
| 135     callback.Run(false, NULL, 0); | 133     callback.Run(false, NULL, 0); | 
| 136     return; | 134     return; | 
| 137   } | 135   } | 
| 138 | 136 | 
| 139   PlatformGetFeatureReport(report_id, callback); | 137   PlatformGetFeatureReport(report_id, callback); | 
| 140 } | 138 } | 
| 141 | 139 | 
| 142 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer, | 140 void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer, | 
| 143                                       size_t size, | 141                                       size_t size, | 
| 144                                       const WriteCallback& callback) { | 142                                       const WriteCallback& callback) { | 
| 145   DCHECK(thread_checker_.CalledOnValidThread()); | 143   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 146   if (device_info_.max_feature_report_size == 0) { | 144   if (device_info_->max_feature_report_size() == 0) { | 
| 147     VLOG(1) << "This device does not support feature reports."; | 145     VLOG(1) << "This device does not support feature reports."; | 
| 148     callback.Run(false); | 146     callback.Run(false); | 
| 149     return; | 147     return; | 
| 150   } | 148   } | 
| 151   DCHECK_GE(size, 1u); | 149   DCHECK_GE(size, 1u); | 
| 152   uint8_t report_id = buffer->data()[0]; | 150   uint8_t report_id = buffer->data()[0]; | 
| 153   if (device_info().has_report_id != (report_id != 0)) { | 151   if (device_info_->has_report_id() != (report_id != 0)) { | 
| 154     VLOG(1) << "Invalid feature report ID."; | 152     VLOG(1) << "Invalid feature report ID."; | 
| 155     callback.Run(false); | 153     callback.Run(false); | 
| 156     return; | 154     return; | 
| 157   } | 155   } | 
| 158   if (IsReportIdProtected(report_id)) { | 156   if (IsReportIdProtected(report_id)) { | 
| 159     VLOG(1) << "Attempt to set a protected feature report."; | 157     VLOG(1) << "Attempt to set a protected feature report."; | 
| 160     callback.Run(false); | 158     callback.Run(false); | 
| 161     return; | 159     return; | 
| 162   } | 160   } | 
| 163 | 161 | 
| 164   PlatformSendFeatureReport(buffer, size, callback); | 162   PlatformSendFeatureReport(buffer, size, callback); | 
| 165 } | 163 } | 
| 166 | 164 | 
| 167 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer, | 165 bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer, | 
| 168                                  size_t size, | 166                                  size_t size, | 
| 169                                  const ReadCallback& callback) { | 167                                  const ReadCallback& callback) { | 
| 170   DCHECK_GE(size, 1u); | 168   DCHECK_GE(size, 1u); | 
| 171   uint8_t report_id = buffer->data()[0]; | 169   uint8_t report_id = buffer->data()[0]; | 
| 172   if (IsReportIdProtected(report_id)) { | 170   if (IsReportIdProtected(report_id)) { | 
| 173     VLOG(1) << "Filtered a protected input report."; | 171     VLOG(1) << "Filtered a protected input report."; | 
| 174     return false; | 172     return false; | 
| 175   } | 173   } | 
| 176 | 174 | 
| 177   callback.Run(true, buffer, size); | 175   callback.Run(true, buffer, size); | 
| 178   return true; | 176   return true; | 
| 179 } | 177 } | 
| 180 | 178 | 
| 181 bool HidConnection::IsReportIdProtected(uint8_t report_id) { | 179 bool HidConnection::IsReportIdProtected(uint8_t report_id) { | 
| 182   HidCollectionInfo collection_info; | 180   HidCollectionInfo collection_info; | 
| 183   if (FindCollectionByReportId(device_info_, report_id, &collection_info)) { | 181   if (FindCollectionByReportId(device_info_->collections(), report_id, | 
|  | 182                                &collection_info)) { | 
| 184     return collection_info.usage.IsProtected(); | 183     return collection_info.usage.IsProtected(); | 
| 185   } | 184   } | 
| 186 | 185 | 
| 187   return has_protected_collection(); | 186   return has_protected_collection(); | 
| 188 } | 187 } | 
| 189 | 188 | 
| 190 PendingHidReport::PendingHidReport() {} | 189 PendingHidReport::PendingHidReport() {} | 
| 191 | 190 | 
| 192 PendingHidReport::~PendingHidReport() {} | 191 PendingHidReport::~PendingHidReport() {} | 
| 193 | 192 | 
| 194 PendingHidRead::PendingHidRead() {} | 193 PendingHidRead::PendingHidRead() {} | 
| 195 | 194 | 
| 196 PendingHidRead::~PendingHidRead() {} | 195 PendingHidRead::~PendingHidRead() {} | 
| 197 | 196 | 
| 198 }  // namespace device | 197 }  // namespace device | 
| OLD | NEW | 
|---|