OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 define('serial_service', [ | 5 define('serial_service', [ |
6 'content/public/renderer/service_provider', | 6 'content/public/renderer/service_provider', |
7 'device/serial/serial.mojom', | 7 'device/serial/serial.mojom', |
8 'mojo/public/js/bindings/core', | |
8 'mojo/public/js/bindings/router', | 9 'mojo/public/js/bindings/router', |
9 ], function(serviceProvider, serialMojom, routerModule) { | 10 ], function(serviceProvider, serialMojom, core, routerModule) { |
10 | 11 |
11 function defineService(proxy, handle) { | 12 function defineService(proxy, handle) { |
12 if (!handle) | 13 if (!handle) |
13 handle = serviceProvider.connectToService(proxy.NAME_); | 14 handle = serviceProvider.connectToService(proxy.NAME_); |
14 var router = new routerModule.Router(handle); | 15 var router = new routerModule.Router(handle); |
15 var service = new proxy(router); | 16 var service = new proxy(router); |
16 return { | 17 return { |
17 service: service, | 18 service: service, |
18 router: router, | 19 router: router, |
19 }; | 20 }; |
20 } | 21 } |
21 | 22 |
22 var service = defineService(serialMojom.SerialServiceProxy).service; | 23 var service = defineService(serialMojom.SerialServiceProxy).service; |
23 | 24 |
24 function getDevices() { | 25 function getDevices() { |
25 return service.getDevices().then(function(response) { | 26 return service.getDevices().then(function(response) { |
26 return $Array.map(response.devices, function(device) { | 27 return $Array.map(response.devices, function(device) { |
27 var result = {path: device.path || ''}; | 28 var result = {path: device.path || ''}; |
28 if (device.has_vendor_id) | 29 if (device.has_vendor_id) |
29 result.vendorId = device.vendor_id; | 30 result.vendorId = device.vendor_id; |
30 if (device.has_product_id) | 31 if (device.has_product_id) |
31 result.productId = device.product_id; | 32 result.productId = device.product_id; |
32 if (device.display_name) | 33 if (device.display_name) |
33 result.displayName = device.display_name; | 34 result.displayName = device.display_name; |
34 return result; | 35 return result; |
35 }); | 36 }); |
36 }); | 37 }); |
37 } | 38 } |
38 | 39 |
40 var DEFAULT_CLIENT_OPTIONS = { | |
41 persistent: false, | |
42 name: '', | |
43 receiveTimeout: 0, | |
44 sendTimeout: 0, | |
45 bufferSize: 4096, | |
46 }; | |
47 | |
48 var DATA_BITS_TO_MOJO = { | |
49 undefined: serialMojom.DataBits.NONE, | |
50 'seven': serialMojom.DataBits.SEVEN, | |
51 'eight': serialMojom.DataBits.EIGHT, | |
52 }; | |
53 var STOP_BITS_TO_MOJO = { | |
54 undefined: serialMojom.StopBits.NONE, | |
55 'one': serialMojom.StopBits.ONE, | |
56 'two': serialMojom.StopBits.TWO, | |
57 }; | |
58 var PARITY_BIT_TO_MOJO = { | |
59 undefined: serialMojom.ParityBit.NONE, | |
60 'no': serialMojom.ParityBit.NO, | |
61 'odd': serialMojom.ParityBit.ODD, | |
62 'even': serialMojom.ParityBit.EVEN, | |
63 }; | |
64 | |
65 function invertMap(input) { | |
66 var output = {}; | |
67 for (var key in input) { | |
68 if (key == 'undefined') | |
69 output[input[key]] = undefined; | |
70 else | |
71 output[input[key]] = key; | |
72 } | |
73 return output; | |
74 } | |
75 var DATA_BITS_FROM_MOJO = invertMap(DATA_BITS_TO_MOJO); | |
76 var STOP_BITS_FROM_MOJO = invertMap(STOP_BITS_TO_MOJO); | |
77 var PARITY_BIT_FROM_MOJO = invertMap(PARITY_BIT_TO_MOJO); | |
78 | |
Ken Rockot(use gerrit already)
2014/07/31 16:28:33
I'm guessing this conversion stuff is some of the
| |
79 function getServiceOptions(options) { | |
80 var out = {}; | |
81 if (options.dataBits) | |
82 out.data_bits = DATA_BITS_TO_MOJO[options.dataBits]; | |
83 if (options.stopBits) | |
84 out.stop_bits = STOP_BITS_TO_MOJO[options.stopBits]; | |
85 if (options.parityBit) | |
86 out.parity_bit = PARITY_BIT_TO_MOJO[options.parityBit]; | |
87 if ('ctsFlowControl' in options) { | |
88 out.has_cts_flow_control = true; | |
89 out.cts_flow_control = options.ctsFlowControl; | |
90 } | |
91 if ('bitrate' in options) | |
92 out.bitrate = options.bitrate; | |
93 return out; | |
94 } | |
95 | |
96 function convertServiceInfo(result) { | |
97 if (!result.info) | |
98 throw new Error('Failed to get ConnectionInfo.'); | |
99 return { | |
100 ctsFlowControl: !!result.info.cts_flow_control, | |
101 bitrate: result.info.bitrate || undefined, | |
102 dataBits: DATA_BITS_FROM_MOJO[result.info.data_bits], | |
103 stopBits: STOP_BITS_FROM_MOJO[result.info.stop_bits], | |
104 parityBit: PARITY_BIT_FROM_MOJO[result.info.parity_bit], | |
105 }; | |
106 } | |
107 | |
108 function Connection(remoteConnection, router, id, options) { | |
109 this.remoteConnection_ = remoteConnection; | |
110 this.router_ = router; | |
111 this.id_ = id; | |
112 getConnections().then(function(connections) { | |
113 connections[this.id_] = this; | |
114 }.bind(this)); | |
115 this.paused_ = false; | |
116 this.options_ = {}; | |
117 for (var key in DEFAULT_CLIENT_OPTIONS) { | |
118 this.options_[key] = DEFAULT_CLIENT_OPTIONS[key]; | |
119 } | |
120 this.setClientOptions_(options); | |
121 } | |
122 | |
123 Connection.create = function(path, options) { | |
124 options = options || {}; | |
125 var serviceOptions = getServiceOptions(options); | |
126 var pipe = core.createMessagePipe(); | |
127 service.connect(path, serviceOptions, pipe.handle0); | |
128 var result = defineService(serialMojom.ConnectionProxy, pipe.handle1); | |
129 return result.service.getInfo().then(convertServiceInfo).then( | |
130 function(info) { | |
131 return Promise.all([info, allocateConnectionId()]); | |
132 }).catch(function(e) { | |
133 result.router.close(); | |
134 throw e; | |
135 }).then(function(results) { | |
136 var info = results[0]; | |
137 var id = results[1]; | |
138 var serialConnectionClient = new Connection( | |
139 result.service, result.router, id, options); | |
140 var clientInfo = serialConnectionClient.getClientInfo_(); | |
141 for (var key in clientInfo) { | |
142 info[key] = clientInfo[key]; | |
143 } | |
144 return { | |
145 connection: serialConnectionClient, | |
146 info: info, | |
147 }; | |
148 }); | |
149 }; | |
150 | |
151 Connection.prototype.close = function() { | |
152 this.router_.close(); | |
153 return getConnections().then(function(connections) { | |
154 delete connections[this.id_] | |
155 return true; | |
156 }.bind(this)); | |
157 }; | |
158 | |
159 Connection.prototype.getClientInfo_ = function() { | |
160 var info = { | |
161 connectionId: this.id_, | |
162 paused: this.paused_, | |
163 } | |
164 for (var key in this.options_) { | |
165 info[key] = this.options_[key]; | |
166 } | |
167 return info; | |
168 }; | |
169 | |
170 Connection.prototype.getInfo = function() { | |
171 var info = this.getClientInfo_(); | |
172 return this.remoteConnection_.getInfo().then(convertServiceInfo).then( | |
173 function(result) { | |
174 for (var key in result) { | |
175 info[key] = result[key]; | |
176 } | |
177 return info; | |
178 }).catch(function() { | |
179 return info; | |
180 }); | |
181 } | |
182 | |
183 Connection.prototype.setClientOptions_ = function(options) { | |
184 if ('name' in options) | |
185 this.options_.name = options.name; | |
186 if ('receiveTimeout' in options) | |
187 this.options_.receiveTimeout = options.receiveTimeout; | |
188 if ('sendTimeout' in options) | |
189 this.options_.sendTimeout = options.sendTimeout; | |
190 if ('bufferSize' in options) | |
191 this.options_.bufferSize = options.bufferSize; | |
192 }; | |
193 | |
194 Connection.prototype.setOptions = function(options) { | |
195 this.setClientOptions_(options); | |
196 var serviceOptions = getServiceOptions(options); | |
197 if ($Object.keys(serviceOptions).length == 0) | |
198 return true; | |
199 return this.remoteConnection_.setOptions(serviceOptions).then( | |
200 function(result) { | |
201 return !!result.success; | |
202 }).catch(function() { | |
203 return false; | |
204 }); | |
205 }; | |
206 | |
207 Connection.prototype.getControlSignals = function() { | |
208 return this.remoteConnection_.getControlSignals().then(function(result) { | |
209 if (!result.signals) | |
210 throw new Error('Failed to get control signals.'); | |
211 var signals = result.signals; | |
212 return { | |
213 dcd: !!signals.dcd, | |
214 cts: !!signals.cts, | |
215 ri: !!signals.ri, | |
216 dsr: !!signals.dsr, | |
217 }; | |
218 }); | |
219 }; | |
220 | |
221 Connection.prototype.setControlSignals = function(signals) { | |
222 var controlSignals = {}; | |
223 if ('dtr' in signals) { | |
224 controlSignals.has_dtr = true; | |
225 controlSignals.dtr = signals.dtr; | |
226 } | |
227 if ('rts' in signals) { | |
228 controlSignals.has_rts = true; | |
229 controlSignals.rts = signals.rts; | |
230 } | |
231 return this.remoteConnection_.setControlSignals(controlSignals).then( | |
232 function(result) { | |
233 return !!result.success; | |
234 }); | |
235 }; | |
236 | |
237 Connection.prototype.flush = function() { | |
238 return this.remoteConnection_.flush().then(function(result) { | |
239 return !!result.success; | |
240 }); | |
241 }; | |
242 | |
243 Connection.prototype.setPaused = function(paused) { | |
244 this.paused_ = paused; | |
245 }; | |
246 | |
247 var connections_ = {}; | |
248 var nextConnectionId_ = 0; | |
249 | |
250 // Wrap all access to |connections_| through getConnections to avoid adding | |
251 // any synchronous dependencies on it. This will likely be important when | |
252 // supporting persistent connections by stashing them. | |
253 function getConnections() { | |
254 return Promise.resolve(connections_); | |
255 } | |
256 | |
257 function getConnection(id) { | |
258 return getConnections().then(function(connections) { | |
259 if (!connections[id]) | |
260 throw new Error ('Serial connection not found.'); | |
261 return connections[id]; | |
262 }); | |
263 } | |
264 | |
265 function forwardToConnection(methodName) { | |
266 return function(connectionId) { | |
267 var args = $Array.slice(arguments, 1); | |
268 return getConnection(connectionId).then(function(connection) { | |
269 return $Function.apply(connection[methodName], connection, args); | |
270 }); | |
271 } | |
272 } | |
273 | |
274 function allocateConnectionId() { | |
275 return Promise.resolve(nextConnectionId_++); | |
276 } | |
277 | |
39 return { | 278 return { |
40 getDevices: getDevices, | 279 getDevices: getDevices, |
280 createConnection: Connection.create, | |
281 getConnection: getConnection, | |
282 getConnections: getConnections, | |
41 }; | 283 }; |
42 }); | 284 }); |
OLD | NEW |