Skip to content

Commit

Permalink
chrome.hid: enrich model with report IDs
Browse files Browse the repository at this point in the history
- add report IDs and max report size
- don't expose sensitive usages

BUG=364423
R=rockot@chromium.org
TESTS=run device_unittests (HidReportDescriptorTest)

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281133 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jracle@logitech.com committed Jul 3, 2014
1 parent 5a43fe6 commit 9ff3823
Show file tree
Hide file tree
Showing 27 changed files with 1,257 additions and 1,106 deletions.
95 changes: 37 additions & 58 deletions chrome/browser/extensions/api/hid/hid_device_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,53 @@ scoped_ptr<base::ListValue> HidDeviceManager::GetApiDevices(
int resource_id = device_iter->first;
device::HidDeviceId device_id = device_iter->second;
device::HidDeviceInfo device_info;

if (hid_service->GetDeviceInfo(device_id, &device_info)) {
if (device_info.vendor_id == vendor_id &&
device_info.product_id == product_id &&
IsDeviceAccessible(device_info)) {
device_info.product_id == product_id) {
api::hid::HidDeviceInfo api_device_info;
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;
for (std::vector<device::HidUsageAndPage>::const_iterator usage_iter =
device_info.usages.begin();
usage_iter != device_info.usages.end();
++usage_iter) {
api::hid::HidUsageAndPage* usage_and_page =
new api::hid::HidUsageAndPage();
usage_and_page->usage_page = (*usage_iter).usage_page;
usage_and_page->usage = (*usage_iter).usage;
linked_ptr<api::hid::HidUsageAndPage> usage_and_page_ptr(
usage_and_page);
api_device_info.usages.push_back(usage_and_page_ptr);
api_device_info.max_input_report_size =
device_info.max_input_report_size;
api_device_info.max_output_report_size =
device_info.max_output_report_size;
api_device_info.max_feature_report_size =
device_info.max_feature_report_size;

for (std::vector<device::HidCollectionInfo>::const_iterator
collections_iter = device_info.collections.begin();
collections_iter != device_info.collections.end();
++collections_iter) {
device::HidCollectionInfo collection = *collections_iter;

// Don't expose sensitive data.
if (collection.usage.IsProtected()) {
continue;
}

api::hid::HidCollectionInfo* api_collection =
new api::hid::HidCollectionInfo();
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));
}
api_devices->Append(api_device_info.ToValue().release());

// Expose devices with which user can communicate.
if (api_device_info.collections.size() > 0)
api_devices->Append(api_device_info.ToValue().release());
}
}
}

return scoped_ptr<base::ListValue>(api_devices);
}

Expand Down Expand Up @@ -116,48 +139,4 @@ void HidDeviceManager::UpdateDevices() {
resource_ids_.swap(new_resource_ids);
}

// static
// TODO(rockot): Add some tests for this.
bool HidDeviceManager::IsDeviceAccessible(
const device::HidDeviceInfo& device_info) {
for (std::vector<device::HidUsageAndPage>::const_iterator iter =
device_info.usages.begin();
iter != device_info.usages.end(); ++iter) {
if (!IsUsageAccessible(*iter)) {
return false;
}
}
return true;
}

