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(1, deviceInfo
.collections
.length
);
143 chrome
.test
.assertEq(0xFF00, deviceInfo
.collections
[0].usagePage
);
144 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].usage
);
145 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].reportIds
.length
);
146 assertArrayBufferEqualsListOfBytes(kReportDescriptor
,
147 deviceInfo
.reportDescriptor
);
148 if (--expectedDevices
== 0) {
149 chrome
.test
.succeed();
153 getDevice(true, function (deviceInfo
) {
154 chrome
.test
.assertEq(0x18D1, deviceInfo
.vendorId
);
155 chrome
.test
.assertEq(0x58F0, deviceInfo
.productId
);
156 chrome
.test
.assertEq(1, deviceInfo
.collections
.length
);
157 chrome
.test
.assertEq(0xFF01, deviceInfo
.collections
[0].usagePage
);
158 chrome
.test
.assertEq(0, deviceInfo
.collections
[0].usage
);
159 chrome
.test
.assertEq(1, deviceInfo
.collections
[0].reportIds
.length
);
160 chrome
.test
.assertEq(1, deviceInfo
.collections
[0].reportIds
[0]);
161 assertArrayBufferEqualsListOfBytes(kReportDescriptorWithIDs
,
162 deviceInfo
.reportDescriptor
);
163 if (--expectedDevices
== 0) {
164 chrome
.test
.succeed();
169 function testConnectWithInvalidDeviceId() {
170 chrome
.hid
.connect(kInvalidDeviceId
, function (connection
) {
171 chrome
.test
.assertLastError("Invalid HID device ID.");
172 chrome
.test
.succeed("Rejected invalid device ID.");
176 function testConnectAndDisconnect() {
177 chrome
.hid
.getDevices({ 'filters': [
178 { 'vendorId': 0x18D1, 'productId': 0x58F0 }
179 ] }, function (devices
) {
180 chrome
.test
.assertNoLastError();
181 chrome
.test
.assertTrue(devices
.length
>= 1, "Expected connectable device.");
182 chrome
.hid
.connect(devices
[0].deviceId
, function (connection
) {
183 chrome
.test
.assertNoLastError();
184 chrome
.hid
.disconnect(connection
.connectionId
, function () {
185 chrome
.test
.assertNoLastError();
186 chrome
.test
.succeed("Opened and closed device.");
192 function testDisconnectWithInvalidConnectionId() {
193 chrome
.hid
.disconnect(kInvalidConnectionId
, function () {
194 chrome
.test
.assertLastError("Connection not established.");
195 chrome
.test
.succeed("Rejected invalid connection ID.");
199 function testReceiveWithInvalidConnectionId() {
200 chrome
.hid
.receive(kInvalidConnectionId
, function (reportId
, data
) {
201 chrome
.test
.assertLastError("Connection not established.");
202 chrome
.test
.succeed("Rejected invalid connection ID.");
206 function testReceiveWithReportId() {
207 openDeviceWithReportId(function (connection
) {
208 chrome
.hid
.receive(connection
, function (reportId
, data
) {
209 chrome
.test
.assertEq(1, reportId
, "Expected report_id == 1.");
210 var expected
= "This is a HID input report.";
211 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
212 chrome
.test
.succeed("Receive successful.");
217 function testReceiveWithoutReportId() {
218 openDeviceWithoutReportId(function (connection
) {
219 chrome
.hid
.receive(connection
, function (reportId
, data
) {
220 chrome
.test
.assertNoLastError();
221 chrome
.test
.assertEq(0, reportId
, "Expected report_id == 0.");
222 var expected
= "This is a HID input report.";
223 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
224 chrome
.test
.succeed("Receive successful.");
229 function testSendWithInvalidConnectionId() {
230 var buffer
= new ArrayBuffer();
231 chrome
.hid
.send(kInvalidConnectionId
, 0, buffer
, function () {
232 chrome
.test
.assertLastError("Connection not established.");
233 chrome
.test
.succeed("Rejected invalid connection ID.");
237 function testSendOversizeReport() {
238 openDeviceWithReportId(function (connection
) {
239 var buffer
= stringToArrayBuffer("oversize report");
240 chrome
.hid
.send(connection
, 1, buffer
, function () {
241 chrome
.test
.assertLastError("Transfer failed.");
242 chrome
.hid
.disconnect(connection
);
243 chrome
.test
.succeed("Caught oversize report.");
248 function testSendWithReportId() {
249 openDeviceWithReportId(function (connection
) {
250 var buffer
= stringToArrayBuffer("o-report");
251 chrome
.hid
.send(connection
, 1, buffer
, function () {
252 chrome
.test
.assertNoLastError();
253 chrome
.hid
.disconnect(connection
);
254 chrome
.test
.succeed("Send successful.");
259 function testSendWithoutReportId() {
260 openDeviceWithoutReportId(function (connection
) {
261 var buffer
= stringToArrayBuffer("o-report");
262 chrome
.hid
.send(connection
, 0, buffer
, function () {
263 chrome
.test
.assertNoLastError();
264 chrome
.hid
.disconnect(connection
);
265 chrome
.test
.succeed("Send successful.");
270 function testSendWithInvalidReportId() {
271 openDeviceWithReportId(function (connection
) {
272 var buffer
= stringToArrayBuffer("o-report");
273 chrome
.hid
.send(connection
, 0, buffer
, function () {
274 chrome
.test
.assertLastError("Transfer failed.");
275 chrome
.hid
.disconnect(connection
);
276 chrome
.test
.succeed("Caught invalid report ID.");
281 function testSendWithUnexpectedReportId() {
282 openDeviceWithoutReportId(function (connection
) {
283 var buffer
= stringToArrayBuffer("o-report");
284 chrome
.hid
.send(connection
, 1, buffer
, function () {
285 chrome
.test
.assertLastError("Transfer failed.");
286 chrome
.hid
.disconnect(connection
);
287 chrome
.test
.succeed("Caught unexpected report ID.");
292 function testReceiveFeatureReportWithInvalidConnectionId() {
293 chrome
.hid
.receiveFeatureReport(kInvalidConnectionId
, 0, function (data
) {
294 chrome
.test
.assertLastError("Connection not established.");
295 chrome
.test
.succeed("Rejected invalid connection ID.");
299 function testReceiveFeatureReportWithReportId() {
300 openDeviceWithReportId(function (connection
) {
301 chrome
.hid
.receiveFeatureReport(connection
, 1, function (data
) {
302 chrome
.test
.assertNoLastError();
303 var expected
= "\1This is a HID feature report.";
304 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
305 chrome
.test
.succeed("Received feature report.");
310 function testReceiveFeatureReportWithoutReportId() {
311 openDeviceWithoutReportId(function (connection
) {
312 chrome
.hid
.receiveFeatureReport(connection
, 0, function (data
) {
313 chrome
.test
.assertNoLastError();
314 var expected
= "This is a HID feature report.";
315 chrome
.test
.assertEq(expected
, arrayBufferToString(data
));
316 chrome
.test
.succeed("Received feature report.");
321 function testReceiveFeatureReportWithInvalidReportId() {
322 openDeviceWithReportId(function (connection
) {
323 chrome
.hid
.receiveFeatureReport(connection
, 0, function (data
) {
324 chrome
.test
.assertLastError("Transfer failed.");
325 chrome
.test
.succeed("Caught invalid report ID.");
330 function testReceiveFeatureReportWithUnexpectedReportId() {
331 openDeviceWithoutReportId(function (connection
) {
332 chrome
.hid
.receiveFeatureReport(connection
, 1, function (data
) {
333 chrome
.test
.assertLastError("Transfer failed.");
334 chrome
.test
.succeed("Caught unexpected report ID.");
339 function testSendFeatureReportWithInvalidConnectionId() {
340 var buffer
= new ArrayBuffer();
341 chrome
.hid
.sendFeatureReport(kInvalidConnectionId
, 0, buffer
, function () {
342 chrome
.test
.assertLastError("Connection not established.");
343 chrome
.test
.succeed("Rejected invalid connection ID.");
347 function testSendFeatureReportWithReportId() {
348 openDeviceWithReportId(function (connection
) {
350 stringToArrayBuffer("The app is setting this HID feature report.");
351 chrome
.hid
.sendFeatureReport(connection
, 1, buffer
, function () {
352 chrome
.test
.assertNoLastError();
353 chrome
.hid
.disconnect(connection
);
354 chrome
.test
.succeed("Send successful.");
359 function testSendFeatureReportWithoutReportId() {
360 openDeviceWithoutReportId(function (connection
) {
362 stringToArrayBuffer("The app is setting this HID feature report.");
363 chrome
.hid
.sendFeatureReport(connection
, 0, buffer
, function () {
364 chrome
.test
.assertNoLastError();
365 chrome
.hid
.disconnect(connection
);
366 chrome
.test
.succeed("Send successful.");
371 function testSendFeatureReportWithInvalidReportId() {
372 openDeviceWithReportId(function (connection
) {
374 stringToArrayBuffer("The app is setting this HID feature report.");
375 chrome
.hid
.sendFeatureReport(connection
, 0, buffer
, function () {
376 chrome
.test
.assertLastError("Transfer failed.");
377 chrome
.hid
.disconnect(connection
);
378 chrome
.test
.succeed("Caught invalid report ID.");
383 function testSendFeatureReportWithUnexpectedReportId() {
384 openDeviceWithoutReportId(function (connection
) {
386 stringToArrayBuffer("The app is setting this HID feature report.");
387 chrome
.hid
.sendFeatureReport(connection
, 1, buffer
, function () {
388 chrome
.test
.assertLastError("Transfer failed.");
389 chrome
.hid
.disconnect(connection
);
390 chrome
.test
.succeed("Caught unexpected report ID.");
395 chrome
.test
.runTests([
396 testGetDevicesWithNoOptions
,
397 testGetDevicesWithLegacyVidAndPid
,
398 testGetDevicesWithNoFilters
,
399 testGetDevicesWithVidPidFilter
,
400 testGetDevicesWithUsageFilter
,
401 testGetDevicesWithUnauthorizedDevice
,
403 testConnectWithInvalidDeviceId
,
404 testConnectAndDisconnect
,
405 testDisconnectWithInvalidConnectionId
,
406 testReceiveWithInvalidConnectionId
,
407 testReceiveWithReportId
,
408 testReceiveWithoutReportId
,
409 testSendWithInvalidConnectionId
,
410 testSendOversizeReport
,
411 testSendWithReportId
,
412 testSendWithoutReportId
,
413 testSendWithInvalidReportId
,
414 testSendWithUnexpectedReportId
,
415 testReceiveFeatureReportWithInvalidConnectionId
,
416 testReceiveFeatureReportWithReportId
,
417 testReceiveFeatureReportWithoutReportId
,
418 testReceiveFeatureReportWithInvalidReportId
,
419 testReceiveFeatureReportWithUnexpectedReportId
,
420 testSendFeatureReportWithInvalidConnectionId
,
421 testSendFeatureReportWithReportId
,
422 testSendFeatureReportWithoutReportId
,
423 testSendFeatureReportWithInvalidReportId
,
424 testSendFeatureReportWithUnexpectedReportId
,