Commit f4dc9d14 authored by reillyg's avatar reillyg Committed by Commit bot

Add more generic filters to the chrome.hid.getDevices API.

Instead of specifying each of the USB vendor and product ID pairs an
app has permission to open this API extension allows filtering of
devices by vendor and product IDs as well as HID usage pages and
usages. The 'vendorId' and 'productId' properties of GetDevicesOptions
are still supported for backwards compatibility.

BUG=

Review URL: https://codereview.chromium.org/514923002

Cr-Commit-Position: refs/heads/master@{#292577}
parent 3a05d24b
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
'usb/usb_ids_unittest.cc', 'usb/usb_ids_unittest.cc',
'usb/usb_service_unittest.cc', 'usb/usb_service_unittest.cc',
'hid/hid_connection_unittest.cc', 'hid/hid_connection_unittest.cc',
'hid/hid_device_filter_unittest.cc',
'hid/hid_report_descriptor_unittest.cc', 'hid/hid_report_descriptor_unittest.cc',
'hid/hid_service_unittest.cc', 'hid/hid_service_unittest.cc',
'hid/input_service_linux_unittest.cc', 'hid/input_service_linux_unittest.cc',
......
...@@ -16,6 +16,8 @@ source_set("hid") { ...@@ -16,6 +16,8 @@ source_set("hid") {
"hid_connection_mac.h", "hid_connection_mac.h",
"hid_connection_win.cc", "hid_connection_win.cc",
"hid_connection_win.h", "hid_connection_win.h",
"hid_device_filter.cc",
"hid_device_filter.h",
"hid_device_info.cc", "hid_device_info.cc",
"hid_device_info.h", "hid_device_info.h",
"hid_report_descriptor.cc", "hid_report_descriptor.cc",
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
'hid_connection_mac.h', 'hid_connection_mac.h',
'hid_connection_win.cc', 'hid_connection_win.cc',
'hid_connection_win.h', 'hid_connection_win.h',
'hid_device_filter.cc',
'hid_device_filter.h',
'hid_device_info.cc', 'hid_device_info.cc',
'hid_device_info.h', 'hid_device_info.h',
'hid_report_descriptor.cc', 'hid_report_descriptor.cc',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/hid/hid_device_filter.h"
#include "device/hid/hid_device_info.h"
namespace device {
HidDeviceFilter::HidDeviceFilter()
: vendor_id_set_(false),
product_id_set_(false),
usage_page_set_(false),
usage_set_(false) {
}
HidDeviceFilter::~HidDeviceFilter() {
}
void HidDeviceFilter::SetVendorId(uint16_t vendor_id) {
vendor_id_set_ = true;
vendor_id_ = vendor_id;
}
void HidDeviceFilter::SetProductId(uint16_t product_id) {
product_id_set_ = true;
product_id_ = product_id;
}
void HidDeviceFilter::SetUsagePage(uint16_t usage_page) {
usage_page_set_ = true;
usage_page_ = usage_page;
}
void HidDeviceFilter::SetUsage(uint16_t usage) {
usage_set_ = true;
usage_ = usage;
}
bool HidDeviceFilter::Matches(const HidDeviceInfo& device_info) const {
if (vendor_id_set_) {
if (device_info.vendor_id != vendor_id_) {
return false;
}
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;
if (collection.usage.usage_page != usage_page_) {
continue;
}
if (usage_set_ && collection.usage.usage != usage_) {
continue;
}
found_matching_collection = true;
}
if (!found_matching_collection) {
return false;
}
}
return true;
}
// 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)) {
return true;
}
}
return false;
}
} // namespace device
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_HID_HID_DEVICE_FILTER_H_
#define DEVICE_HID_HID_DEVICE_FILTER_H_
#include <stdint.h>
#include <vector>
namespace device {
struct HidDeviceInfo;
class HidDeviceFilter {
public:
HidDeviceFilter();
~HidDeviceFilter();
void SetVendorId(uint16_t vendor_id);
void SetProductId(uint16_t product_id);
void SetUsagePage(uint16_t usage_page);
void SetUsage(uint16_t usage);
bool Matches(const HidDeviceInfo& device_info) const;
static bool MatchesAny(const HidDeviceInfo& device_info,
const std::vector<HidDeviceFilter>& filters);
private:
uint16_t vendor_id_;
uint16_t product_id_;
uint16_t usage_page_;
uint16_t usage_;
bool vendor_id_set_ : 1;
bool product_id_set_ : 1;
bool usage_page_set_ : 1;
bool usage_set_ : 1;
};
} // namespace device
#endif // DEVICE_HID_HID_DEVICE_FILTER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/hid/hid_device_filter.h"
#include "device/hid/hid_device_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
namespace {
class HidFilterTest : public testing::Test {
public:
virtual void SetUp() OVERRIDE {
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);
}
protected:
HidDeviceInfo device_info_;
};
TEST_F(HidFilterTest, MatchAny) {
HidDeviceFilter filter;
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchVendorId) {
HidDeviceFilter filter;
filter.SetVendorId(0x046d);
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchVendorIdNegative) {
HidDeviceFilter filter;
filter.SetVendorId(0x18d1);
ASSERT_FALSE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchProductId) {
HidDeviceFilter filter;
filter.SetVendorId(0x046d);
filter.SetProductId(0xc31c);
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchProductIdNegative) {
HidDeviceFilter filter;
filter.SetVendorId(0x046d);
filter.SetProductId(0x0801);
ASSERT_FALSE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchUsagePage) {
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageKeyboard);
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchUsagePageNegative) {
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageLed);
ASSERT_FALSE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchVendorAndUsagePage) {
HidDeviceFilter filter;
filter.SetVendorId(0x046d);
filter.SetUsagePage(HidUsageAndPage::kPageKeyboard);
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchUsageAndPage) {
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageKeyboard);
filter.SetUsage(0x01);
ASSERT_TRUE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchUsageAndPageNegative) {
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageKeyboard);
filter.SetUsage(0x02);
ASSERT_FALSE(filter.Matches(device_info_));
}
TEST_F(HidFilterTest, MatchEmptyFilterListNegative) {
std::vector<HidDeviceFilter> filters;
ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters));
}
TEST_F(HidFilterTest, MatchFilterList) {
std::vector<HidDeviceFilter> filters;
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageKeyboard);
filters.push_back(filter);
ASSERT_TRUE(HidDeviceFilter::MatchesAny(device_info_, filters));
}
TEST_F(HidFilterTest, MatchFilterListNegative) {
std::vector<HidDeviceFilter> filters;
HidDeviceFilter filter;
filter.SetUsagePage(HidUsageAndPage::kPageLed);
filters.push_back(filter);
ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters));
}
} // namespace
} // namespace device
...@@ -8,18 +8,18 @@ ...@@ -8,18 +8,18 @@
#include <vector> #include <vector>
#include "device/hid/hid_connection.h" #include "device/hid/hid_connection.h"
#include "device/hid/hid_device_filter.h"
#include "device/hid/hid_device_info.h" #include "device/hid/hid_device_info.h"
#include "device/hid/hid_service.h" #include "device/hid/hid_service.h"
#include "extensions/browser/api/api_resource_manager.h" #include "extensions/browser/api/api_resource_manager.h"
#include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/api/extensions_api_client.h"
#include "extensions/common/api/hid.h" #include "extensions/common/api/hid.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/permissions/usb_device_permission.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
namespace hid = extensions::core_api::hid; namespace hid = extensions::core_api::hid;
using device::HidConnection; using device::HidConnection;
using device::HidDeviceFilter;
using device::HidDeviceInfo; using device::HidDeviceInfo;
using device::HidService; using device::HidService;
...@@ -38,6 +38,22 @@ base::Value* PopulateHidConnection(int connection_id, ...@@ -38,6 +38,22 @@ base::Value* PopulateHidConnection(int connection_id,
return connection_value.ToValue().release(); return connection_value.ToValue().release();
} }
void ConvertHidDeviceFilter(linked_ptr<hid::DeviceFilter> input,
HidDeviceFilter* output) {
if (input->vendor_id) {
output->SetVendorId(*input->vendor_id);
}
if (input->product_id) {
output->SetProductId(*input->product_id);
}
if (input->usage_page) {
output->SetUsagePage(*input->usage_page);
}
if (input->usage) {
output->SetUsage(*input->usage);
}
}
} // namespace } // namespace
namespace extensions { namespace extensions {
...@@ -84,18 +100,23 @@ bool HidGetDevicesFunction::Prepare() { ...@@ -84,18 +100,23 @@ bool HidGetDevicesFunction::Prepare() {
} }
void HidGetDevicesFunction::AsyncWorkStart() { void HidGetDevicesFunction::AsyncWorkStart() {
const uint16_t vendor_id = parameters_->options.vendor_id; std::vector<HidDeviceFilter> filters;
const uint16_t product_id = parameters_->options.product_id; if (parameters_->options.filters) {
UsbDevicePermission::CheckParam param( filters.resize(parameters_->options.filters->size());
vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); for (size_t i = 0; i < parameters_->options.filters->size(); ++i) {
if (!extension()->permissions_data()->CheckAPIPermissionWithParam( ConvertHidDeviceFilter(parameters_->options.filters->at(i), &filters[i]);
APIPermission::kUsbDevice, &param)) { }
LOG(WARNING) << "Insufficient permissions to access device."; }
CompleteWithError(kErrorPermissionDenied); if (parameters_->options.vendor_id) {
return; HidDeviceFilter legacy_filter;
legacy_filter.SetVendorId(*parameters_->options.vendor_id);
if (parameters_->options.product_id) {
legacy_filter.SetProductId(*parameters_->options.product_id);
}
filters.push_back(legacy_filter);
} }
SetResult(device_manager_->GetApiDevices(vendor_id, product_id).release()); SetResult(device_manager_->GetApiDevices(extension(), filters).release());
AsyncWorkCompleted(); AsyncWorkCompleted();
} }
...@@ -116,12 +137,7 @@ void HidConnectFunction::AsyncWorkStart() { ...@@ -116,12 +137,7 @@ void HidConnectFunction::AsyncWorkStart() {
return; return;
} }
UsbDevicePermission::CheckParam param( if (!device_manager_->HasPermission(extension(), device_info)) {
device_info.vendor_id,
device_info.product_id,
UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
APIPermission::kUsbDevice, &param)) {
LOG(WARNING) << "Insufficient permissions to access device."; LOG(WARNING) << "Insufficient permissions to access device.";
CompleteWithError(kErrorPermissionDenied); CompleteWithError(kErrorPermissionDenied);
return; return;
......
...@@ -8,9 +8,13 @@ ...@@ -8,9 +8,13 @@
#include <vector> #include <vector>
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "device/hid/hid_device_filter.h"
#include "device/hid/hid_service.h" #include "device/hid/hid_service.h"
#include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/api/extensions_api_client.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/permissions/usb_device_permission.h"
using device::HidDeviceFilter;
using device::HidService; using device::HidService;
using device::HidUsageAndPage; using device::HidUsageAndPage;
...@@ -30,8 +34,8 @@ HidDeviceManager::GetFactoryInstance() { ...@@ -30,8 +34,8 @@ HidDeviceManager::GetFactoryInstance() {
} }
scoped_ptr<base::ListValue> HidDeviceManager::GetApiDevices( scoped_ptr<base::ListValue> HidDeviceManager::GetApiDevices(
uint16_t vendor_id, const Extension* extension,
uint16_t product_id) { const std::vector<HidDeviceFilter>& filters) {
UpdateDevices(); UpdateDevices();
HidService* hid_service = ExtensionsAPIClient::Get()->GetHidService(); HidService* hid_service = ExtensionsAPIClient::Get()->GetHidService();
...@@ -46,47 +50,52 @@ scoped_ptr<base::ListValue> HidDeviceManager::GetApiDevices( ...@@ -46,47 +50,52 @@ scoped_ptr<base::ListValue> HidDeviceManager::GetApiDevices(
device::HidDeviceInfo device_info; device::HidDeviceInfo device_info;
if (hid_service->GetDeviceInfo(device_id, &device_info)) { if (hid_service->GetDeviceInfo(device_id, &device_info)) {
if (device_info.vendor_id == vendor_id && if (!filters.empty() &&
device_info.product_id == product_id) { !HidDeviceFilter::MatchesAny(device_info, filters)) {
core_api::hid::HidDeviceInfo api_device_info; continue;
api_device_info.device_id = resource_id; }
api_device_info.vendor_id = device_info.vendor_id;
api_device_info.product_id = device_info.product_id; if (!HasPermission(extension, device_info)) {
api_device_info.max_input_report_size = continue;
device_info.max_input_report_size; }
api_device_info.max_output_report_size =
device_info.max_output_report_size; core_api::hid::HidDeviceInfo api_device_info;
api_device_info.max_feature_report_size = api_device_info.device_id = resource_id;
device_info.max_feature_report_size; api_device_info.vendor_id = device_info.vendor_id;
api_device_info.product_id = device_info.product_id;
for (std::vector<device::HidCollectionInfo>::const_iterator api_device_info.max_input_report_size = device_info.max_input_report_size;
collections_iter = device_info.collections.begin(); api_device_info.max_output_report_size =
collections_iter != device_info.collections.end(); device_info.max_output_report_size;
++collections_iter) { api_device_info.max_feature_report_size =
device::HidCollectionInfo collection = *collections_iter; device_info.max_feature_report_size;
// Don't expose sensitive data. for (std::vector<device::HidCollectionInfo>::const_iterator
if (collection.usage.IsProtected()) { collections_iter = device_info.collections.begin();
continue; collections_iter != device_info.collections.end();
} ++collections_iter) {
const device::HidCollectionInfo& collection = *collections_iter;
core_api::hid::HidCollectionInfo* api_collection =
new core_api::hid::HidCollectionInfo(); // Don't expose sensitive data.
api_collection->usage_page = collection.usage.usage_page; if (collection.usage.IsProtected()) {
api_collection->usage = collection.usage.usage; continue;
api_collection->report_ids.resize(collection.report_ids.size());
std::copy(collection.report_ids.begin(),
collection.report_ids.end(),
api_collection->report_ids.begin());
api_device_info.collections.push_back(
make_linked_ptr(api_collection));
} }
// Expose devices with which user can communicate. core_api::hid::HidCollectionInfo* api_collection =
if (api_device_info.collections.size() > 0) new core_api::hid::HidCollectionInfo();
api_devices->Append(api_device_info.ToValue().release()); api_collection->usage_page = collection.usage.usage_page;
api_collection->usage = collection.usage.usage;
api_collection->report_ids.resize(collection.report_ids.size());
std::copy(collection.report_ids.begin(),
collection.report_ids.end(),
api_collection->report_ids.begin());
api_device_info.collections.push_back(make_linked_ptr(api_collection));
}
// Expose devices with which user can communicate.
if (api_device_info.collections.size() > 0) {
api_devices->Append(api_device_info.ToValue().release());
} }
} }
} }
...@@ -108,6 +117,20 @@ bool HidDeviceManager::GetDeviceInfo(int resource_id, ...@@ -108,6 +117,20 @@ bool HidDeviceManager::GetDeviceInfo(int resource_id,
return hid_service->GetDeviceInfo(device_iter->second, device_info); return hid_service->GetDeviceInfo(device_iter->second, device_info);
} }
bool HidDeviceManager::HasPermission(const Extension* extension,
const device::HidDeviceInfo& device_info) {
UsbDevicePermission::CheckParam usbParam(
device_info.vendor_id,
device_info.product_id,
UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
if (extension->permissions_data()->CheckAPIPermissionWithParam(
APIPermission::kUsbDevice, &usbParam)) {
return true;
}
return false;
}
void HidDeviceManager::UpdateDevices() { void HidDeviceManager::UpdateDevices() {
thread_checker_.CalledOnValidThread(); thread_checker_.CalledOnValidThread();
HidService* hid_service = ExtensionsAPIClient::Get()->GetHidService(); HidService* hid_service = ExtensionsAPIClient::Get()->GetHidService();
......
...@@ -16,8 +16,14 @@ ...@@ -16,8 +16,14 @@
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/common/api/hid.h" #include "extensions/common/api/hid.h"
namespace device {
class HidDeviceFilter;
}
namespace extensions { namespace extensions {
class Extension;
class HidDeviceManager : public BrowserContextKeyedAPI { class HidDeviceManager : public BrowserContextKeyedAPI {
public: public:
explicit HidDeviceManager(content::BrowserContext* context); explicit HidDeviceManager(content::BrowserContext* context);
...@@ -31,11 +37,15 @@ class HidDeviceManager : public BrowserContextKeyedAPI { ...@@ -31,11 +37,15 @@ class HidDeviceManager : public BrowserContextKeyedAPI {
return BrowserContextKeyedAPIFactory<HidDeviceManager>::Get(context); return BrowserContextKeyedAPIFactory<HidDeviceManager>::Get(context);
} }
scoped_ptr<base::ListValue> GetApiDevices(uint16_t vendor_id, scoped_ptr<base::ListValue> GetApiDevices(
uint16_t product_id); const Extension* extension,
const std::vector<device::HidDeviceFilter>& filters);
bool GetDeviceInfo(int resource_id, device::HidDeviceInfo* device_info); bool GetDeviceInfo(int resource_id, device::HidDeviceInfo* device_info);
bool HasPermission(const Extension* extension,
const device::HidDeviceInfo& device_info);
private: private:
friend class BrowserContextKeyedAPIFactory<HidDeviceManager>; friend class BrowserContextKeyedAPIFactory<HidDeviceManager>;
......
...@@ -6,33 +6,29 @@ ...@@ -6,33 +6,29 @@
// This API provides access to HID operations from within the context of an app. // This API provides access to HID operations from within the context of an app.
// Using this API, apps can function as drivers for hardware devices. // Using this API, apps can function as drivers for hardware devices.
namespace hid { namespace hid {
// HID top-level collection attributes.
// Each enumerated device interface exposes an array of these objects.
// |usagePage|: HID usage page identifier.
// |usage|: Page-defined usage identifier.
// |reportIds|: Report IDs which belong to the collection and to its children.
dictionary HidCollectionInfo { dictionary HidCollectionInfo {
// HID usage page identifier.
long usagePage; long usagePage;
// Page-defined usage identifier.
long usage; long usage;
// Report IDs which belong to the collection and to its children.
long[] reportIds; long[] reportIds;
}; };
// Returned by <code>getDevices</code> functions to describes a connected HID [noinline_doc] dictionary HidDeviceInfo {
// device. Use <code>connect</code> to connect to any of the returned devices. // Device opaque ID.
// |deviceId|: Device opaque ID.
// |vendorId|: Vendor ID.
// |productId|: Product ID.
// |collections|: Top-level collections from this device's report descriptor.
// |maxInputReportSize|: Top-level collection's max input report size.
// |maxOutputReportSize|: Top-level collection's max output report size.
// |maxFeatureReportSize|: Top-level collection's max feature report size.
dictionary HidDeviceInfo {
long deviceId; long deviceId;
// Vendor ID.
long vendorId; long vendorId;
// Product ID.
long productId; long productId;
// Top-level collections from this device's report descriptors.
HidCollectionInfo[] collections; HidCollectionInfo[] collections;
// Top-level collection's maximum input report size.
long maxInputReportSize; long maxInputReportSize;
// Top-level collection's maximum output report size.
long maxOutputReportSize; long maxOutputReportSize;
// Top-level collection's maximum feature report size.
long maxFeatureReportSize; long maxFeatureReportSize;
}; };
...@@ -42,48 +38,54 @@ namespace hid { ...@@ -42,48 +38,54 @@ namespace hid {
long connectionId; long connectionId;
}; };
// Searching criteria to enumerate devices with. [noinline_doc] dictionary DeviceFilter {
// Device vendor ID.
long? vendorId;
// Device product ID, only checked only if the vendor ID matches.
long? productId;
// HID usage page identifier.
long? usagePage;
// HID usage identifier, checked only if the HID usage page matches.
long? usage;
};
dictionary GetDevicesOptions { dictionary GetDevicesOptions {
long vendorId; [deprecated="Equivalent to setting $(ref:DeviceFilter.vendorId)."]
long productId; long? vendorId;
[deprecated="Equivalent to setting $(ref:DeviceFilter.productId)."]
long? productId;
// A device matching any given filter will be returned. An empty filter list
// will return all devices the app has permission for.
DeviceFilter[]? filters;
}; };
callback GetDevicesCallback = void (HidDeviceInfo[] devices); callback GetDevicesCallback = void (HidDeviceInfo[] devices);
callback ConnectCallback = void (HidConnectInfo connection); callback ConnectCallback = void (HidConnectInfo connection);
callback DisconnectCallback = void (); callback DisconnectCallback = void ();
// The callback to be invoked when a <code>receive</code> call is finished.
// |reportId|: The ID of the report. // |reportId|: The ID of the report.
// |data|: The content of the report. // |data|: The content of the report.
callback ReceiveCallback = void (long reportId, ArrayBuffer data); callback ReceiveCallback = void (long reportId, ArrayBuffer data);
// The callback to be invoked when a <code>receiveFeatureReport</code> call
// is finished.
// |data|: The content of the report. // |data|: The content of the report.
callback ReceiveFeatureReportCallback = void (ArrayBuffer data); callback ReceiveFeatureReportCallback = void (ArrayBuffer data);
// The callback to be invoked when a <code>send</code> or
// <code>sendFeatureReport</code> call is finished.
callback SendCallback = void(); callback SendCallback = void();
interface Functions { interface Functions {
// Enumerate all the connected HID devices specified by the vendorId/ // Enumerate connected HID devices.
// productId/interfaceId tuple.
// |options|: The properties to search for on target devices. // |options|: The properties to search for on target devices.
// |callback|: Invoked with the <code>HidDeviceInfo</code> array on success.
static void getDevices(GetDevicesOptions options, static void getDevices(GetDevicesOptions options,
GetDevicesCallback callback); GetDevicesCallback callback);
// Open a connection to an HID device for communication. // Open a connection to an HID device for communication.
// |deviceId|: The ID of the device to open. // |deviceId|: The ID of the device to open.
// |callback|: Invoked with an <code>HidConnectInfo</code>.
static void connect(long deviceId, static void connect(long deviceId,
ConnectCallback callback); ConnectCallback callback);
// Disconnect from a device. Invoking operations on a device after calling // Disconnect from a device. Invoking operations on a device after calling
// this is safe but has no effect. // this is safe but has no effect.
// |connectionId|: The connection to close. // |connectionId|: The connection to close.
// |callback|: The callback to invoke once the device is closed.
static void disconnect(long connectionId, static void disconnect(long connectionId,
optional DisconnectCallback callback); optional DisconnectCallback callback);
...@@ -91,7 +93,6 @@ namespace hid { ...@@ -91,7 +93,6 @@ namespace hid {
// //
// Input reports are returned to the host through the INTERRUPT IN endpoint. // Input reports are returned to the host through the INTERRUPT IN endpoint.
// |connectionId|: The connection from which to receive a report. // |connectionId|: The connection from which to receive a report.
// |callback|: The callback to invoke with received report.
static void receive(long connectionId, static void receive(long connectionId,
ReceiveCallback callback); ReceiveCallback callback);
...@@ -103,7 +104,6 @@ namespace hid { ...@@ -103,7 +104,6 @@ namespace hid {
// |connectionId|: The connection to which to send a report. // |connectionId|: The connection to which to send a report.
// |reportId|: The report ID to use, or <code>0</code> if none. // |reportId|: The report ID to use, or <code>0</code> if none.
// |data|: The report data. // |data|: The report data.
// |callback|: The callback to invoke once the write is finished.
static void send(long connectionId, static void send(long connectionId,
long reportId, long reportId,
ArrayBuffer data, ArrayBuffer data,
...@@ -113,7 +113,6 @@ namespace hid { ...@@ -113,7 +113,6 @@ namespace hid {
// //
// |connectionId|: The connection to read Input report from. // |connectionId|: The connection to read Input report from.
// |reportId|: The report ID, or zero if none. // |reportId|: The report ID, or zero if none.
// |callback|: The callback to invoke once the write is finished.
static void receiveFeatureReport(long connectionId, static void receiveFeatureReport(long connectionId,
long reportId, long reportId,
ReceiveFeatureReportCallback callback); ReceiveFeatureReportCallback callback);
...@@ -125,7 +124,6 @@ namespace hid { ...@@ -125,7 +124,6 @@ namespace hid {
// |connectionId|: The connection to read Input report from. // |connectionId|: The connection to read Input report from.
// |reportId|: The report ID to use, or <code>0</code> if none. // |reportId|: The report ID to use, or <code>0</code> if none.
// |data|: The report data. // |data|: The report data.
// |callback|: The callback to invoke once the write is finished.
static void sendFeatureReport(long connectionId, static void sendFeatureReport(long connectionId,
long reportId, long reportId,
ArrayBuffer data, ArrayBuffer data,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment