1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var kInvalidDeviceId
= -1;
6 var kInvalidConnectionId
= -1;
8 var kReportDescriptor
= [0x06, 0x00, 0xFF, 0x08, 0xA1, 0x01, 0x15,
9 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95,
10 0x08, 0x08, 0x81, 0x02, 0x08, 0x91, 0x02,
11 0x08, 0xB1, 0x02, 0xC0];
12 var kReportDescriptorWithIDs
= [
13 0x06, 0x01, 0xFF, 0x08, 0xA1, 0x01, 0x15, 0x00, 0x26,
14 0xFF, 0x00, 0x85, 0x01, 0x75, 0x08, 0x95, 0x08, 0x08,
15 0x81, 0x02, 0x08, 0x91, 0x02, 0x08, 0xB1, 0x02, 0xC0];
17 function getDevice(wantReportIds
, callback
) {
18 chrome
.hid
.getDevices({}, function (devices
) {
19 chrome
.test
.assertNoLastError();
20 for (var device
of devices
) {
21 chrome
.test
.assertTrue(device
.collections
.length
> 0);
22 var foundReportId
= false;
23 for (var collection
of device
.collections
) {
24 if (collection
.reportIds
.length
> 0) {
28 if (wantReportIds
== foundReportId
) {
33 chrome
.test
.fail("No appropriate device found.");
37 function openDevice(wantReportIds
, callback
) {
38 getDevice(wantReportIds
, function (device
) {
39 chrome
.hid
.connect(device
.deviceId
, function (connection
) {
40 chrome
.test
.assertNoLastError();
41 callback(connection
.connectionId
);
46 function openDeviceWithReportId(callback
) {
47 return openDevice(true, callback
);
50 function openDeviceWithoutReportId(callback
) {
51 return openDevice(false, callback
);
54 function arrayBufferToString(buffer
) {
55 return String
.fromCharCode
.apply(null, new Uint8Array(buffer
));
58 function stringToArrayBuffer(string
) {
59 var buffer
= new ArrayBuffer(string
.length
);
60 var view
= new Uint8Array(buffer
);
61 for (var i
= 0; i
< string
.length
; i
++) {
62 view
[i
] = string
.charCodeAt(i
);
67 function assertArrayBufferEqualsListOfBytes(expected
, actual
) {
68 chrome
.test
.assertEq(expected
.length
, actual
.byteLength
);
69 var byteView
= new Uint8Array(actual
);
70 for (var i
= 0; i
< expected
.length
; i
++) {
71 chrome
.test
.assertEq(expected
[i
], byteView
[i
], 'index ' + i
);
75 function testGetDevicesWithNoOptions() {
76 chrome
.hid
.getDevices({}, function (devices
) {
77 chrome
.test
.assertNoLastError();
78 chrome
.test
.assertEq(2, devices
.length
, "Expected two enumerated devices.");
79 chrome
.test
.succeed("Device enumeration successful.");
83 function testGetDevicesWithLegacyVidAndPid() {
84 chrome
.hid
.getDevices({
87 }, function (devices
) {
88 chrome
.test
.assertNoLastError();
89 chrome
.test
.assertEq(2, devices
.length
, "Expected two enumerated devices.");
90 chrome
.test
.succeed("Device enumeration successful.");
94 function testGetDevicesWithNoFilters() {
95 chrome
.hid
.getDevices({ 'filters': [] }, function (devices
) {
96 chrome
.test
.assertNoLastError();
97 chrome
.test
.assertEq(2, devices
.length
, "Expected two enumerated devices.");
98 chrome
.test
.succeed("Device enumeration successful.");
102 function testGetDevicesWithVidPidFilter() {
103 chrome
.hid
.getDevices({ 'filters': [
104 { 'vendorId': 0x18D1, 'productId': 0x58F0}
105 ] }, function (devices
) {
106 chrome
.test
.assertNoLastError();
107 chrome
.test
.assertEq(2, devices
.length
, "Expected two enumerated devices.");
108 chrome
.test
.succeed("Device enumeration successful.");
112 function testGetDevicesWithUsageFilter() {
113 chrome
.hid
.getDevices({ 'filters': [
114 { 'usagePage': 0xFF00 } /* vendor-specified usage page */
115 ] }, function (devices
) {
116 chrome
.test
.assertNoLastError();
117 chrome
.test
.assertEq(1, devices
.length
, "Expected one enumerated device.");
118 var device
= devices
[0];
119 chrome
.test
.assertEq(1, device
.collections
.length
,
120 "Expected one collection.");
121 var collection
= device
.collections
[0];
122 chrome
.test
.assertEq(0xFF00, collection
.usagePage
);
123 chrome
.test
.succeed("Device enumeration successful.");
127 function testGetDevicesWithUnauthorizedDevice() {
128 chrome
.hid
.getDevices({ 'filters': [
129 { 'vendorId': 0x18D1, 'productId': 0x58F1}
130 ] }, function (devices
) {
131 chrome
.test
.assertNoLastError();
132 chrome
.test
.assertEq(0, devices
.length
, "Expected no enumerated devices.");
133 chrome
.test
.succeed("Device enumeration successful.");
137 function testDeviceInfo() {
138 var expectedDevices
= 2;
139 getDevice(false, function (deviceInfo
) {
140 chrome
.test
.assertEq(0x18D1, deviceInfo
.vendorId
);
141 chrome
.test
.assertEq(0x58F0, deviceInfo
.productId
);
142 chrome
.test
.assertEq("Test Device", deviceInfo
.productName
);
143 chrome
.test
.assertEq("A", deviceInfo
.serialNumber
);
144 chrome
.test
.assertEq(1, deviceInfo
.collections
.length
);
145 chrome
.test
.assertEq(0xFF00, deviceInfo
.collections
[0].usagePage
);
146 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].usage
);
147 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].reportIds
.length
);
148 assertArrayBufferEqualsListOfBytes(kReportDescriptor
,
149 deviceInfo
.reportDescriptor
);
150 if (--expectedDevices
== 0) {
151 chrome
.test
.succeed();
155 getDevice(true, function (deviceInfo
) {
156 chrome
.test
.assertEq(0x18D1, deviceInfo
.vendorId
);
157 chrome
.test
.assertEq(0x58F0, deviceInfo
.productId
);
158 chrome
.test
.assertEq(1, deviceInfo
.collections
.length
);
159 chrome
.test
.assertEq(0xFF01, deviceInfo
.collections
[0].usagePage
);
160 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].usage
);
161 chrome
.test
.assertEq(1, deviceInfo
.collections
[0].reportIds
.length
);
162 chrome
.test
.assertEq(1, deviceInfo
.collections
[0].reportIds
[0]);
163 assertArrayBufferEqualsListOfBytes(kReportDescriptorWithIDs
,
164 deviceInfo
.reportDescriptor
);
165 if (--expectedDevices
== 0) {
166 chrome
.test
.succeed();
171 function testConnectWithInvalidDeviceId() {
172 chrome
.hid
.connect(kInvalidDeviceId
, function (connection
) {
173 chrome
.test
.assertLastError("Invalid HID device ID.");
174 chrome
.test
.succeed("Rejected invalid device ID.");
178 function testConnectAndDisconnect() {
179 chrome
.hid
.getDevices({ 'filters': [
180 { 'vendorId': 0x18D1, 'productId': 0x58F0 }
181 ] }, function (devices
) {
182 chrome
.test
.assertNoLastError();
183 chrome
.test
.assertTrue(devices
.length
>= 1, "Expected connectable device.");
184 chrome
.hid
.connect(devices
[0].deviceId
, function (connection
) {
185 chrome
.test
.assertNoLastError();
186 chrome
.hid
.disconnect(connection
.connectionId
, function () {
187 chrome
.test
.assertNoLastError();
188 chrome
.test
.succeed("Opened and closed device.");
194 function testDisconnectWithInvalidConnectionId() {
195 chrome
.hid
.disconnect(kInvalidConnectionId
, function () {
196 chrome
.test
.assertLastError("Connection not established.");
197 chrome
.test
.succeed("Rejected invalid connection ID.");
201 function testReceiveWithInvalidConnectionId() {
202 chrome
.hid
.receive(kInvalidConnectionId
, function (reportId
, data
) {
203 chrome
.test
.assertLastError("Connection not established.");
204 chrome
.test
.succeed("Rejected invalid connection ID.");
208 function testReceiveWithReportId() {
209 openDeviceWithReportId(function (connection
) {
210 chrome
.hid
.receive(connection
, function (reportId
, data
) {
211 chrome
.test
.assertEq(1, reportId
, "Expected report_id == 1.");
212 var expected
= "This is a HID input report.";
213 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
214 chrome
.test
.succeed("Receive successful.");
219 function testReceiveWithoutReportId() {
220 openDeviceWithoutReportId(function (connection
) {
221 chrome
.hid
.receive(connection
, function (reportId
, data
) {
222 chrome
.test
.assertNoLastError();
223 chrome
.test
.assertEq(0, reportId
, "Expected report_id == 0.");
224 var expected
= "This is a HID input report.";
225 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
226 chrome
.test
.succeed("Receive successful.");
231 function testSendWithInvalidConnectionId() {
232 var buffer
= new ArrayBuffer();
233 chrome
.hid
.send(kInvalidConnectionId
, 0, buffer
, function () {
234 chrome
.test
.assertLastError("Connection not established.");
235 chrome
.test
.succeed("Rejected invalid connection ID.");
239 function testSendOversizeReport() {
240 openDeviceWithReportId(function (connection
) {
241 var buffer
= stringToArrayBuffer("oversize report");
242 chrome
.hid
.send(connection
, 1, buffer
, function () {
243 chrome
.test
.assertLastError("Transfer failed.");
244 chrome
.hid
.disconnect(connection
);
245 chrome
.test
.succeed("Caught oversize report.");
250 function testSendWithReportId() {
251 openDeviceWithReportId(function (connection
) {
252 var buffer
= stringToArrayBuffer("o-report");
253 chrome
.hid
.send(connection
, 1, buffer
, function () {
254 chrome
.test
.assertNoLastError();
255 chrome
.hid
.disconnect(connection
);
256 chrome
.test
.succeed("Send successful.");
261 function testSendWithoutReportId() {
262 openDeviceWithoutReportId(function (connection
) {
263 var buffer
= stringToArrayBuffer("o-report");
264 chrome
.hid
.send(connection
, 0, buffer
, function () {
265 chrome
.test
.assertNoLastError();
266 chrome
.hid
.disconnect(connection
);
267 chrome
.test
.succeed("Send successful.");
272 function testSendWithInvalidReportId() {
273 openDeviceWithReportId(function (connection
) {
274 var buffer
= stringToArrayBuffer("o-report");
275 chrome
.hid
.send(connection
, 0, buffer
, function () {
276 chrome
.test
.assertLastError("Transfer failed.");
277 chrome
.hid
.disconnect(connection
);
278 chrome
.test
.succeed("Caught invalid report ID.");
283 function testSendWithUnexpectedReportId() {
284 openDeviceWithoutReportId(function (connection
) {
285 var buffer
= stringToArrayBuffer("o-report");
286 chrome
.hid
.send(connection
, 1, buffer
, function () {
287 chrome
.test
.assertLastError("Transfer failed.");
288 chrome
.hid
.disconnect(connection
);
289 chrome
.test
.succeed("Caught unexpected report ID.");
294 function testReceiveFeatureReportWithInvalidConnectionId() {
295 chrome
.hid
.receiveFeatureReport(kInvalidConnectionId
, 0, function (data
) {
296 chrome
.test
.assertLastError("Connection not established.");
297 chrome
.test
.succeed("Rejected invalid connection ID.");
301 function testReceiveFeatureReportWithReportId() {
302 openDeviceWithReportId(function (connection
) {
303 chrome
.hid
.receiveFeatureReport(connection
, 1, function (data
) {
304 chrome
.test
.assertNoLastError();
305 var expected
= "\1This is a HID feature report.";
306 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
307 chrome
.test
.succeed("Received feature report.");
312 function testReceiveFeatureReportWithoutReportId() {
313 openDeviceWithoutReportId(function (connection
) {
314 chrome
.hid
.receiveFeatureReport(connection
, 0, function (data
) {
315 chrome
.test
.assertNoLastError();
316 var expected
= "This is a HID feature report.";
317 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
318 chrome
.test
.succeed("Received feature report.");
323 function testReceiveFeatureReportWithInvalidReportId() {
324 openDeviceWithReportId(function (connection
) {
325 chrome
.hid
.receiveFeatureReport(connection
, 0, function (data
) {
326 chrome
.test
.assertLastError("Transfer failed.");
327 chrome
.test
.succeed("Caught invalid report ID.");
332 function testReceiveFeatureReportWithUnexpectedReportId() {
333 openDeviceWithoutReportId(function (connection
) {
334 chrome
.hid
.receiveFeatureReport(connection
, 1, function (data
) {
335 chrome
.test
.assertLastError("Transfer failed.");
336 chrome
.test
.succeed("Caught unexpected report ID.");
341 function testSendFeatureReportWithInvalidConnectionId() {
342 var buffer
= new ArrayBuffer();
343 chrome
.hid
.sendFeatureReport(kInvalidConnectionId
, 0, buffer
, function () {
344 chrome
.test
.assertLastError("Connection not established.");
345 chrome
.test
.succeed("Rejected invalid connection ID.");
349 function testSendFeatureReportWithReportId() {
350 openDeviceWithReportId(function (connection
) {
352 stringToArrayBuffer("The app is setting this HID feature report.");
353 chrome
.hid
.sendFeatureReport(connection
, 1, buffer
, function () {
354 chrome
.test
.assertNoLastError();
355 chrome
.hid
.disconnect(connection
);
356 chrome
.test
.succeed("Send successful.");
361 function testSendFeatureReportWithoutReportId() {
362 openDeviceWithoutReportId(function (connection
) {
364 stringToArrayBuffer("The app is setting this HID feature report.");
365 chrome
.hid
.sendFeatureReport(connection
, 0, buffer
, function () {
366 chrome
.test
.assertNoLastError();
367 chrome
.hid
.disconnect(connection
);
368 chrome
.test
.succeed("Send successful.");
373 function testSendFeatureReportWithInvalidReportId() {
374 openDeviceWithReportId(function (connection
) {
376 stringToArrayBuffer("The app is setting this HID feature report.");
377 chrome
.hid
.sendFeatureReport(connection
, 0, buffer
, function () {
378 chrome
.test
.assertLastError("Transfer failed.");
379 chrome
.hid
.disconnect(connection
);
380 chrome
.test
.succeed("Caught invalid report ID.");
385 function testSendFeatureReportWithUnexpectedReportId() {
386 openDeviceWithoutReportId(function (connection
) {
388 stringToArrayBuffer("The app is setting this HID feature report.");
389 chrome
.hid
.sendFeatureReport(connection
, 1, buffer
, function () {
390 chrome
.test
.assertLastError("Transfer failed.");
391 chrome
.hid
.disconnect(connection
);
392 chrome
.test
.succeed("Caught unexpected report ID.");
397 chrome
.test
.runTests([
398 testGetDevicesWithNoOptions
,
399 testGetDevicesWithLegacyVidAndPid
,
400 testGetDevicesWithNoFilters
,
401 testGetDevicesWithVidPidFilter
,
402 testGetDevicesWithUsageFilter
,
403 testGetDevicesWithUnauthorizedDevice
,
405 testConnectWithInvalidDeviceId
,
406 testConnectAndDisconnect
,
407 testDisconnectWithInvalidConnectionId
,
408 testReceiveWithInvalidConnectionId
,
409 testReceiveWithReportId
,
410 testReceiveWithoutReportId
,
411 testSendWithInvalidConnectionId
,
412 testSendOversizeReport
,
413 testSendWithReportId
,
414 testSendWithoutReportId
,
415 testSendWithInvalidReportId
,
416 testSendWithUnexpectedReportId
,
417 testReceiveFeatureReportWithInvalidConnectionId
,
418 testReceiveFeatureReportWithReportId
,
419 testReceiveFeatureReportWithoutReportId
,
420 testReceiveFeatureReportWithInvalidReportId
,
421 testReceiveFeatureReportWithUnexpectedReportId
,
422 testSendFeatureReportWithInvalidConnectionId
,
423 testSendFeatureReportWithReportId
,
424 testSendFeatureReportWithoutReportId
,
425 testSendFeatureReportWithInvalidReportId
,
426 testSendFeatureReportWithUnexpectedReportId
,