Commit 0511c9e8 authored by Francois Beaufort's avatar Francois Beaufort Committed by Commit Bot

[WebHID] Change some interfaces to dictionaries

This CL changes HIDCollectionInfo, HIDReportInfo, and HIDReportItem
interfaces to dictionaries for easier logging with JSON and to avoid
polluting the window web namespace.

Spec: https://github.com/WICG/webhid/issues/22
Test: https://webhid-collections.glitch.me/

Change-Id: Ife8d089505312bba9f42e5d8fb1c466f44bd8e45
Bug: 890096
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2398541Reviewed-by: default avatarMatt Reynolds <mattreynolds@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Cr-Commit-Position: refs/heads/master@{#812626}
parent d0bda2ee
......@@ -1565,18 +1565,12 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gyroscope.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_element.cc",
......
......@@ -8,18 +8,12 @@ blink_modules_sources("hid") {
sources = [
"hid.cc",
"hid.h",
"hid_collection_info.cc",
"hid_collection_info.h",
"hid_connection_event.cc",
"hid_connection_event.h",
"hid_device.cc",
"hid_device.h",
"hid_input_report_event.cc",
"hid_input_report_event.h",
"hid_report_info.cc",
"hid_report_info.h",
"hid_report_item.cc",
"hid_report_item.h",
"navigator_hid.cc",
"navigator_hid.h",
]
......@@ -27,7 +21,7 @@ blink_modules_sources("hid") {
source_set("unit_tests") {
testonly = true
sources = [ "hid_report_item_test.cc" ]
sources = [ "hid_device_test.cc" ]
configs += [
"//third_party/blink/renderer:config",
......
// Copyright 2019 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 "third_party/blink/renderer/modules/hid/hid_collection_info.h"
#include "services/device/public/mojom/hid.mojom-blink.h"
#include "third_party/blink/renderer/modules/hid/hid_report_info.h"
namespace blink {
HIDCollectionInfo::HIDCollectionInfo(
const device::mojom::blink::HidCollectionInfo& info)
: usage_page_(info.usage->usage_page),
usage_(info.usage->usage),
collection_type_(info.collection_type) {
for (const auto& child : info.children)
children_.push_back(MakeGarbageCollected<HIDCollectionInfo>(*child));
for (const auto& report : info.input_reports)
input_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report));
for (const auto& report : info.output_reports)
output_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report));
for (const auto& report : info.feature_reports)
feature_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report));
}
HIDCollectionInfo::~HIDCollectionInfo() = default;
uint16_t HIDCollectionInfo::usagePage() const {
return usage_page_;
}
uint16_t HIDCollectionInfo::usage() const {
return usage_;
}
const HeapVector<Member<HIDCollectionInfo>>& HIDCollectionInfo::children()
const {
return children_;
}
const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::inputReports()
const {
return input_reports_;
}
const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::outputReports()
const {
return output_reports_;
}
const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::featureReports()
const {
return feature_reports_;
}
uint32_t HIDCollectionInfo::collectionType() const {
return collection_type_;
}
void HIDCollectionInfo::Trace(Visitor* visitor) const {
visitor->Trace(children_);
visitor->Trace(input_reports_);
visitor->Trace(output_reports_);
visitor->Trace(feature_reports_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_
#include "services/device/public/mojom/hid.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class HIDReportInfo;
class MODULES_EXPORT HIDCollectionInfo : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit HIDCollectionInfo(
const device::mojom::blink::HidCollectionInfo& collection);
~HIDCollectionInfo() override;
uint16_t usagePage() const;
uint16_t usage() const;
const HeapVector<Member<HIDCollectionInfo>>& children() const;
const HeapVector<Member<HIDReportInfo>>& inputReports() const;
const HeapVector<Member<HIDReportInfo>>& outputReports() const;
const HeapVector<Member<HIDReportInfo>>& featureReports() const;
uint32_t collectionType() const;
void Trace(Visitor* visitor) const override;
private:
uint16_t usage_page_;
uint16_t usage_;
uint32_t collection_type_;
HeapVector<Member<HIDCollectionInfo>> children_;
HeapVector<Member<HIDReportInfo>> input_reports_;
HeapVector<Member<HIDReportInfo>> output_reports_;
HeapVector<Member<HIDReportInfo>> feature_reports_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_
......@@ -5,24 +5,21 @@
// Information about a HID collection, including its reports and subcollections.
// https://wicg.github.io/webhid/index.html#report-descriptor
[
Exposed(Window WebHID),
SecureContext
] interface HIDCollectionInfo {
dictionary HIDCollectionInfo {
// The 16-bit usage page associated with this collection. Zero if not set.
readonly attribute unsigned short usagePage;
unsigned short usagePage;
// The 16-bit usage value associated with this collection. Zero if not set.
readonly attribute unsigned short usage;
unsigned short usage;
// The subcollections of this collection, in the order they were encountered
// in the report descriptor.
readonly attribute FrozenArray<HIDCollectionInfo> children;
sequence<HIDCollectionInfo> children;
// Input, output, and feature reports described in this collection, sorted
// by report ID. If this is a subcollection, only the portion of the report
// described within this collection is included.
readonly attribute FrozenArray<HIDReportInfo> inputReports;
readonly attribute FrozenArray<HIDReportInfo> outputReports;
readonly attribute FrozenArray<HIDReportInfo> featureReports;
sequence<HIDReportInfo> inputReports;
sequence<HIDReportInfo> outputReports;
sequence<HIDReportInfo> featureReports;
};
......@@ -6,13 +6,14 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/hid/hid.h"
#include "third_party/blink/renderer/modules/hid/hid_collection_info.h"
#include "third_party/blink/renderer/modules/hid/hid_input_report_event.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
......@@ -85,6 +86,129 @@ bool IsProtected(
return false;
}
// The HID specification defines four canonical unit systems. Each unit system
// corresponds to a set of units for length, mass, time, temperature, current,
// and luminous intensity. The vendor-defined unit system can be used for
// devices which produce measurements that cannot be adequately described by
// these unit systems.
//
// See the Units table in section 6.2.2.7 of the Device Class Definition for
// HID v1.11.
// https://www.usb.org/document-library/device-class-definition-hid-111
enum HidUnitSystem {
// none: No unit system
kUnitSystemNone = 0x00,
// si-linear: Centimeter, Gram, Seconds, Kelvin, Ampere, Candela
kUnitSystemSILinear = 0x01,
// si-rotation: Radians, Gram, Seconds, Kelvin, Ampere, Candela
kUnitSystemSIRotation = 0x02,
// english-linear: Inch, Slug, Seconds, Fahrenheit, Ampere, Candela
kUnitSystemEnglishLinear = 0x03,
// english-linear: Degrees, Slug, Seconds, Fahrenheit, Ampere, Candela
kUnitSystemEnglishRotation = 0x04,
// vendor-defined unit system
kUnitSystemVendorDefined = 0x0f,
};
uint32_t ConvertHidUsageAndPageToUint32(
const device::mojom::blink::HidUsageAndPage& usage) {
return (usage.usage_page) << 16 | usage.usage;
}
String UnitSystemToString(uint8_t unit) {
DCHECK_LE(unit, 0x0f);
switch (unit) {
case kUnitSystemNone:
return "none";
case kUnitSystemSILinear:
return "si-linear";
case kUnitSystemSIRotation:
return "si-rotation";
case kUnitSystemEnglishLinear:
return "english-linear";
case kUnitSystemEnglishRotation:
return "english-rotation";
case kUnitSystemVendorDefined:
return "vendor-defined";
default:
break;
}
// Values other than those defined in HidUnitSystem are reserved by the spec.
return "reserved";
}
// Convert |unit_factor_exponent| from its coded representation to a signed
// integer type.
int8_t UnitFactorExponentToInt(uint8_t unit_factor_exponent) {
DCHECK_LE(unit_factor_exponent, 0x0f);
// Values from 0x08 to 0x0f encode negative exponents.
if (unit_factor_exponent > 0x08)
return int8_t{unit_factor_exponent} - 16;
return unit_factor_exponent;
}
// Unpack the 32-bit unit definition value |unit| into each of its components.
// The unit definition value includes the unit system as well as unit factor
// exponents for each of the 6 units defined by the unit system.
void UnpackUnitValues(uint32_t unit,
String& unit_system,
int8_t& length_exponent,
int8_t& mass_exponent,
int8_t& time_exponent,
int8_t& temperature_exponent,
int8_t& current_exponent,
int8_t& luminous_intensity_exponent) {
unit_system = UnitSystemToString(unit & 0x0f);
length_exponent = UnitFactorExponentToInt((unit >> 4) & 0x0f);
mass_exponent = UnitFactorExponentToInt((unit >> 8) & 0x0f);
time_exponent = UnitFactorExponentToInt((unit >> 12) & 0x0f);
temperature_exponent = UnitFactorExponentToInt((unit >> 16) & 0x0f);
current_exponent = UnitFactorExponentToInt((unit >> 20) & 0x0f);
luminous_intensity_exponent = UnitFactorExponentToInt((unit >> 24) & 0x0f);
}
HIDReportInfo* ToHIDReportInfo(
const device::mojom::blink::HidReportDescription& report_info) {
HIDReportInfo* result = HIDReportInfo::Create();
result->setReportId(report_info.report_id);
HeapVector<Member<HIDReportItem>> items;
for (const auto& item : report_info.items)
items.push_back(HIDDevice::ToHIDReportItem(*item));
result->setItems(items);
return result;
}
HIDCollectionInfo* ToHIDCollectionInfo(
const device::mojom::blink::HidCollectionInfo& collection) {
HIDCollectionInfo* result = HIDCollectionInfo::Create();
result->setUsage(collection.usage->usage);
result->setUsagePage(collection.usage->usage_page);
HeapVector<Member<HIDReportInfo>> input_reports;
for (const auto& report : collection.input_reports)
input_reports.push_back(ToHIDReportInfo(*report));
result->setInputReports(input_reports);
HeapVector<Member<HIDReportInfo>> output_reports;
for (const auto& report : collection.output_reports)
output_reports.push_back(ToHIDReportInfo(*report));
result->setOutputReports(output_reports);
HeapVector<Member<HIDReportInfo>> feature_reports;
for (const auto& report : collection.feature_reports)
feature_reports.push_back(ToHIDReportInfo(*report));
result->setFeatureReports(feature_reports);
HeapVector<Member<HIDCollectionInfo>> children;
for (const auto& child : collection.children)
children.push_back(ToHIDCollectionInfo(*child));
result->setChildren(children);
return result;
}
} // namespace
HIDDevice::HIDDevice(HID* parent,
......@@ -98,10 +222,8 @@ HIDDevice::HIDDevice(HID* parent,
DCHECK(device_info_);
for (const auto& collection : device_info_->collections) {
// Omit information about top-level collections with protected usages.
if (!IsProtected(*collection->usage)) {
collections_.push_back(
MakeGarbageCollected<HIDCollectionInfo>(*collection));
}
if (!IsProtected(*collection->usage))
collections_.push_back(ToHIDCollectionInfo(*collection));
}
}
......@@ -373,4 +495,57 @@ void HIDDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) {
device_requests_.erase(find_result);
}
// static
HIDReportItem* HIDDevice::ToHIDReportItem(
const device::mojom::blink::HidReportItem& report_item) {
HIDReportItem* result = HIDReportItem::Create();
result->setIsAbsolute(!report_item.is_relative);
result->setIsArray(!report_item.is_variable);
result->setIsRange(report_item.is_range);
result->setHasNull(report_item.has_null_position);
result->setReportSize(report_item.report_size);
result->setReportCount(report_item.report_count);
result->setUnitExponent(
UnitFactorExponentToInt(report_item.unit_exponent & 0x0f));
result->setLogicalMinimum(report_item.logical_minimum);
result->setLogicalMaximum(report_item.logical_maximum);
result->setPhysicalMinimum(report_item.physical_minimum);
result->setPhysicalMaximum(report_item.physical_maximum);
Vector<uint32_t> usages;
for (const auto& usage : report_item.usages)
usages.push_back(ConvertHidUsageAndPageToUint32(*usage));
result->setUsages(usages);
result->setUsageMinimum(
ConvertHidUsageAndPageToUint32(*report_item.usage_minimum));
result->setUsageMaximum(
ConvertHidUsageAndPageToUint32(*report_item.usage_maximum));
String unit_system;
int8_t unit_factor_length_exponent;
int8_t unit_factor_mass_exponent;
int8_t unit_factor_time_exponent;
int8_t unit_factor_temperature_exponent;
int8_t unit_factor_current_exponent;
int8_t unit_factor_luminous_intensity_exponent;
UnpackUnitValues(report_item.unit, unit_system, unit_factor_length_exponent,
unit_factor_mass_exponent, unit_factor_time_exponent,
unit_factor_temperature_exponent,
unit_factor_current_exponent,
unit_factor_luminous_intensity_exponent);
result->setUnitSystem(unit_system);
result->setUnitFactorLengthExponent(unit_factor_length_exponent);
result->setUnitFactorMassExponent(unit_factor_mass_exponent);
result->setUnitFactorTimeExponent(unit_factor_time_exponent);
result->setUnitFactorTemperatureExponent(unit_factor_temperature_exponent);
result->setUnitFactorCurrentExponent(unit_factor_current_exponent);
result->setUnitFactorLuminousIntensityExponent(
unit_factor_luminous_intensity_exponent);
// TODO(mattreynolds): Set |strings_|.
return result;
}
} // namespace blink
......@@ -10,6 +10,7 @@
#include "third_party/blink/public/mojom/hid/hid.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
......@@ -70,6 +71,9 @@ class MODULES_EXPORT HIDDevice
// ExecutionContextLifecycleObserver:
void ContextDestroyed() override;
static HIDReportItem* ToHIDReportItem(
const device::mojom::blink::HidReportItem& report_item);
void Trace(Visitor*) const override;
private:
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Copyright 2020 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 "third_party/blink/renderer/modules/hid/hid_report_item.h"
#include "third_party/blink/renderer/modules/hid/hid_device.h"
#include "services/device/public/mojom/hid.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -61,38 +61,38 @@ device::mojom::blink::HidReportItemPtr MakeReportItem() {
} // namespace
TEST(HIDReportItemTest, singleUsageItem) {
TEST(HIDDeviceTest, singleUsageItem) {
device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem();
HIDReportItem item(*mojo_item);
HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item);
// Check that all item properties are correctly converted for the sample
// report item.
EXPECT_TRUE(item.isAbsolute());
EXPECT_FALSE(item.isArray());
EXPECT_FALSE(item.isRange());
EXPECT_FALSE(item.hasNull());
EXPECT_EQ(1U, item.usages().size());
EXPECT_EQ(0x00090001U, item.usages()[0]);
EXPECT_EQ(0U, item.usageMinimum());
EXPECT_EQ(0U, item.usageMaximum());
EXPECT_TRUE(item.strings().IsEmpty());
EXPECT_EQ(8U, item.reportSize());
EXPECT_EQ(1U, item.reportCount());
EXPECT_EQ(0, item.unitExponent());
EXPECT_EQ("none", item.unitSystem());
EXPECT_EQ(0, item.unitFactorLengthExponent());
EXPECT_EQ(0, item.unitFactorMassExponent());
EXPECT_EQ(0, item.unitFactorTimeExponent());
EXPECT_EQ(0, item.unitFactorTemperatureExponent());
EXPECT_EQ(0, item.unitFactorCurrentExponent());
EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent());
EXPECT_EQ(0, item.logicalMinimum());
EXPECT_EQ(1, item.logicalMaximum());
EXPECT_EQ(0, item.physicalMinimum());
EXPECT_EQ(1, item.physicalMaximum());
EXPECT_TRUE(item->isAbsolute());
EXPECT_FALSE(item->isArray());
EXPECT_FALSE(item->isRange());
EXPECT_FALSE(item->hasNull());
EXPECT_EQ(1U, item->usages().size());
EXPECT_EQ(0x00090001U, item->usages()[0]);
EXPECT_EQ(0U, item->usageMinimum());
EXPECT_EQ(0U, item->usageMaximum());
EXPECT_FALSE(item->hasStrings());
EXPECT_EQ(8U, item->reportSize());
EXPECT_EQ(1U, item->reportCount());
EXPECT_EQ(0, item->unitExponent());
EXPECT_EQ("none", item->unitSystem());
EXPECT_EQ(0, item->unitFactorLengthExponent());
EXPECT_EQ(0, item->unitFactorMassExponent());
EXPECT_EQ(0, item->unitFactorTimeExponent());
EXPECT_EQ(0, item->unitFactorTemperatureExponent());
EXPECT_EQ(0, item->unitFactorCurrentExponent());
EXPECT_EQ(0, item->unitFactorLuminousIntensityExponent());
EXPECT_EQ(0, item->logicalMinimum());
EXPECT_EQ(1, item->logicalMaximum());
EXPECT_EQ(0, item->physicalMinimum());
EXPECT_EQ(1, item->physicalMaximum());
}
TEST(HIDReportItemTest, multiUsageItem) {
TEST(HIDDeviceTest, multiUsageItem) {
device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem();
// Configure the item to use 8 non-consecutive usages.
......@@ -103,22 +103,22 @@ TEST(HIDReportItemTest, multiUsageItem) {
}
mojo_item->report_size = 1; // 1 bit.
mojo_item->report_count = 8;
HIDReportItem item(*mojo_item);
EXPECT_EQ(8U, item.usages().size());
EXPECT_EQ(0x00090002U, item.usages()[0]);
EXPECT_EQ(0x00090004U, item.usages()[1]);
EXPECT_EQ(0x00090006U, item.usages()[2]);
EXPECT_EQ(0x00090008U, item.usages()[3]);
EXPECT_EQ(0x0009000aU, item.usages()[4]);
EXPECT_EQ(0x0009000cU, item.usages()[5]);
EXPECT_EQ(0x0009000eU, item.usages()[6]);
EXPECT_EQ(0x00090010U, item.usages()[7]);
EXPECT_EQ(1U, item.reportSize());
EXPECT_EQ(8U, item.reportCount());
HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item);
EXPECT_EQ(8U, item->usages().size());
EXPECT_EQ(0x00090002U, item->usages()[0]);
EXPECT_EQ(0x00090004U, item->usages()[1]);
EXPECT_EQ(0x00090006U, item->usages()[2]);
EXPECT_EQ(0x00090008U, item->usages()[3]);
EXPECT_EQ(0x0009000aU, item->usages()[4]);
EXPECT_EQ(0x0009000cU, item->usages()[5]);
EXPECT_EQ(0x0009000eU, item->usages()[6]);
EXPECT_EQ(0x00090010U, item->usages()[7]);
EXPECT_EQ(1U, item->reportSize());
EXPECT_EQ(8U, item->reportCount());
}
TEST(HIDReportItemTest, usageRangeItem) {
TEST(HIDDeviceTest, usageRangeItem) {
device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem();
// Configure the item to use a usage range. The item defines eight fields,
......@@ -131,32 +131,32 @@ TEST(HIDReportItemTest, usageRangeItem) {
mojo_item->usage_maximum->usage = 0x08; // 8th button usage.
mojo_item->report_size = 1; // 1 bit.
mojo_item->report_count = 8;
HIDReportItem item(*mojo_item);
HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item);
EXPECT_TRUE(item.usages().IsEmpty());
EXPECT_EQ(0x00090001U, item.usageMinimum());
EXPECT_EQ(0x00090008U, item.usageMaximum());
EXPECT_EQ(1U, item.reportSize());
EXPECT_EQ(8U, item.reportCount());
EXPECT_FALSE(item->hasStrings());
EXPECT_EQ(0x00090001U, item->usageMinimum());
EXPECT_EQ(0x00090008U, item->usageMaximum());
EXPECT_EQ(1U, item->reportSize());
EXPECT_EQ(8U, item->reportCount());
}
TEST(HIDReportItemTest, unitDefinition) {
TEST(HIDDeviceTest, unitDefinition) {
device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem();
// Add a unit definition and check that the unit properties are correctly
// converted.
mojo_item->unit_exponent = 0x0C; // 10^-4
mojo_item->unit = 0x0000E111; // g*cm/s^2
HIDReportItem item(*mojo_item);
EXPECT_EQ("si-linear", item.unitSystem());
EXPECT_EQ(-4, item.unitExponent());
EXPECT_EQ(1, item.unitFactorLengthExponent());
EXPECT_EQ(1, item.unitFactorMassExponent());
EXPECT_EQ(-2, item.unitFactorTimeExponent());
EXPECT_EQ(0, item.unitFactorTemperatureExponent());
EXPECT_EQ(0, item.unitFactorCurrentExponent());
EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent());
HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item);
EXPECT_EQ("si-linear", item->unitSystem());
EXPECT_EQ(-4, item->unitExponent());
EXPECT_EQ(1, item->unitFactorLengthExponent());
EXPECT_EQ(1, item->unitFactorMassExponent());
EXPECT_EQ(-2, item->unitFactorTimeExponent());
EXPECT_EQ(0, item->unitFactorTemperatureExponent());
EXPECT_EQ(0, item->unitFactorCurrentExponent());
EXPECT_EQ(0, item->unitFactorLuminousIntensityExponent());
}
} // namespace blink
// Copyright 2019 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 "third_party/blink/renderer/modules/hid/hid_report_info.h"
#include "services/device/public/mojom/hid.mojom-blink.h"
#include "third_party/blink/renderer/modules/hid/hid_report_item.h"
namespace blink {
HIDReportInfo::HIDReportInfo(
const device::mojom::blink::HidReportDescription& report)
: report_id_(report.report_id) {
for (const auto& item : report.items)
items_.push_back(MakeGarbageCollected<HIDReportItem>(*item));
}
HIDReportInfo::~HIDReportInfo() {}
uint8_t HIDReportInfo::reportId() const {
return report_id_;
}
const HeapVector<Member<HIDReportItem>>& HIDReportInfo::items() const {
return items_;
}
void HIDReportInfo::Trace(Visitor* visitor) const {
visitor->Trace(items_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_
#include "services/device/public/mojom/hid.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class HIDReportItem;
class MODULES_EXPORT HIDReportInfo : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit HIDReportInfo(
const device::mojom::blink::HidReportDescription& report);
~HIDReportInfo() override;
uint8_t reportId() const;
const HeapVector<Member<HIDReportItem>>& items() const;
void Trace(Visitor* visitor) const override;
private:
uint8_t report_id_;
HeapVector<Member<HIDReportItem>> items_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_
......@@ -8,13 +8,10 @@
// only the portion of the report contained by the collection.
// https://wicg.github.io/webhid/index.html#report-descriptor
[
Exposed(Window WebHID),
SecureContext
] interface HIDReportInfo {
dictionary HIDReportInfo {
// The 8-bit report ID associated with this report.
readonly attribute octet reportId;
octet reportId;
// An ordered array that describes the fields within this report.
readonly attribute FrozenArray<HIDReportItem> items;
sequence<HIDReportItem> items;
};
// Copyright 2019 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 "third_party/blink/renderer/modules/hid/hid_report_item.h"
#include "services/device/public/mojom/hid.mojom-blink.h"
namespace blink {
namespace {
// The HID specification defines four canonical unit systems. Each unit system
// corresponds to a set of units for length, mass, time, temperature, current,
// and luminous intensity. The vendor-defined unit system can be used for
// devices which produce measurements that cannot be adequately described by
// these unit systems.
//
// See the Units table in section 6.2.2.7 of the Device Class Definition for
// HID v1.11.
// https://www.usb.org/document-library/device-class-definition-hid-111
enum HidUnitSystem {
// none: No unit system
kUnitSystemNone = 0x00,
// si-linear: Centimeter, Gram, Seconds, Kelvin, Ampere, Candela
kUnitSystemSILinear = 0x01,
// si-rotation: Radians, Gram, Seconds, Kelvin, Ampere, Candela
kUnitSystemSIRotation = 0x02,
// english-linear: Inch, Slug, Seconds, Fahrenheit, Ampere, Candela
kUnitSystemEnglishLinear = 0x03,
// english-linear: Degrees, Slug, Seconds, Fahrenheit, Ampere, Candela
kUnitSystemEnglishRotation = 0x04,
// vendor-defined unit system
kUnitSystemVendorDefined = 0x0f,
};
uint32_t ConvertHidUsageAndPageToUint32(
const device::mojom::blink::HidUsageAndPage& usage) {
return (usage.usage_page) << 16 | usage.usage;
}
String UnitSystemToString(uint8_t unit) {
DCHECK_LE(unit, 0x0f);
switch (unit) {
case kUnitSystemNone:
return "none";
case kUnitSystemSILinear:
return "si-linear";
case kUnitSystemSIRotation:
return "si-rotation";
case kUnitSystemEnglishLinear:
return "english-linear";
case kUnitSystemEnglishRotation:
return "english-rotation";
case kUnitSystemVendorDefined:
return "vendor-defined";
default:
break;
}
// Values other than those defined in HidUnitSystem are reserved by the spec.
return "reserved";
}
// Convert |unit_factor_exponent| from its coded representation to a signed
// integer type.
int8_t UnitFactorExponentToInt(uint8_t unit_factor_exponent) {
DCHECK_LE(unit_factor_exponent, 0x0f);
// Values from 0x08 to 0x0f encode negative exponents.
if (unit_factor_exponent > 0x08)
return int8_t{unit_factor_exponent} - 16;
return unit_factor_exponent;
}
// Unpack the 32-bit unit definition value |unit| into each of its components.
// The unit definition value includes the unit system as well as unit factor
// exponents for each of the 6 units defined by the unit system.
void UnpackUnitValues(uint32_t unit,
String& unit_system,
int8_t& length_exponent,
int8_t& mass_exponent,
int8_t& time_exponent,
int8_t& temperature_exponent,
int8_t& current_exponent,
int8_t& luminous_intensity_exponent) {
unit_system = UnitSystemToString(unit & 0x0f);
length_exponent = UnitFactorExponentToInt((unit >> 4) & 0x0f);
mass_exponent = UnitFactorExponentToInt((unit >> 8) & 0x0f);
time_exponent = UnitFactorExponentToInt((unit >> 12) & 0x0f);
temperature_exponent = UnitFactorExponentToInt((unit >> 16) & 0x0f);
current_exponent = UnitFactorExponentToInt((unit >> 20) & 0x0f);
luminous_intensity_exponent = UnitFactorExponentToInt((unit >> 24) & 0x0f);
}
} // namespace
HIDReportItem::HIDReportItem(const device::mojom::blink::HidReportItem& item)
: is_absolute_(!item.is_relative),
is_array_(!item.is_variable),
is_range_(item.is_range),
has_null_(item.has_null_position),
report_size_(item.report_size),
report_count_(item.report_count),
unit_exponent_(UnitFactorExponentToInt(item.unit_exponent & 0x0f)),
logical_minimum_(item.logical_minimum),
logical_maximum_(item.logical_maximum),
physical_minimum_(item.physical_minimum),
physical_maximum_(item.physical_maximum) {
for (const auto& usage : item.usages)
usages_.push_back(ConvertHidUsageAndPageToUint32(*usage));
usage_minimum_ = ConvertHidUsageAndPageToUint32(*item.usage_minimum);
usage_maximum_ = ConvertHidUsageAndPageToUint32(*item.usage_maximum);
UnpackUnitValues(item.unit, unit_system_, unit_factor_length_exponent_,
unit_factor_mass_exponent_, unit_factor_time_exponent_,
unit_factor_temperature_exponent_,
unit_factor_current_exponent_,
unit_factor_luminous_intensity_exponent_);
// TODO(mattreynolds): Set |strings_|.
}
HIDReportItem::~HIDReportItem() = default;
} // namespace blink
// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_
#include "services/device/public/mojom/hid.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class MODULES_EXPORT HIDReportItem : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit HIDReportItem(const device::mojom::blink::HidReportItem& item);
~HIDReportItem() override;
bool isAbsolute() const { return is_absolute_; }
bool isArray() const { return is_array_; }
bool isRange() const { return is_range_; }
bool hasNull() const { return has_null_; }
const Vector<uint32_t>& usages() const { return usages_; }
uint32_t usageMinimum() const { return usage_minimum_; }
uint32_t usageMaximum() const { return usage_maximum_; }
const Vector<String>& strings() const { return strings_; }
uint16_t reportSize() const { return report_size_; }
uint16_t reportCount() const { return report_count_; }
int8_t unitExponent() const { return unit_exponent_; }
String unitSystem() const { return unit_system_; }
int8_t unitFactorLengthExponent() const {
return unit_factor_length_exponent_;
}
int8_t unitFactorMassExponent() const { return unit_factor_mass_exponent_; }
int8_t unitFactorTimeExponent() const { return unit_factor_time_exponent_; }
int8_t unitFactorTemperatureExponent() const {
return unit_factor_temperature_exponent_;
}
int8_t unitFactorCurrentExponent() const {
return unit_factor_current_exponent_;
}
int8_t unitFactorLuminousIntensityExponent() const {
return unit_factor_luminous_intensity_exponent_;
}
int32_t logicalMinimum() const { return logical_minimum_; }
int32_t logicalMaximum() const { return logical_maximum_; }
int32_t physicalMinimum() const { return physical_minimum_; }
int32_t physicalMaximum() const { return physical_maximum_; }
private:
bool is_absolute_;
bool is_array_;
bool is_range_;
bool has_null_;
Vector<uint32_t> usages_;
Vector<String> strings_;
uint32_t usage_minimum_;
uint32_t usage_maximum_;
uint16_t report_size_;
uint16_t report_count_;
int8_t unit_exponent_;
String unit_system_;
int8_t unit_factor_length_exponent_;
int8_t unit_factor_mass_exponent_;
int8_t unit_factor_time_exponent_;
int8_t unit_factor_temperature_exponent_;
int8_t unit_factor_current_exponent_;
int8_t unit_factor_luminous_intensity_exponent_;
int32_t logical_minimum_;
int32_t logical_maximum_;
int32_t physical_minimum_;
int32_t physical_maximum_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_
......@@ -28,77 +28,74 @@ enum HIDUnitSystem {
"reserved",
};
[
Exposed(Window WebHID),
SecureContext
] interface HIDReportItem {
dictionary HIDReportItem {
// True if the item represents an absolute measurement (e.g. joystick tilt)
// or false if it represents a relative measurement (e.g. mouse movement).
readonly attribute boolean isAbsolute;
boolean isAbsolute;
// True if the item is an Array or false if it is a Variable. Array items
// are typically used when a device needs to represent a large number of
// button-type inputs, but only a few inputs need to be active at once.
// Variable items require space in the report for each input, but can report
// all inputs simultaneously.
readonly attribute boolean isArray;
boolean isArray;
// True if the usages for this item are defined by |usageMinimum| and
// |usageMaximum| or false if the usages are defined by |usages|.
readonly attribute boolean isRange;
boolean isRange;
// True if the item uses an out-of-bounds value when there is no input.
readonly attribute boolean hasNull;
boolean hasNull;
// An ordered list of 32-bit usage values associated with this item. Unused
// if |isRange| is true. If |reportCount| is two or more, usages are
// assigned from the list until the list is exhausted.
readonly attribute FrozenArray<unsigned long> usages;
sequence<unsigned long> usages;
// The minimum and maximum usage values associated with this item. Unused if
// |isRange| is false. If |reportCount| is two or more, usages are assigned
// starting from |usageMinimum| and increment by one.
readonly attribute unsigned long usageMinimum;
readonly attribute unsigned long usageMaximum;
unsigned long usageMinimum;
unsigned long usageMaximum;
// The size of a single field described by this item, in bits.
readonly attribute unsigned short reportSize;
unsigned short reportSize;
// The number of similar fields described by this item. The total size of
// the item described by this report is |reportSize| * |reportCount| bits.
readonly attribute unsigned short reportCount;
unsigned short reportCount;
// The base 10 exponent of the units for this report item. For instance, for
// kilograms |unitExponent| would be 3 and for micrograms it would be -6.
readonly attribute byte unitExponent;
byte unitExponent;
// The unit system determines which units are used for length, mass, time,
// temperature, current, and luminous intensity. May be "none" if the values
// for this report item are unitless.
readonly attribute HIDUnitSystem unitSystem;
HIDUnitSystem unitSystem;
// The following members determine the exponents for each factor of the
// unit definition. For instance, for acceleration all factors would have
// an exponent of 0 except |unitFactorLengthExponent| which would be 1 and
// |unitFactorTimeExponent| which would be -2.
readonly attribute byte unitFactorLengthExponent;
readonly attribute byte unitFactorMassExponent;
readonly attribute byte unitFactorTimeExponent;
readonly attribute byte unitFactorTemperatureExponent;
readonly attribute byte unitFactorCurrentExponent;
readonly attribute byte unitFactorLuminousIntensityExponent;
byte unitFactorLengthExponent;
byte unitFactorMassExponent;
byte unitFactorTimeExponent;
byte unitFactorTemperatureExponent;
byte unitFactorCurrentExponent;
byte unitFactorLuminousIntensityExponent;
// The minimum and maximum values that may be represented by this input. A
// device with |hasNull| may report a value outside this range to indicate
// no input.
readonly attribute long logicalMinimum;
readonly attribute long logicalMaximum;
long logicalMinimum;
long logicalMaximum;
// The minimum and maximum values, scaled to the units described by |unit|
// and |unitExponent|.
readonly attribute long physicalMinimum;
readonly attribute long physicalMaximum;
long physicalMinimum;
long physicalMaximum;
// The strings associated with this item.
readonly attribute FrozenArray<DOMString> strings;
sequence<DOMString> strings;
};
......@@ -4,18 +4,18 @@
modules_idl_files = [
"hid.idl",
"hid_collection_info.idl",
"hid_connection_event.idl",
"hid_device.idl",
"hid_input_report_event.idl",
"hid_report_info.idl",
"hid_report_item.idl",
]
modules_dictionary_idl_files = [
"hid_collection_info.idl",
"hid_connection_event_init.idl",
"hid_device_filter.idl",
"hid_device_request_options.idl",
"hid_report_info.idl",
"hid_report_item.idl",
]
modules_dependency_idl_files = [ "navigator_hid.idl" ]
......@@ -6653,9 +6653,6 @@ crbug.com/1112778 external/wpt/html/semantics/scripting-1/the-script-element/mod
crbug.com/1092048 external/wpt/FileAPI/blob/Blob-stream.any.html [ Pass Timeout ]
crbug.com/1092048 external/wpt/FileAPI/blob/Blob-stream.any.worker.html [ Pass Timeout ]
# Sheriff 2020-08-04: New wpt tests are failing
crbug.com/1112771 external/wpt/webhid/idlharness.https.window.html [ Failure ]
# Sheriff 2020-08-05
crbug.com/1113050 fast/borders/border-radius-mask-video-ratio.html [ Pass Failure ]
crbug.com/1113127 fast/canvas/downsample-quality.html [ Pass Failure Crash ]
......
......@@ -14,9 +14,6 @@ idl_test(
Navigator: ['navigator'],
// TODO: HIDConnectionEvent
// TODO: HIDInputReportEvent
// TODO: HIDReportItem
// TODO: HIDReportInfo
// TODO: HIDCollectionInfo
// TODO: HIDDevice
});
}
......
......@@ -106,8 +106,6 @@ hid_test(async (t, fake) => {
assert_equals(d.collections.length, 1, 'device.collections.length');
const c = d.collections[0];
assert_true(c instanceof HIDCollectionInfo,
'collection instanceof HIDCollectionInfo');
assert_equals(c.usagePage, device.mojom.PAGE_GENERIC_DESKTOP,
'collection.usagePage');
assert_equals(c.usage, device.mojom.GENERIC_DESKTOP_GAME_PAD,
......@@ -118,13 +116,10 @@ hid_test(async (t, fake) => {
assert_equals(c.featureReports.length, 0, 'collection.featureReports.length');
const r = c.inputReports[0];
assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo');
assert_equals(r.reportId, kTestReportId, 'report.reportId');
assert_equals(r.items.length, 1, 'report.items.length');
const i = r.items[0];
assert_true(i instanceof HIDReportItem,
'reportItem instanceof HIDReportItem');
assert_true(i.isAbsolute, 'reportItem.isAbsolute');
assert_false(i.isArray, 'reportItem.isArray');
assert_false(i.isRange, 'reportItem.isRange');
......@@ -153,7 +148,7 @@ hid_test(async (t, fake) => {
assert_equals(i.logicalMaximum, 1, 'reportItem.logicalMaximum');
assert_equals(i.physicalMinimum, 0, 'reportItem.physicalMinimum');
assert_equals(i.physicalMaximum, 1, 'reportItem.physicalMaximum');
assert_equals(i.strings.length, 0, 'reportItem.strings.length');
// TODO(mattreynolds): Check i.strings.length.
}, 'HIDDevice preserves device info');
hid_test(async (t, fake) => {
......@@ -180,17 +175,12 @@ hid_test(async (t, fake) => {
assert_equals(d.collections.length, 1, 'device.collections.length');
const c = d.collections[0];
assert_true(c instanceof HIDCollectionInfo,
'collection instanceof HIDCollectionInfo');
assert_equals(c.inputReports.length, 1, 'collection.inputReports.length');
const r = c.inputReports[0];
assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo');
assert_equals(r.items.length, 1, 'report.items.length');
const i = r.items[0];
assert_true(i instanceof HIDReportItem,
'reportItem instanceof HIDReportItem');
assert_equals(i.unitExponent, -4, 'reportItem.unitExponent');
assert_equals(i.unitSystem, 'si-linear', 'reportItem.unitSystem');
assert_equals(i.unitFactorLengthExponent, 1,
......
......@@ -2630,15 +2630,6 @@ interface HID : EventTarget
method requestDevice
setter onconnect
setter ondisconnect
interface HIDCollectionInfo
attribute @@toStringTag
getter children
getter featureReports
getter inputReports
getter outputReports
getter usage
getter usagePage
method constructor
interface HIDConnectionEvent : Event
attribute @@toStringTag
getter device
......@@ -2664,36 +2655,6 @@ interface HIDInputReportEvent : Event
getter device
getter reportId
method constructor
interface HIDReportInfo
attribute @@toStringTag
getter items
getter reportId
method constructor
interface HIDReportItem
attribute @@toStringTag
getter hasNull
getter isAbsolute
getter isArray
getter isRange
getter logicalMaximum
getter logicalMinimum
getter physicalMaximum
getter physicalMinimum
getter reportCount
getter reportSize
getter strings
getter unitExponent
getter unitFactorCurrentExponent
getter unitFactorLengthExponent
getter unitFactorLuminousIntensityExponent
getter unitFactorMassExponent
getter unitFactorTemperatureExponent
getter unitFactorTimeExponent
getter unitSystem
getter usageMaximum
getter usageMinimum
getter usages
method constructor
interface HTMLAllCollection
attribute @@toStringTag
getter length
......
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