// static
bool HidDeviceManager::IsUsageAccessible(
const HidUsageAndPage& usage_and_page) {
if (usage_and_page.usage_page == HidUsageAndPage::kPageKeyboard)
return false;

if (usage_and_page.usage_page != HidUsageAndPage::kPageGenericDesktop)
return true;

uint16_t usage = usage_and_page.usage;
if (usage == HidUsageAndPage::kGenericDesktopPointer ||
usage == HidUsageAndPage::kGenericDesktopMouse ||
usage == HidUsageAndPage::kGenericDesktopKeyboard ||
usage == HidUsageAndPage::kGenericDesktopKeypad) {
return false;
}

if (usage >= HidUsageAndPage::kGenericDesktopSystemControl &&
usage <= HidUsageAndPage::kGenericDesktopSystemWarmRestart) {
return false;
}

if (usage >= HidUsageAndPage::kGenericDesktopSystemDock &&
usage <= HidUsageAndPage::kGenericDesktopSystemDisplaySwap) {
return false;
}

return true;
}

} // namespace extensions
9 changes: 0 additions & 9 deletions chrome/browser/extensions/api/hid/hid_device_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@ class HidDeviceManager : public BrowserContextKeyedAPI {

void UpdateDevices();

// Determines if a given device interface should be accessible to API
// consumers. In order for a device interface to be accessible, ALL of its
// specified usages must be accessible.
static bool IsDeviceAccessible(const device::HidDeviceInfo& device_info);

// Determines if a given usage is available to API consumers. This is used to
// blacklist usages which could be security or privacy concerns.
static bool IsUsageAccessible(const device::HidUsageAndPage& usage_and_page);

base::ThreadChecker thread_checker_;

int next_resource_id_;
Expand Down
24 changes: 15 additions & 9 deletions chrome/common/extensions/api/hid.idl
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,34 @@
// 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.
namespace hid {
// HID usage pair. Each enumerated device interface exposes an array of
// these objects. Values correspond to those defined by the
// <a href="http://www.usb.org/developers/devclass_docs/HID1_11.pdf>
// HID device class specification</a>.
// |usage_page|: HID usage page identifier.
// 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.
dictionary HidUsageAndPage {
long usage_page;
// |reportIds|: Report IDs which belong to the collection and to its children.
dictionary HidCollectionInfo {
long usagePage;
long usage;
long[] reportIds;
};

// Returned by <code>getDevices</code> functions to describes a connected HID
// device. Use <code>connect</code> to connect to any of the returned devices.
// |deviceId|: Device opaque ID.
// |vendorId|: Vendor ID.
// |productId|: Product ID.
// |usages|: HID usage pairs exposed by underlying Top-level collections.
// |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 vendorId;
long productId;
HidUsageAndPage[] usages;
HidCollectionInfo[] collections;
long maxInputReportSize;
long maxOutputReportSize;
long maxFeatureReportSize;
};

// Returned by <code>connect</code> to represent a communication session with
Expand Down
4 changes: 2 additions & 2 deletions device/hid/hid.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
'sources': [
'device_monitor_linux.cc',
'device_monitor_linux.h',
'hid_collection_info.cc',
'hid_collection_info.h',
'hid_connection.cc',
'hid_connection.h',
'hid_connection_linux.cc',
Expand All @@ -40,8 +42,6 @@
'hid_service_win.h',
'hid_usage_and_page.cc',
'hid_usage_and_page.h',
'hid_utils_mac.cc',
'hid_utils_mac.h',
'input_service_linux.cc',
'input_service_linux.h',
],
Expand Down
17 changes: 17 additions & 0 deletions device/hid/hid_collection_info.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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_collection_info.h"

namespace device {

HidCollectionInfo::HidCollectionInfo()
: usage(HidUsageAndPage::kGenericDesktopUndefined,
HidUsageAndPage::kPageUndefined) {
}

HidCollectionInfo::~HidCollectionInfo() {
}

} // namespace device
29 changes: 29 additions & 0 deletions device/hid/hid_collection_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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_COLLECTION_INFO_H_
#define DEVICE_HID_HID_COLLECTION_INFO_H_

#include <set>

#include "device/hid/hid_usage_and_page.h"

namespace device {

struct HidCollectionInfo {
HidCollectionInfo();
~HidCollectionInfo();

// Collection's usage ID.
HidUsageAndPage usage;

// HID report IDs which belong
// to this collection or to its
// embedded collections.
std::set<int> report_ids;
};

} // namespace device"

#endif // DEVICE_HID_HID_COLLECTION_INFO_H_
Loading

0 comments on commit 9ff3823

Please sign in to comment.