Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: extensions/renderer/resources/serial_service.js

Issue 423403002: Implement more of chrome.serial on the Mojo SerialConnection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@js-serial
Patch Set: add missing semicolons Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
raymes 2014/08/14 02:58:05 Please add a comment to this file explaining what
Sam McNally 2014/08/14 04:33:51 Done.
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
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()]);
raymes 2014/08/01 02:16:28 the indentation here looks odd but I see it throug
Sam McNally 2014/08/01 06:39:24 It's to maintain 2 space indent per scope.
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 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698