summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--device/hid/hid_connection.cc39
-rw-r--r--device/hid/hid_connection.h6
-rw-r--r--device/hid/hid_connection_linux.cc12
-rw-r--r--device/hid/hid_connection_linux.h2
-rw-r--r--device/hid/hid_connection_mac.cc10
-rw-r--r--device/hid/hid_connection_mac.h4
-rw-r--r--device/hid/hid_connection_unittest.cc15
-rw-r--r--device/hid/hid_connection_win.cc6
-rw-r--r--device/hid/hid_connection_win.h2
-rw-r--r--device/hid/hid_device_filter.cc24
-rw-r--r--device/hid/hid_device_filter.h8
-rw-r--r--device/hid/hid_device_filter_unittest.cc13
-rw-r--r--device/hid/hid_device_info.cc16
-rw-r--r--device/hid/hid_device_info.h63
-rw-r--r--device/hid/hid_service.cc32
-rw-r--r--device/hid/hid_service.h15
-rw-r--r--device/hid/hid_service_linux.cc36
-rw-r--r--device/hid/hid_service_mac.cc181
-rw-r--r--device/hid/hid_service_mac.h3
-rw-r--r--device/hid/hid_service_win.cc36
-rw-r--r--extensions/browser/api/hid/hid_api.cc7
-rw-r--r--extensions/browser/api/hid/hid_apitest.cc42
-rw-r--r--extensions/browser/api/hid/hid_device_manager.cc54
-rw-r--r--extensions/browser/api/hid/hid_device_manager.h14
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(&params)));
} 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_;