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