diff options
24 files changed, 347 insertions, 293 deletions
diff --git a/device/hid/hid_connection.cc b/device/hid/hid_connection.cc index 5ff39f3..6ce2d7f 100644 --- a/device/hid/hid_connection.cc +++ b/device/hid/hid_connection.cc @@ -38,14 +38,12 @@ struct CollectionIsProtected { } }; -bool FindCollectionByReportId(const HidDeviceInfo& device_info, +bool FindCollectionByReportId(const std::vector<HidCollectionInfo>& collections, uint8_t report_id, HidCollectionInfo* collection_info) { - std::vector<HidCollectionInfo>::const_iterator collection_iter = - std::find_if(device_info.collections.begin(), - device_info.collections.end(), - CollectionHasReportId(report_id)); - if (collection_iter != device_info.collections.end()) { + std::vector<HidCollectionInfo>::const_iterator collection_iter = std::find_if( + collections.begin(), collections.end(), CollectionHasReportId(report_id)); + if (collection_iter != collections.end()) { if (collection_info) { *collection_info = *collection_iter; } @@ -55,17 +53,17 @@ bool FindCollectionByReportId(const HidDeviceInfo& device_info, return false; } -bool HasProtectedCollection(const HidDeviceInfo& device_info) { - return std::find_if(device_info.collections.begin(), - device_info.collections.end(), - CollectionIsProtected()) != device_info.collections.end(); +bool HasProtectedCollection(const std::vector<HidCollectionInfo>& collections) { + return std::find_if(collections.begin(), collections.end(), + CollectionIsProtected()) != collections.end(); } } // namespace -HidConnection::HidConnection(const HidDeviceInfo& device_info) +HidConnection::HidConnection(scoped_refptr<HidDeviceInfo> device_info) : device_info_(device_info), closed_(false) { - has_protected_collection_ = HasProtectedCollection(device_info); + has_protected_collection_ = + HasProtectedCollection(device_info->collections()); } HidConnection::~HidConnection() { @@ -83,7 +81,7 @@ void HidConnection::Close() { void HidConnection::Read(const ReadCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (device_info_.max_input_report_size == 0) { + if (device_info_->max_input_report_size() == 0) { VLOG(1) << "This device does not support input reports."; callback.Run(false, NULL, 0); return; @@ -96,14 +94,14 @@ void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, size_t size, const WriteCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (device_info_.max_output_report_size == 0) { + if (device_info_->max_output_report_size() == 0) { VLOG(1) << "This device does not support output reports."; callback.Run(false); return; } DCHECK_GE(size, 1u); uint8_t report_id = buffer->data()[0]; - if (device_info().has_report_id != (report_id != 0)) { + if (device_info_->has_report_id() != (report_id != 0)) { VLOG(1) << "Invalid output report ID."; callback.Run(false); return; @@ -120,12 +118,12 @@ void HidConnection::Write(scoped_refptr<net::IOBuffer> buffer, void HidConnection::GetFeatureReport(uint8_t report_id, const ReadCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (device_info_.max_feature_report_size == 0) { + if (device_info_->max_feature_report_size() == 0) { VLOG(1) << "This device does not support feature reports."; callback.Run(false, NULL, 0); return; } - if (device_info().has_report_id != (report_id != 0)) { + if (device_info_->has_report_id() != (report_id != 0)) { VLOG(1) << "Invalid feature report ID."; callback.Run(false, NULL, 0); return; @@ -143,14 +141,14 @@ void HidConnection::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer, size_t size, const WriteCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (device_info_.max_feature_report_size == 0) { + if (device_info_->max_feature_report_size() == 0) { VLOG(1) << "This device does not support feature reports."; callback.Run(false); return; } DCHECK_GE(size, 1u); uint8_t report_id = buffer->data()[0]; - if (device_info().has_report_id != (report_id != 0)) { + if (device_info_->has_report_id() != (report_id != 0)) { VLOG(1) << "Invalid feature report ID."; callback.Run(false); return; @@ -180,7 +178,8 @@ bool HidConnection::CompleteRead(scoped_refptr<net::IOBuffer> buffer, bool HidConnection::IsReportIdProtected(uint8_t report_id) { HidCollectionInfo collection_info; - if (FindCollectionByReportId(device_info_, report_id, &collection_info)) { + if (FindCollectionByReportId(device_info_->collections(), report_id, + &collection_info)) { return collection_info.usage.IsProtected(); } diff --git a/device/hid/hid_connection.h b/device/hid/hid_connection.h index 8c1bc0d..1c71075 100644 --- a/device/hid/hid_connection.h +++ b/device/hid/hid_connection.h @@ -27,7 +27,7 @@ class HidConnection : public base::RefCountedThreadSafe<HidConnection> { ReadCallback; typedef base::Callback<void(bool success)> WriteCallback; - const HidDeviceInfo& device_info() const { return device_info_; } + scoped_refptr<HidDeviceInfo> device_info() const { return device_info_; } bool has_protected_collection() const { return has_protected_collection_; } const base::ThreadChecker& thread_checker() const { return thread_checker_; } bool closed() const { return closed_; } @@ -59,7 +59,7 @@ class HidConnection : public base::RefCountedThreadSafe<HidConnection> { protected: friend class base::RefCountedThreadSafe<HidConnection>; - explicit HidConnection(const HidDeviceInfo& device_info); + explicit HidConnection(scoped_refptr<HidDeviceInfo> device_info); virtual ~HidConnection(); virtual void PlatformClose() = 0; @@ -85,7 +85,7 @@ class HidConnection : public base::RefCountedThreadSafe<HidConnection> { private: bool IsReportIdProtected(uint8_t report_id); - const HidDeviceInfo device_info_; + scoped_refptr<HidDeviceInfo> device_info_; bool has_protected_collection_; base::ThreadChecker thread_checker_; bool closed_; diff --git a/device/hid/hid_connection_linux.cc b/device/hid/hid_connection_linux.cc index 27975e2..e9ca4b2 100644 --- a/device/hid/hid_connection_linux.cc +++ b/device/hid/hid_connection_linux.cc @@ -32,15 +32,15 @@ namespace device { class HidConnectionLinux::Helper : public base::MessagePumpLibevent::Watcher { public: Helper(base::PlatformFile platform_file, - const HidDeviceInfo& device_info, + scoped_refptr<HidDeviceInfo> device_info, base::WeakPtr<HidConnectionLinux> connection, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : platform_file_(platform_file), connection_(connection), task_runner_(task_runner) { // Report buffers must always have room for the report ID. - report_buffer_size_ = device_info.max_input_report_size + 1; - has_report_id_ = device_info.has_report_id; + report_buffer_size_ = device_info->max_input_report_size() + 1; + has_report_id_ = device_info->has_report_id(); } ~Helper() override { DCHECK(thread_checker_.CalledOnValidThread()); } @@ -111,7 +111,7 @@ class HidConnectionLinux::Helper : public base::MessagePumpLibevent::Watcher { }; HidConnectionLinux::HidConnectionLinux( - const HidDeviceInfo& device_info, + scoped_refptr<HidDeviceInfo> device_info, base::File device_file, scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) : HidConnection(device_info), @@ -175,9 +175,9 @@ void HidConnectionLinux::PlatformGetFeatureReport( const ReadCallback& callback) { // The first byte of the destination buffer is the report ID being requested // and is overwritten by the feature report. - DCHECK_GT(device_info().max_feature_report_size, 0u); + DCHECK_GT(device_info()->max_feature_report_size(), 0u); scoped_refptr<net::IOBufferWithSize> buffer( - new net::IOBufferWithSize(device_info().max_feature_report_size + 1)); + new net::IOBufferWithSize(device_info()->max_feature_report_size() + 1)); buffer->data()[0] = report_id; file_task_runner_->PostTask( diff --git a/device/hid/hid_connection_linux.h b/device/hid/hid_connection_linux.h index 13a7165..c8ffc85 100644 --- a/device/hid/hid_connection_linux.h +++ b/device/hid/hid_connection_linux.h @@ -20,7 +20,7 @@ namespace device { class HidConnectionLinux : public HidConnection { public: HidConnectionLinux( - const HidDeviceInfo& device_info, + scoped_refptr<HidDeviceInfo> device_info, base::File device_file, scoped_refptr<base::SingleThreadTaskRunner> file_thread_runner); diff --git a/device/hid/hid_connection_mac.cc b/device/hid/hid_connection_mac.cc index 5f8ef97..fe485f7 100644 --- a/device/hid/hid_connection_mac.cc +++ b/device/hid/hid_connection_mac.cc @@ -16,7 +16,7 @@ namespace device { HidConnectionMac::HidConnectionMac( IOHIDDeviceRef device, - HidDeviceInfo device_info, + scoped_refptr<HidDeviceInfo> device_info, scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) : HidConnection(device_info), device_(device, base::scoped_policy::RETAIN), @@ -27,8 +27,8 @@ HidConnectionMac::HidConnectionMac( IOHIDDeviceScheduleWithRunLoop( device_.get(), CFRunLoopGetMain(), kCFRunLoopDefaultMode); - size_t expected_report_size = device_info.max_input_report_size; - if (device_info.has_report_id) { + size_t expected_report_size = device_info->max_input_report_size(); + if (device_info->has_report_id()) { expected_report_size++; } inbound_buffer_.resize(expected_report_size); @@ -126,7 +126,7 @@ void HidConnectionMac::InputReportCallback(void* context, } scoped_refptr<net::IOBufferWithSize> buffer; - if (connection->device_info().has_report_id) { + if (connection->device_info()->has_report_id()) { // report_id is already contained in report_bytes buffer = new net::IOBufferWithSize(report_length); memcpy(buffer->data(), report_bytes, report_length); @@ -165,7 +165,7 @@ void HidConnectionMac::ProcessReadQueue() { void HidConnectionMac::GetFeatureReportAsync(uint8_t report_id, const ReadCallback& callback) { scoped_refptr<net::IOBufferWithSize> buffer( - new net::IOBufferWithSize(device_info().max_feature_report_size + 1)); + new net::IOBufferWithSize(device_info()->max_feature_report_size() + 1)); CFIndex report_size = buffer->size(); // The IOHIDDevice object is shared with the UI thread and so this function diff --git a/device/hid/hid_connection_mac.h b/device/hid/hid_connection_mac.h index daac83b..7e6df025 100644 --- a/device/hid/hid_connection_mac.h +++ b/device/hid/hid_connection_mac.h @@ -26,9 +26,9 @@ namespace device { class HidConnectionMac : public HidConnection { public: - explicit HidConnectionMac( + HidConnectionMac( IOHIDDeviceRef device, - HidDeviceInfo device_info, + scoped_refptr<HidDeviceInfo> device_info, scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); private: diff --git a/device/hid/hid_connection_unittest.cc b/device/hid/hid_connection_unittest.cc index ab3841c..e474a62 100644 --- a/device/hid/hid_connection_unittest.cc +++ b/device/hid/hid_connection_unittest.cc @@ -62,19 +62,20 @@ class DeviceCatcher : HidService::Observer { } private: - void OnEnumerationComplete(const std::vector<HidDeviceInfo>& devices) { - for (const HidDeviceInfo& device_info : devices) { - if (device_info.serial_number == serial_number_) { - device_id_ = device_info.device_id; + void OnEnumerationComplete( + const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + for (const scoped_refptr<HidDeviceInfo>& device_info : devices) { + if (device_info->serial_number() == serial_number_) { + device_id_ = device_info->device_id(); run_loop_.Quit(); break; } } } - void OnDeviceAdded(const HidDeviceInfo& device_info) override { - if (device_info.serial_number == serial_number_) { - device_id_ = device_info.device_id; + void OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) override { + if (device_info->serial_number() == serial_number_) { + device_id_ = device_info->device_id(); run_loop_.Quit(); } } diff --git a/device/hid/hid_connection_win.cc b/device/hid/hid_connection_win.cc index 5db7ed4..a0c8a50 100644 --- a/device/hid/hid_connection_win.cc +++ b/device/hid/hid_connection_win.cc @@ -102,7 +102,7 @@ void PendingHidTransfer::WillDestroyCurrentMessageLoop() { callback_.Run(this, false); } -HidConnectionWin::HidConnectionWin(const HidDeviceInfo& device_info, +HidConnectionWin::HidConnectionWin(scoped_refptr<HidDeviceInfo> device_info, base::win::ScopedHandle file) : HidConnection(device_info) { file_ = file.Pass(); @@ -120,7 +120,7 @@ void HidConnectionWin::PlatformRead( // Windows will always include the report ID (including zero if report IDs // are not in use) in the buffer. scoped_refptr<net::IOBufferWithSize> buffer = new net::IOBufferWithSize( - base::checked_cast<int>(device_info().max_input_report_size + 1)); + base::checked_cast<int>(device_info()->max_input_report_size() + 1)); scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( buffer, base::Bind(&HidConnectionWin::OnReadComplete, this, buffer, callback))); @@ -152,7 +152,7 @@ void HidConnectionWin::PlatformGetFeatureReport(uint8_t report_id, const ReadCallback& callback) { // The first byte of the destination buffer is the report ID being requested. scoped_refptr<net::IOBufferWithSize> buffer = new net::IOBufferWithSize( - base::checked_cast<int>(device_info().max_feature_report_size + 1)); + base::checked_cast<int>(device_info()->max_feature_report_size() + 1)); buffer->data()[0] = report_id; scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( diff --git a/device/hid/hid_connection_win.h b/device/hid/hid_connection_win.h index 9a4d0c5..5830c21 100644 --- a/device/hid/hid_connection_win.h +++ b/device/hid/hid_connection_win.h @@ -18,7 +18,7 @@ struct PendingHidTransfer; class HidConnectionWin : public HidConnection { public: - HidConnectionWin(const HidDeviceInfo& device_info, + HidConnectionWin(scoped_refptr<HidDeviceInfo> device_info, base::win::ScopedHandle file); private: diff --git a/device/hid/hid_device_filter.cc b/device/hid/hid_device_filter.cc index 70ebcf4..3be57ab 100644 --- a/device/hid/hid_device_filter.cc +++ b/device/hid/hid_device_filter.cc @@ -38,24 +38,21 @@ void HidDeviceFilter::SetUsage(uint16_t usage) { usage_ = usage; } -bool HidDeviceFilter::Matches(const HidDeviceInfo& device_info) const { +bool HidDeviceFilter::Matches( + scoped_refptr<const HidDeviceInfo> device_info) const { if (vendor_id_set_) { - if (device_info.vendor_id != vendor_id_) { + if (device_info->vendor_id() != vendor_id_) { return false; } - if (product_id_set_ && device_info.product_id != product_id_) { + if (product_id_set_ && device_info->product_id() != product_id_) { return false; } } if (usage_page_set_) { bool found_matching_collection = false; - for (std::vector<HidCollectionInfo>::const_iterator i = - device_info.collections.begin(); - i != device_info.collections.end() && !found_matching_collection; - ++i) { - const HidCollectionInfo& collection = *i; + for (const HidCollectionInfo& collection : device_info->collections()) { if (collection.usage.usage_page != usage_page_) { continue; } @@ -73,13 +70,10 @@ bool HidDeviceFilter::Matches(const HidDeviceInfo& device_info) const { } // static -bool HidDeviceFilter::MatchesAny( - const HidDeviceInfo& device_info, - const std::vector<HidDeviceFilter>& filters) { - for (std::vector<HidDeviceFilter>::const_iterator i = filters.begin(); - i != filters.end(); - ++i) { - if (i->Matches(device_info)) { +bool HidDeviceFilter::MatchesAny(scoped_refptr<const HidDeviceInfo> device_info, + const std::vector<HidDeviceFilter>& filters) { + for (const HidDeviceFilter& filter : filters) { + if (filter.Matches(device_info)) { return true; } } diff --git a/device/hid/hid_device_filter.h b/device/hid/hid_device_filter.h index a0abbb7..fbffd2b 100644 --- a/device/hid/hid_device_filter.h +++ b/device/hid/hid_device_filter.h @@ -8,9 +8,11 @@ #include <stdint.h> #include <vector> +#include "base/memory/ref_counted.h" + namespace device { -struct HidDeviceInfo; +class HidDeviceInfo; class HidDeviceFilter { public: @@ -22,9 +24,9 @@ class HidDeviceFilter { void SetUsagePage(uint16_t usage_page); void SetUsage(uint16_t usage); - bool Matches(const HidDeviceInfo& device_info) const; + bool Matches(scoped_refptr<const HidDeviceInfo> device_info) const; - static bool MatchesAny(const HidDeviceInfo& device_info, + static bool MatchesAny(scoped_refptr<const HidDeviceInfo> device_info, const std::vector<HidDeviceFilter>& filters); private: diff --git a/device/hid/hid_device_filter_unittest.cc b/device/hid/hid_device_filter_unittest.cc index aac87ff..a59adea 100644 --- a/device/hid/hid_device_filter_unittest.cc +++ b/device/hid/hid_device_filter_unittest.cc @@ -8,22 +8,21 @@ namespace device { -namespace { - class HidFilterTest : public testing::Test { public: void SetUp() override { - device_info_.vendor_id = 0x046d; - device_info_.product_id = 0xc31c; + device_info_ = new HidDeviceInfo(); + device_info_->vendor_id_ = 0x046d; + device_info_->product_id_ = 0xc31c; HidCollectionInfo collection; collection.usage.usage_page = HidUsageAndPage::kPageKeyboard; collection.usage.usage = 0x01; - device_info_.collections.push_back(collection); + device_info_->collections_.push_back(collection); } protected: - HidDeviceInfo device_info_; + scoped_refptr<HidDeviceInfo> device_info_; }; TEST_F(HidFilterTest, MatchAny) { @@ -111,6 +110,4 @@ TEST_F(HidFilterTest, MatchFilterListNegative) { ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters)); } -} // namespace - } // namespace device diff --git a/device/hid/hid_device_info.cc b/device/hid/hid_device_info.cc index 6298ebc..1a9d3a6 100644 --- a/device/hid/hid_device_info.cc +++ b/device/hid/hid_device_info.cc @@ -9,14 +9,14 @@ namespace device { const char kInvalidHidDeviceId[] = ""; HidDeviceInfo::HidDeviceInfo() - : device_id(kInvalidHidDeviceId), - vendor_id(0), - product_id(0), - bus_type(kHIDBusTypeUSB), - has_report_id(false), - max_input_report_size(0), - max_output_report_size(0), - max_feature_report_size(0) { + : device_id_(kInvalidHidDeviceId), + vendor_id_(0), + product_id_(0), + bus_type_(kHIDBusTypeUSB), + has_report_id_(false), + max_input_report_size_(0), + max_output_report_size_(0), + max_feature_report_size_(0) { } HidDeviceInfo::~HidDeviceInfo() {} diff --git a/device/hid/hid_device_info.h b/device/hid/hid_device_info.h index 917a129..7aae955 100644 --- a/device/hid/hid_device_info.h +++ b/device/hid/hid_device_info.h @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/memory/ref_counted.h" #include "build/build_config.h" #include "device/hid/hid_collection_info.h" @@ -21,28 +22,64 @@ enum HidBusType { typedef std::string HidDeviceId; extern const char kInvalidHidDeviceId[]; -struct HidDeviceInfo { +class HidDeviceInfo : public base::RefCountedThreadSafe<HidDeviceInfo> { + public: HidDeviceInfo(); + + // Device identification. + const HidDeviceId& device_id() const { return device_id_; } + uint16_t vendor_id() const { return vendor_id_; } + uint16_t product_id() const { return product_id_; } + const std::string& product_name() const { return product_name_; } + const std::string& serial_number() const { return serial_number_; } + HidBusType bus_type() const { return bus_type_; } + + // Top-Level Collections information. + const std::vector<HidCollectionInfo>& collections() const { + return collections_; + } + bool has_report_id() const { return has_report_id_; }; + size_t max_input_report_size() const { return max_input_report_size_; } + size_t max_output_report_size() const { return max_output_report_size_; } + size_t max_feature_report_size() const { return max_feature_report_size_; } + +#if defined(OS_LINUX) + const std::string& device_node() const { return device_node_; } +#endif + + private: + friend class base::RefCountedThreadSafe<HidDeviceInfo>; + + // TODO(reillyg): Define public constructors that make some of these + // declarations unnecessary. + friend class HidServiceLinux; + friend class HidServiceMac; + friend class HidServiceWin; + friend class MockHidService; + friend class HidFilterTest; + ~HidDeviceInfo(); // Device identification. - HidDeviceId device_id; - uint16_t vendor_id; - uint16_t product_id; - std::string product_name; - std::string serial_number; - HidBusType bus_type; + HidDeviceId device_id_; + uint16_t vendor_id_; + uint16_t product_id_; + std::string product_name_; + std::string serial_number_; + HidBusType bus_type_; // Top-Level Collections information. - std::vector<HidCollectionInfo> collections; - bool has_report_id; - size_t max_input_report_size; - size_t max_output_report_size; - size_t max_feature_report_size; + std::vector<HidCollectionInfo> collections_; + bool has_report_id_; + size_t max_input_report_size_; + size_t max_output_report_size_; + size_t max_feature_report_size_; #if defined(OS_LINUX) - std::string device_node; + std::string device_node_; #endif + + DISALLOW_COPY_AND_ASSIGN(HidDeviceInfo); }; } // namespace device diff --git a/device/hid/hid_service.cc b/device/hid/hid_service.cc index 4953f25..c0b176e 100644 --- a/device/hid/hid_service.cc +++ b/device/hid/hid_service.cc @@ -25,6 +25,14 @@ namespace { HidService* g_service; } +void HidService::Observer::OnDeviceAdded( + scoped_refptr<HidDeviceInfo> device_info) { +} + +void HidService::Observer::OnDeviceRemoved( + scoped_refptr<HidDeviceInfo> device_info) { +} + HidService* HidService::GetInstance( scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { if (g_service == NULL) { @@ -53,7 +61,7 @@ void HidService::SetInstanceForTest(HidService* instance) { void HidService::GetDevices(const GetDevicesCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (enumeration_ready_) { - std::vector<HidDeviceInfo> devices; + std::vector<scoped_refptr<HidDeviceInfo>> devices; for (const auto& map_entry : devices_) { devices.push_back(map_entry.second); } @@ -73,14 +81,14 @@ void HidService::RemoveObserver(HidService::Observer* observer) { } // Fills in the device info struct of the given device_id. -bool HidService::GetDeviceInfo(const HidDeviceId& device_id, - HidDeviceInfo* info) const { +scoped_refptr<HidDeviceInfo> HidService::GetDeviceInfo( + const HidDeviceId& device_id) const { DCHECK(thread_checker_.CalledOnValidThread()); DeviceMap::const_iterator it = devices_.find(device_id); - if (it == devices_.end()) - return false; - *info = it->second; - return true; + if (it == devices_.end()) { + return nullptr; + } + return it->second; } HidService::HidService() : enumeration_ready_(false) { @@ -90,13 +98,13 @@ HidService::~HidService() { DCHECK(thread_checker_.CalledOnValidThread()); } -void HidService::AddDevice(const HidDeviceInfo& info) { +void HidService::AddDevice(scoped_refptr<HidDeviceInfo> device_info) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(devices_, info.device_id)) { - devices_[info.device_id] = info; + if (!ContainsKey(devices_, device_info->device_id())) { + devices_[device_info->device_id()] = device_info; if (enumeration_ready_) { - FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceAdded(info)); + FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceAdded(device_info)); } } } @@ -116,7 +124,7 @@ void HidService::FirstEnumerationComplete() { enumeration_ready_ = true; if (!pending_enumerations_.empty()) { - std::vector<HidDeviceInfo> devices; + std::vector<scoped_refptr<HidDeviceInfo>> devices; for (const auto& map_entry : devices_) { devices.push_back(map_entry.second); } diff --git a/device/hid/hid_service.h b/device/hid/hid_service.h index 8d296c0..6d6ef2b 100644 --- a/device/hid/hid_service.h +++ b/device/hid/hid_service.h @@ -26,11 +26,11 @@ class HidService { public: class Observer { public: - virtual void OnDeviceAdded(const HidDeviceInfo& info) {} - virtual void OnDeviceRemoved(const HidDeviceInfo& info) {} + virtual void OnDeviceAdded(scoped_refptr<HidDeviceInfo> info); + virtual void OnDeviceRemoved(scoped_refptr<HidDeviceInfo> info); }; - typedef base::Callback<void(const std::vector<HidDeviceInfo>&)> + typedef base::Callback<void(const std::vector<scoped_refptr<HidDeviceInfo>>&)> GetDevicesCallback; typedef base::Callback<void(scoped_refptr<HidConnection> connection)> ConnectCallback; @@ -51,8 +51,9 @@ class HidService { void RemoveObserver(Observer* observer); // Fills in a DeviceInfo struct with info for the given device_id. - // Returns |true| if successful or |false| if |device_id| is invalid. - bool GetDeviceInfo(const HidDeviceId& device_id, HidDeviceInfo* info) const; + // Returns |nullptr| if |device_id| is invalid. + scoped_refptr<HidDeviceInfo> GetDeviceInfo( + const HidDeviceId& device_id) const; // Opens a connection to a device. The callback will be run with null on // failure. @@ -63,12 +64,12 @@ class HidService { friend void base::DeletePointer<HidService>(HidService* service); friend class HidConnectionTest; - typedef std::map<HidDeviceId, HidDeviceInfo> DeviceMap; + typedef std::map<HidDeviceId, scoped_refptr<HidDeviceInfo>> DeviceMap; HidService(); virtual ~HidService(); - void AddDevice(const HidDeviceInfo& info); + void AddDevice(scoped_refptr<HidDeviceInfo> info); void RemoveDevice(const HidDeviceId& device_id); void FirstEnumerationComplete(); diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc index 76ba3af..556f3bb 100644 --- a/device/hid/hid_service_linux.cc +++ b/device/hid/hid_service_linux.cc @@ -43,7 +43,7 @@ const char kSysfsReportDescriptorKey[] = "report_descriptor"; } // namespace struct HidServiceLinux::ConnectParams { - ConnectParams(const HidDeviceInfo& device_info, + ConnectParams(scoped_refptr<HidDeviceInfo> device_info, const ConnectCallback& callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) @@ -53,7 +53,7 @@ struct HidServiceLinux::ConnectParams { file_task_runner(file_task_runner) {} ~ConnectParams() {} - HidDeviceInfo device_info; + scoped_refptr<HidDeviceInfo> device_info; ConnectCallback callback; scoped_refptr<base::SingleThreadTaskRunner> task_runner; scoped_refptr<base::SingleThreadTaskRunner> file_task_runner; @@ -90,14 +90,14 @@ class HidServiceLinux::Helper : public DeviceMonitorLinux::Observer, return; } - HidDeviceInfo device_info; - device_info.device_id = device_path; + scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); + device_info->device_id_ = device_path; const char* str_property = udev_device_get_devnode(device); if (!str_property) { return; } - device_info.device_node = str_property; + device_info->device_node_ = str_property; udev_device* parent = udev_device_get_parent(device); if (!parent) { @@ -117,21 +117,21 @@ class HidServiceLinux::Helper : public DeviceMonitorLinux::Observer, uint32_t int_property = 0; if (HexStringToUInt(base::StringPiece(parts[1]), &int_property)) { - device_info.vendor_id = int_property; + device_info->vendor_id_ = int_property; } if (HexStringToUInt(base::StringPiece(parts[2]), &int_property)) { - device_info.product_id = int_property; + device_info->product_id_ = int_property; } str_property = udev_device_get_property_value(parent, kHIDUnique); if (str_property != NULL) { - device_info.serial_number = str_property; + device_info->serial_number_ = str_property; } str_property = udev_device_get_property_value(parent, kHIDName); if (str_property != NULL) { - device_info.product_name = str_property; + device_info->product_name_ = str_property; } const char* parent_sysfs_path = udev_device_get_syspath(parent); @@ -149,10 +149,11 @@ class HidServiceLinux::Helper : public DeviceMonitorLinux::Observer, HidReportDescriptor report_descriptor( reinterpret_cast<uint8_t*>(&report_descriptor_str[0]), report_descriptor_str.length()); - report_descriptor.GetDetails( - &device_info.collections, &device_info.has_report_id, - &device_info.max_input_report_size, &device_info.max_output_report_size, - &device_info.max_feature_report_size); + report_descriptor.GetDetails(&device_info->collections_, + &device_info->has_report_id_, + &device_info->max_input_report_size_, + &device_info->max_output_report_size_, + &device_info->max_feature_report_size_); task_runner_->PostTask(FROM_HERE, base::Bind(&HidServiceLinux::AddDevice, service_, device_info)); @@ -213,7 +214,7 @@ void HidServiceLinux::Connect(const HidDeviceId& device_id, task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); return; } - const HidDeviceInfo& device_info = map_entry->second; + scoped_refptr<HidDeviceInfo> device_info = map_entry->second; scoped_ptr<ConnectParams> params(new ConnectParams( device_info, callback, task_runner_, file_task_runner_)); @@ -225,7 +226,7 @@ void HidServiceLinux::Connect(const HidDeviceId& device_id, DCHECK(client) << "Could not get permission broker client."; if (client) { client->RequestPathAccess( - device_info.device_node, -1, + device_info->device_node(), -1, base::Bind(&HidServiceLinux::OnRequestPathAccessComplete, base::Passed(¶ms))); } else { @@ -265,7 +266,7 @@ void HidServiceLinux::OnRequestPathAccessComplete( void HidServiceLinux::OpenDevice(scoped_ptr<ConnectParams> params) { base::ThreadRestrictions::AssertIOAllowed(); scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; - base::FilePath device_path(params->device_info.device_node); + base::FilePath device_path(params->device_info->device_node()); base::File& device_file = params->device_file; int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; @@ -280,7 +281,8 @@ void HidServiceLinux::OpenDevice(scoped_ptr<ConnectParams> params) { } } if (!device_file.IsValid()) { - LOG(ERROR) << "Failed to open '" << params->device_info.device_node << "': " + LOG(ERROR) << "Failed to open '" << params->device_info->device_node() + << "': " << base::File::ErrorToString(device_file.error_details()); task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); return; diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc index 0ee1ce3..5c3f5bd 100644 --- a/device/hid/hid_service_mac.cc +++ b/device/hid/hid_service_mac.cc @@ -127,57 +127,6 @@ bool GetCollectionInfos(IOHIDDeviceRef device, return true; } -bool PopulateDeviceInfo(io_service_t service, HidDeviceInfo* device_info) { - io_string_t service_path; - IOReturn result = - IORegistryEntryGetPath(service, kIOServicePlane, service_path); - if (result != kIOReturnSuccess) { - VLOG(1) << "Failed to get IOService path: " - << base::StringPrintf("0x%04x", result); - return false; - } - - base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device( - IOHIDDeviceCreate(kCFAllocatorDefault, service)); - if (!hid_device) { - VLOG(1) << "Unable to create IOHIDDevice object for " << service_path - << "."; - return false; - } - - device_info->device_id = service_path; - device_info->vendor_id = - GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)); - device_info->product_id = - GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)); - device_info->product_name = - GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)); - device_info->serial_number = - GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)); - if (!GetCollectionInfos(hid_device, &device_info->has_report_id, - &device_info->collections)) { - VLOG(1) << "Unable to get collection info for " << service_path << "."; - return false; - } - device_info->max_input_report_size = - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxInputReportSizeKey)); - if (device_info->has_report_id && device_info->max_input_report_size > 0) { - device_info->max_input_report_size--; - } - device_info->max_output_report_size = - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxOutputReportSizeKey)); - if (device_info->has_report_id && device_info->max_output_report_size > 0) { - device_info->max_output_report_size--; - } - device_info->max_feature_report_size = - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxFeatureReportSizeKey)); - if (device_info->has_report_id && device_info->max_feature_report_size > 0) { - device_info->max_feature_report_size--; - } - - return true; -} - } // namespace HidServiceMac::HidServiceMac( @@ -228,6 +177,49 @@ HidServiceMac::HidServiceMac( FirstEnumerationComplete(); } +void HidServiceMac::Connect(const HidDeviceId& device_id, + const ConnectCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + const auto& map_entry = devices().find(device_id); + if (map_entry == devices().end()) { + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; + } + scoped_refptr<HidDeviceInfo> device_info = map_entry->second; + + io_string_t service_path; + strncpy(service_path, device_id.c_str(), sizeof service_path); + base::mac::ScopedIOObject<io_service_t> service( + IORegistryEntryFromPath(kIOMasterPortDefault, service_path)); + if (!service.get()) { + VLOG(1) << "IOService not found for path: " << device_id; + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; + } + + base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device( + IOHIDDeviceCreate(kCFAllocatorDefault, service)); + if (!hid_device) { + VLOG(1) << "Unable to create IOHIDDevice object."; + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; + } + + IOReturn result = IOHIDDeviceOpen(hid_device, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + VLOG(1) << "Failed to open device: " << base::StringPrintf("0x%04x", + result); + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; + } + + task_runner_->PostTask( + FROM_HERE, base::Bind(callback, make_scoped_refptr(new HidConnectionMac( + hid_device.release(), device_info, + file_task_runner_)))); +} + HidServiceMac::~HidServiceMac() { } @@ -252,12 +244,14 @@ void HidServiceMac::AddDevices() { io_service_t device; while ((device = IOIteratorNext(devices_added_iterator_)) != IO_OBJECT_NULL) { - HidDeviceInfo device_info; - if (PopulateDeviceInfo(device, &device_info)) { + scoped_refptr<HidDeviceInfo> device_info = CreateDeviceInfo(device); + if (device_info) { AddDevice(device_info); + // The reference retained by IOIteratorNext is released below in + // RemoveDevices when the device is removed. + } else { + IOObjectRelease(device); } - // The reference retained by IOIteratorNext is released below in - // RemoveDevices when the device is removed. } } @@ -281,48 +275,61 @@ void HidServiceMac::RemoveDevices() { } } -void HidServiceMac::Connect(const HidDeviceId& device_id, - const ConnectCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - const auto& map_entry = devices().find(device_id); - if (map_entry == devices().end()) { - task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); - return; - } - const HidDeviceInfo& device_info = map_entry->second; - +// static +scoped_refptr<HidDeviceInfo> HidServiceMac::CreateDeviceInfo( + io_service_t service) { + scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); io_string_t service_path; - strncpy(service_path, device_id.c_str(), sizeof service_path); - base::mac::ScopedIOObject<io_service_t> service( - IORegistryEntryFromPath(kIOMasterPortDefault, service_path)); - if (!service.get()) { - VLOG(1) << "IOService not found for path: " << device_id; - task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); - return; + IOReturn result = + IORegistryEntryGetPath(service, kIOServicePlane, service_path); + if (result != kIOReturnSuccess) { + VLOG(1) << "Failed to get IOService path: " << base::StringPrintf("0x%04x", + result); + return nullptr; } base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device( IOHIDDeviceCreate(kCFAllocatorDefault, service)); if (!hid_device) { - VLOG(1) << "Unable to create IOHIDDevice object."; - task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); - return; + VLOG(1) << "Unable to create IOHIDDevice object for " << service_path + << "."; + return nullptr; } - IOReturn result = IOHIDDeviceOpen(hid_device, kIOHIDOptionsTypeNone); - if (result != kIOReturnSuccess) { - VLOG(1) << "Failed to open device: " - << base::StringPrintf("0x%04x", result); - task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); - return; + device_info->device_id_ = service_path; + device_info->vendor_id_ = + GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)); + device_info->product_id_ = + GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)); + device_info->product_name_ = + GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)); + device_info->serial_number_ = + GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)); + if (!GetCollectionInfos(hid_device, &device_info->has_report_id_, + &device_info->collections_)) { + VLOG(1) << "Unable to get collection info for " << service_path << "."; + return nullptr; + } + device_info->max_input_report_size_ = + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxInputReportSizeKey)); + if (device_info->has_report_id() && + device_info->max_input_report_size() > 0) { + device_info->max_input_report_size_--; + } + device_info->max_output_report_size_ = + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxOutputReportSizeKey)); + if (device_info->has_report_id() && + device_info->max_output_report_size_ > 0) { + device_info->max_output_report_size_--; + } + device_info->max_feature_report_size_ = + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxFeatureReportSizeKey)); + if (device_info->has_report_id() && + device_info->max_feature_report_size_ > 0) { + device_info->max_feature_report_size_--; } - task_runner_->PostTask( - FROM_HERE, - base::Bind(callback, - make_scoped_refptr(new HidConnectionMac( - hid_device.release(), device_info, file_task_runner_)))); + return device_info; } } // namespace device diff --git a/device/hid/hid_service_mac.h b/device/hid/hid_service_mac.h index bfb58bd..11725d2 100644 --- a/device/hid/hid_service_mac.h +++ b/device/hid/hid_service_mac.h @@ -40,6 +40,9 @@ class HidServiceMac : public HidService { void AddDevices(); void RemoveDevices(); + static scoped_refptr<device::HidDeviceInfo> CreateDeviceInfo( + io_service_t device); + // Platform notification port. IONotificationPortRef notify_port_; base::mac::ScopedIOObject<io_iterator_t> devices_added_iterator_; diff --git a/device/hid/hid_service_win.cc b/device/hid/hid_service_win.cc index e497837..27f4148 100644 --- a/device/hid/hid_service_win.cc +++ b/device/hid/hid_service_win.cc @@ -47,9 +47,9 @@ void HidServiceWin::Connect(const HidDeviceId& device_id, task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); return; } - const HidDeviceInfo& device_info = map_entry->second; + scoped_refptr<HidDeviceInfo> device_info = map_entry->second; - base::win::ScopedHandle file(OpenDevice(device_info.device_id)); + base::win::ScopedHandle file(OpenDevice(device_info->device_id())); if (!file.IsValid()) { PLOG(ERROR) << "Failed to open device"; task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); @@ -156,9 +156,6 @@ void HidServiceWin::CollectInfoFromValueCaps( } void HidServiceWin::OnDeviceAdded(const std::string& device_path) { - HidDeviceInfo device_info; - device_info.device_id = device_path; - // Try to open the device. base::win::ScopedHandle device_handle(OpenDevice(device_path)); if (!device_handle.IsValid()) { @@ -172,8 +169,10 @@ void HidServiceWin::OnDeviceAdded(const std::string& device_path) { return; } - device_info.vendor_id = attrib.VendorID; - device_info.product_id = attrib.ProductID; + scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); + device_info->device_id_ = device_path; + device_info->vendor_id_ = attrib.VendorID; + device_info->product_id_ = attrib.ProductID; // Get usage and usage page (optional). PHIDP_PREPARSED_DATA preparsed_data; @@ -181,9 +180,10 @@ void HidServiceWin::OnDeviceAdded(const std::string& device_path) { preparsed_data) { HIDP_CAPS capabilities = {0}; if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { - device_info.max_input_report_size = capabilities.InputReportByteLength; - device_info.max_output_report_size = capabilities.OutputReportByteLength; - device_info.max_feature_report_size = + device_info->max_input_report_size_ = capabilities.InputReportByteLength; + device_info->max_output_report_size_ = + capabilities.OutputReportByteLength; + device_info->max_feature_report_size_ = capabilities.FeatureReportByteLength; HidCollectionInfo collection_info; collection_info.usage = HidUsageAndPage( @@ -214,21 +214,21 @@ void HidServiceWin::OnDeviceAdded(const std::string& device_path) { capabilities.NumberFeatureValueCaps, &collection_info); if (!collection_info.report_ids.empty()) { - device_info.has_report_id = true; + device_info->has_report_id_ = true; } - device_info.collections.push_back(collection_info); + device_info->collections_.push_back(collection_info); } // Whether or not the device includes report IDs in its reports the size // of the report ID is included in the value provided by Windows. This // appears contrary to the MSDN documentation. - if (device_info.max_input_report_size > 0) { - device_info.max_input_report_size--; + if (device_info->max_input_report_size() > 0) { + device_info->max_input_report_size_--; } - if (device_info.max_output_report_size > 0) { - device_info.max_output_report_size--; + if (device_info->max_output_report_size() > 0) { + device_info->max_output_report_size_--; } - if (device_info.max_feature_report_size > 0) { - device_info.max_feature_report_size--; + if (device_info->max_feature_report_size() > 0) { + device_info->max_feature_report_size_--; } HidD_FreePreparsedData(preparsed_data); } diff --git a/extensions/browser/api/hid/hid_api.cc b/extensions/browser/api/hid/hid_api.cc index 73e9150..e021cf2 100644 --- a/extensions/browser/api/hid/hid_api.cc +++ b/extensions/browser/api/hid/hid_api.cc @@ -121,8 +121,9 @@ ExtensionFunction::ResponseAction HidConnectFunction::Run() { return RespondNow(Error(kErrorServiceUnavailable)); } - HidDeviceInfo device_info; - if (!device_manager->GetDeviceInfo(parameters->device_id, &device_info)) { + scoped_refptr<HidDeviceInfo> device_info = + device_manager->GetDeviceInfo(parameters->device_id); + if (!device_info) { return RespondNow(Error(kErrorInvalidDeviceId)); } @@ -136,7 +137,7 @@ ExtensionFunction::ResponseAction HidConnectFunction::Run() { } hid_service->Connect( - device_info.device_id, + device_info->device_id(), base::Bind(&HidConnectFunction::OnConnectComplete, this)); return RespondLater(); } diff --git a/extensions/browser/api/hid/hid_apitest.cc b/extensions/browser/api/hid/hid_apitest.cc index e30457c..60c418a 100644 --- a/extensions/browser/api/hid/hid_apitest.cc +++ b/extensions/browser/api/hid/hid_apitest.cc @@ -14,10 +14,6 @@ #include "extensions/test/extension_test_message_listener.h" #include "net/base/io_buffer.h" -namespace extensions { - -namespace { - using base::ThreadTaskRunnerHandle; using device::HidCollectionInfo; using device::HidConnection; @@ -27,16 +23,18 @@ using device::HidService; using device::HidUsageAndPage; using net::IOBuffer; +namespace device { + class MockHidConnection : public HidConnection { public: - MockHidConnection(const HidDeviceInfo& device_info) + MockHidConnection(scoped_refptr<HidDeviceInfo> device_info) : HidConnection(device_info) {} void PlatformClose() override {} void PlatformRead(const ReadCallback& callback) override { const char kResult[] = "This is a HID input report."; - uint8_t report_id = device_info().has_report_id ? 1 : 0; + uint8_t report_id = device_info()->has_report_id() ? 1 : 0; scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(kResult))); buffer->data()[0] = report_id; memcpy(buffer->data() + 1, kResult, sizeof(kResult) - 1); @@ -51,7 +49,7 @@ class MockHidConnection : public HidConnection { bool result = false; if (size == sizeof(kExpected)) { uint8_t report_id = buffer->data()[0]; - uint8_t expected_report_id = device_info().has_report_id ? 1 : 0; + uint8_t expected_report_id = device_info()->has_report_id() ? 1 : 0; if (report_id == expected_report_id) { if (memcmp(buffer->data() + 1, kExpected, sizeof(kExpected) - 1) == 0) { result = true; @@ -67,7 +65,7 @@ class MockHidConnection : public HidConnection { const char kResult[] = "This is a HID feature report."; scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(kResult))); size_t offset = 0; - if (device_info().has_report_id) { + if (device_info()->has_report_id()) { buffer->data()[offset++] = report_id; } memcpy(buffer->data() + offset, kResult, sizeof(kResult) - 1); @@ -83,7 +81,7 @@ class MockHidConnection : public HidConnection { bool result = false; if (size == sizeof(kExpected)) { uint8_t report_id = buffer->data()[0]; - uint8_t expected_report_id = device_info().has_report_id ? 1 : 0; + uint8_t expected_report_id = device_info()->has_report_id() ? 1 : 0; if (report_id == expected_report_id && memcmp(buffer->data() + 1, kExpected, sizeof(kExpected) - 1) == 0) { result = true; @@ -130,22 +128,22 @@ class MockHidService : public HidService { int vendor_id, int product_id, bool report_id) { - HidDeviceInfo device_info; - device_info.device_id = device_id; - device_info.vendor_id = vendor_id; - device_info.product_id = product_id; - device_info.max_input_report_size = 128; - device_info.max_output_report_size = 128; - device_info.max_feature_report_size = 128; + scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); + device_info->device_id_ = device_id; + device_info->vendor_id_ = vendor_id; + device_info->product_id_ = product_id; + device_info->max_input_report_size_ = 128; + device_info->max_output_report_size_ = 128; + device_info->max_feature_report_size_ = 128; { HidCollectionInfo collection_info; if (report_id) { collection_info.usage = HidUsageAndPage(0, HidUsageAndPage::kPageVendor); collection_info.report_ids.insert(1); - device_info.has_report_id = true; + device_info->has_report_id_ = true; } - device_info.collections.push_back(collection_info); + device_info->collections_.push_back(collection_info); } HidService::AddDevice(device_info); } @@ -155,18 +153,20 @@ class MockHidService : public HidService { } }; -} // namespace +} // namespace device + +namespace extensions { class HidApiTest : public ShellApiTest { public: void SetUpOnMainThread() override { ShellApiTest::SetUpOnMainThread(); - hid_service_ = new MockHidService(); + hid_service_ = new device::MockHidService(); HidService::SetInstanceForTest(hid_service_); } protected: - MockHidService* hid_service_; + device::MockHidService* hid_service_; }; IN_PROC_BROWSER_TEST_F(HidApiTest, HidApp) { diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc index 5c84f8a9..c95d20f 100644 --- a/extensions/browser/api/hid/hid_device_manager.cc +++ b/extensions/browser/api/hid/hid_device_manager.cc @@ -26,14 +26,14 @@ namespace extensions { namespace { void PopulateHidDeviceInfo(hid::HidDeviceInfo* output, - const HidDeviceInfo& input) { - output->vendor_id = input.vendor_id; - output->product_id = input.product_id; - output->max_input_report_size = input.max_input_report_size; - output->max_output_report_size = input.max_output_report_size; - output->max_feature_report_size = input.max_feature_report_size; - - for (const device::HidCollectionInfo& collection : input.collections) { + scoped_refptr<HidDeviceInfo> input) { + output->vendor_id = input->vendor_id(); + output->product_id = input->product_id(); + output->max_input_report_size = input->max_input_report_size(); + output->max_output_report_size = input->max_output_report_size(); + output->max_feature_report_size = input->max_feature_report_size(); + + for (const device::HidCollectionInfo& collection : input->collections()) { // Don't expose sensitive data. if (collection.usage.IsProtected()) { continue; @@ -51,7 +51,7 @@ void PopulateHidDeviceInfo(hid::HidDeviceInfo* output, } } -bool WillDispatchDeviceEvent(const HidDeviceInfo& device_info, +bool WillDispatchDeviceEvent(scoped_refptr<HidDeviceInfo> device_info, content::BrowserContext* context, const Extension* extension, base::ListValue* event_args) { @@ -119,8 +119,7 @@ void HidDeviceManager::GetApiDevices( } } -bool HidDeviceManager::GetDeviceInfo(int resource_id, - HidDeviceInfo* device_info) { +scoped_refptr<HidDeviceInfo> HidDeviceManager::GetDeviceInfo(int resource_id) { DCHECK(thread_checker_.CalledOnValidThread()); HidService* hid_service = device::DeviceClient::Get()->GetHidService(); DCHECK(hid_service); @@ -128,18 +127,17 @@ bool HidDeviceManager::GetDeviceInfo(int resource_id, ResourceIdToDeviceIdMap::const_iterator device_iter = device_ids_.find(resource_id); if (device_iter == device_ids_.end()) { - return false; + return nullptr; } - return hid_service->GetDeviceInfo(device_iter->second, device_info); + return hid_service->GetDeviceInfo(device_iter->second); } // static bool HidDeviceManager::HasPermission(const Extension* extension, - const HidDeviceInfo& device_info) { + scoped_refptr<HidDeviceInfo> device_info) { UsbDevicePermission::CheckParam usbParam( - device_info.vendor_id, - device_info.product_id, + device_info->vendor_id(), device_info->product_id(), UsbDevicePermissionData::UNSPECIFIED_INTERFACE); if (extension->permissions_data()->CheckAPIPermissionWithParam( APIPermission::kUsbDevice, &usbParam)) { @@ -168,13 +166,13 @@ void HidDeviceManager::OnListenerAdded(const EventListenerInfo& details) { LazyInitialize(); } -void HidDeviceManager::OnDeviceAdded(const HidDeviceInfo& device_info) { +void HidDeviceManager::OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_LT(next_resource_id_, std::numeric_limits<int>::max()); int new_id = next_resource_id_++; - DCHECK(!ContainsKey(resource_ids_, device_info.device_id)); - resource_ids_[device_info.device_id] = new_id; - device_ids_[new_id] = device_info.device_id; + DCHECK(!ContainsKey(resource_ids_, device_info->device_id())); + resource_ids_[device_info->device_id()] = new_id; + device_ids_[new_id] = device_info->device_id(); // Don't generate events during the initial enumeration. if (enumeration_ready_ && event_router_) { @@ -190,9 +188,10 @@ void HidDeviceManager::OnDeviceAdded(const HidDeviceInfo& device_info) { } } -void HidDeviceManager::OnDeviceRemoved(const HidDeviceInfo& device_info) { +void HidDeviceManager::OnDeviceRemoved( + scoped_refptr<HidDeviceInfo> device_info) { DCHECK(thread_checker_.CalledOnValidThread()); - const auto& resource_entry = resource_ids_.find(device_info.device_id); + const auto& resource_entry = resource_ids_.find(device_info->device_id()); DCHECK(resource_entry != resource_ids_.end()); int resource_id = resource_entry->second; const auto& device_entry = device_ids_.find(resource_id); @@ -234,8 +233,9 @@ scoped_ptr<base::ListValue> HidDeviceManager::CreateApiDeviceList( int resource_id = map_entry.first; const HidDeviceId& device_id = map_entry.second; - HidDeviceInfo device_info; - if (!hid_service->GetDeviceInfo(device_id, &device_info)) { + scoped_refptr<HidDeviceInfo> device_info = + hid_service->GetDeviceInfo(device_id); + if (!device_info) { continue; } @@ -262,10 +262,10 @@ scoped_ptr<base::ListValue> HidDeviceManager::CreateApiDeviceList( } void HidDeviceManager::OnEnumerationComplete( - const std::vector<HidDeviceInfo>& devices) { + const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { DCHECK(resource_ids_.empty()); DCHECK(device_ids_.empty()); - for (const device::HidDeviceInfo& device_info : devices) { + for (const scoped_refptr<HidDeviceInfo>& device_info : devices) { OnDeviceAdded(device_info); } enumeration_ready_ = true; @@ -280,7 +280,7 @@ void HidDeviceManager::OnEnumerationComplete( void HidDeviceManager::DispatchEvent(const std::string& event_name, scoped_ptr<base::ListValue> event_args, - const HidDeviceInfo& device_info) { + scoped_refptr<HidDeviceInfo> device_info) { scoped_ptr<Event> event(new Event(event_name, event_args.Pass())); event->will_dispatch_callback = base::Bind(&WillDispatchDeviceEvent, device_info); diff --git a/extensions/browser/api/hid/hid_device_manager.h b/extensions/browser/api/hid/hid_device_manager.h index e979693..d39eccd 100644 --- a/extensions/browser/api/hid/hid_device_manager.h +++ b/extensions/browser/api/hid/hid_device_manager.h @@ -55,10 +55,10 @@ class HidDeviceManager : public BrowserContextKeyedAPI, const std::vector<device::HidDeviceFilter>& filters, const GetApiDevicesCallback& callback); - bool GetDeviceInfo(int resource_id, device::HidDeviceInfo* device_info); + scoped_refptr<device::HidDeviceInfo> GetDeviceInfo(int resource_id); static bool HasPermission(const Extension* extension, - const device::HidDeviceInfo& device_info); + scoped_refptr<device::HidDeviceInfo> device_info); private: friend class BrowserContextKeyedAPIFactory<HidDeviceManager>; @@ -80,8 +80,9 @@ class HidDeviceManager : public BrowserContextKeyedAPI, void OnListenerAdded(const EventListenerInfo& details) override; // HidService::Observer: - void OnDeviceAdded(const device::HidDeviceInfo& device_info) override; - void OnDeviceRemoved(const device::HidDeviceInfo& device_info) override; + void OnDeviceAdded(scoped_refptr<device::HidDeviceInfo> device_info) override; + void OnDeviceRemoved( + scoped_refptr<device::HidDeviceInfo> device_info) override; // Wait to perform an initial enumeration and register a HidService::Observer // until the first API customer makes a request or registers an event @@ -94,11 +95,12 @@ class HidDeviceManager : public BrowserContextKeyedAPI, scoped_ptr<base::ListValue> CreateApiDeviceList( const Extension* extension, const std::vector<device::HidDeviceFilter>& filters); - void OnEnumerationComplete(const std::vector<device::HidDeviceInfo>& devices); + void OnEnumerationComplete( + const std::vector<scoped_refptr<device::HidDeviceInfo>>& devices); void DispatchEvent(const std::string& event_name, scoped_ptr<base::ListValue> event_args, - const device::HidDeviceInfo& device_info); + scoped_refptr<device::HidDeviceInfo> device_info); base::ThreadChecker thread_checker_; EventRouter* event_router_; |