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.
6 * Custom bindings for the Serial API.
8 * The bindings are implemented by asynchronously delegating to the
9 * serial_service module. The functions that apply to a particular connection
10 * are delegated to the appropriate method on the Connection object specified by
14 var binding
= require('binding').Binding
.create('serial');
15 var context
= requireNative('v8_context');
16 var eventBindings
= require('event_bindings');
17 var utils
= require('utils');
19 var serialServicePromise = function() {
20 // getBackgroundPage is not available in unit tests so fall back to the
21 // current page's serial_service module.
22 if (!chrome
.runtime
.getBackgroundPage
)
23 return requireAsync('serial_service');
25 // Load the serial_service module from the background page if one exists. This
26 // is necessary for serial connections created in one window to be usable
27 // after that window is closed. This is necessary because the Mojo async
28 // waiter only functions while the v8 context remains.
29 return utils
.promise(chrome
.runtime
.getBackgroundPage
).then(function(bgPage
) {
30 return context
.GetModuleSystem(bgPage
).requireAsync('serial_service');
32 return requireAsync('serial_service');
36 function forwardToConnection(methodName
) {
37 return function(connectionId
) {
38 var args
= $Array
.slice(arguments
, 1);
39 return serialServicePromise
.then(function(serialService
) {
40 return serialService
.getConnection(connectionId
);
41 }).then(function(connection
) {
42 return $Function
.apply(connection
[methodName
], connection
, args
);
47 function addEventListeners(connection
, id
) {
48 connection
.onData = function(data
) {
49 eventBindings
.dispatchEvent(
50 'serial.onReceive', [{connectionId
: id
, data
: data
}]);
52 connection
.onError = function(error
) {
53 eventBindings
.dispatchEvent(
54 'serial.onReceiveError', [{connectionId
: id
, error
: error
}]);
58 serialServicePromise
.then(function(serialService
) {
59 return serialService
.getConnections().then(function(connections
) {
60 for (var entry
of connections
) {
61 var connection
= entry
[1];
62 addEventListeners(connection
, entry
[0]);
63 connection
.resumeReceives();
68 binding
.registerCustomHook(function(bindingsAPI
) {
69 var apiFunctions
= bindingsAPI
.apiFunctions
;
70 apiFunctions
.setHandleRequestWithPromise('getDevices', function() {
71 return serialServicePromise
.then(function(serialService
) {
72 return serialService
.getDevices();
76 apiFunctions
.setHandleRequestWithPromise('connect', function(path
, options
) {
77 return serialServicePromise
.then(function(serialService
) {
78 return serialService
.createConnection(path
, options
);
79 }).then(function(result
) {
80 addEventListeners(result
.connection
, result
.info
.connectionId
);
82 }).catch (function(e
) {
83 throw new Error('Failed to connect to the port.');
87 apiFunctions
.setHandleRequestWithPromise(
88 'disconnect', forwardToConnection('close'));
89 apiFunctions
.setHandleRequestWithPromise(
90 'getInfo', forwardToConnection('getInfo'));
91 apiFunctions
.setHandleRequestWithPromise(
92 'update', forwardToConnection('setOptions'));
93 apiFunctions
.setHandleRequestWithPromise(
94 'getControlSignals', forwardToConnection('getControlSignals'));
95 apiFunctions
.setHandleRequestWithPromise(
96 'setControlSignals', forwardToConnection('setControlSignals'));
97 apiFunctions
.setHandleRequestWithPromise(
98 'flush', forwardToConnection('flush'));
99 apiFunctions
.setHandleRequestWithPromise(
100 'setPaused', forwardToConnection('setPaused'));
101 apiFunctions
.setHandleRequestWithPromise(
102 'send', forwardToConnection('send'));
104 apiFunctions
.setHandleRequestWithPromise('getConnections', function() {
105 return serialServicePromise
.then(function(serialService
) {
106 return serialService
.getConnections();
107 }).then(function(connections
) {
109 for (var connection
of connections
.values()) {
110 promises
.push(connection
.getInfo());
112 return Promise
.all(promises
);
117 exports
.binding
= binding
.generate();