Chromium Code Reviews| Index: extensions/renderer/resources/serial_service.js |
| diff --git a/extensions/renderer/resources/serial_service.js b/extensions/renderer/resources/serial_service.js |
| index 92e17d06ec2b8dfb8936021ec29f1fbf6ddf7abb..68f55d7a3b174bec4626b84dab9bbb2f7f498676 100644 |
| --- a/extensions/renderer/resources/serial_service.js |
| +++ b/extensions/renderer/resources/serial_service.js |
| @@ -5,8 +5,9 @@ |
| define('serial_service', [ |
| 'content/public/renderer/service_provider', |
| 'device/serial/serial.mojom', |
| + 'mojo/public/js/bindings/core', |
| 'mojo/public/js/bindings/router', |
| -], function(serviceProvider, serialMojom, routerModule) { |
| +], function(serviceProvider, serialMojom, core, routerModule) { |
| function defineService(proxy, handle) { |
| if (!handle) |
| @@ -36,7 +37,248 @@ define('serial_service', [ |
| }); |
| } |
| + var DEFAULT_CLIENT_OPTIONS = { |
| + persistent: false, |
| + name: '', |
| + receiveTimeout: 0, |
| + sendTimeout: 0, |
| + bufferSize: 4096, |
| + }; |
| + |
| + var DATA_BITS_TO_MOJO = { |
| + undefined: serialMojom.DataBits.NONE, |
| + 'seven': serialMojom.DataBits.SEVEN, |
| + 'eight': serialMojom.DataBits.EIGHT, |
| + }; |
| + var STOP_BITS_TO_MOJO = { |
| + undefined: serialMojom.StopBits.NONE, |
| + 'one': serialMojom.StopBits.ONE, |
| + 'two': serialMojom.StopBits.TWO, |
| + }; |
| + var PARITY_BIT_TO_MOJO = { |
| + undefined: serialMojom.ParityBit.NONE, |
| + 'no': serialMojom.ParityBit.NO, |
| + 'odd': serialMojom.ParityBit.ODD, |
| + 'even': serialMojom.ParityBit.EVEN, |
| + }; |
| + |
| + function invertMap(input) { |
| + var output = {}; |
| + for (var key in input) { |
| + if (key == 'undefined') |
| + output[input[key]] = undefined; |
| + else |
| + output[input[key]] = key; |
| + } |
| + return output; |
| + } |
| + var DATA_BITS_FROM_MOJO = invertMap(DATA_BITS_TO_MOJO); |
| + var STOP_BITS_FROM_MOJO = invertMap(STOP_BITS_TO_MOJO); |
| + var PARITY_BIT_FROM_MOJO = invertMap(PARITY_BIT_TO_MOJO); |
| + |
|
Ken Rockot(use gerrit already)
2014/07/31 16:28:33
I'm guessing this conversion stuff is some of the
|
| + function getServiceOptions(options) { |
| + var out = {}; |
| + if (options.dataBits) |
| + out.data_bits = DATA_BITS_TO_MOJO[options.dataBits]; |
| + if (options.stopBits) |
| + out.stop_bits = STOP_BITS_TO_MOJO[options.stopBits]; |
| + if (options.parityBit) |
| + out.parity_bit = PARITY_BIT_TO_MOJO[options.parityBit]; |
| + if ('ctsFlowControl' in options) { |
| + out.has_cts_flow_control = true; |
| + out.cts_flow_control = options.ctsFlowControl; |
| + } |
| + if ('bitrate' in options) |
| + out.bitrate = options.bitrate; |
| + return out; |
| + } |
| + |
| + function convertServiceInfo(result) { |
| + if (!result.info) |
| + throw new Error('Failed to get ConnectionInfo.'); |
| + return { |
| + ctsFlowControl: !!result.info.cts_flow_control, |
| + bitrate: result.info.bitrate || undefined, |
| + dataBits: DATA_BITS_FROM_MOJO[result.info.data_bits], |
| + stopBits: STOP_BITS_FROM_MOJO[result.info.stop_bits], |
| + parityBit: PARITY_BIT_FROM_MOJO[result.info.parity_bit], |
| + }; |
| + } |
| + |
| + function Connection(remoteConnection, router, id, options) { |
| + this.remoteConnection_ = remoteConnection; |
| + this.router_ = router; |
| + this.id_ = id; |
| + getConnections().then(function(connections) { |
| + connections[this.id_] = this; |
| + }.bind(this)); |
| + this.paused_ = false; |
| + this.options_ = {}; |
| + for (var key in DEFAULT_CLIENT_OPTIONS) { |
| + this.options_[key] = DEFAULT_CLIENT_OPTIONS[key]; |
| + } |
| + this.setClientOptions_(options); |
| + } |
| + |
| + Connection.create = function(path, options) { |
| + options = options || {}; |
| + var serviceOptions = getServiceOptions(options); |
| + var pipe = core.createMessagePipe(); |
| + service.connect(path, serviceOptions, pipe.handle0); |
| + var result = defineService(serialMojom.ConnectionProxy, pipe.handle1); |
| + return result.service.getInfo().then(convertServiceInfo).then( |
| + function(info) { |
| + return Promise.all([info, allocateConnectionId()]); |
| + }).catch(function(e) { |
| + result.router.close(); |
| + throw e; |
| + }).then(function(results) { |
| + var info = results[0]; |
| + var id = results[1]; |
| + var serialConnectionClient = new Connection( |
| + result.service, result.router, id, options); |
| + var clientInfo = serialConnectionClient.getClientInfo_(); |
| + for (var key in clientInfo) { |
| + info[key] = clientInfo[key]; |
| + } |
| + return { |
| + connection: serialConnectionClient, |
| + info: info, |
| + }; |
| + }); |
| + }; |
| + |
| + Connection.prototype.close = function() { |
| + this.router_.close(); |
| + return getConnections().then(function(connections) { |
| + delete connections[this.id_] |
| + return true; |
| + }.bind(this)); |
| + }; |
| + |
| + Connection.prototype.getClientInfo_ = function() { |
| + var info = { |
| + connectionId: this.id_, |
| + paused: this.paused_, |
| + } |
| + for (var key in this.options_) { |
| + info[key] = this.options_[key]; |
| + } |
| + return info; |
| + }; |
| + |
| + Connection.prototype.getInfo = function() { |
| + var info = this.getClientInfo_(); |
| + return this.remoteConnection_.getInfo().then(convertServiceInfo).then( |
| + function(result) { |
| + for (var key in result) { |
| + info[key] = result[key]; |
| + } |
| + return info; |
| + }).catch(function() { |
| + return info; |
| + }); |
| + } |
| + |
| + Connection.prototype.setClientOptions_ = function(options) { |
| + if ('name' in options) |
| + this.options_.name = options.name; |
| + if ('receiveTimeout' in options) |
| + this.options_.receiveTimeout = options.receiveTimeout; |
| + if ('sendTimeout' in options) |
| + this.options_.sendTimeout = options.sendTimeout; |
| + if ('bufferSize' in options) |
| + this.options_.bufferSize = options.bufferSize; |
| + }; |
| + |
| + Connection.prototype.setOptions = function(options) { |
| + this.setClientOptions_(options); |
| + var serviceOptions = getServiceOptions(options); |
| + if ($Object.keys(serviceOptions).length == 0) |
| + return true; |
| + return this.remoteConnection_.setOptions(serviceOptions).then( |
| + function(result) { |
| + return !!result.success; |
| + }).catch(function() { |
| + return false; |
| + }); |
| + }; |
| + |
| + Connection.prototype.getControlSignals = function() { |
| + return this.remoteConnection_.getControlSignals().then(function(result) { |
| + if (!result.signals) |
| + throw new Error('Failed to get control signals.'); |
| + var signals = result.signals; |
| + return { |
| + dcd: !!signals.dcd, |
| + cts: !!signals.cts, |
| + ri: !!signals.ri, |
| + dsr: !!signals.dsr, |
| + }; |
| + }); |
| + }; |
| + |
| + Connection.prototype.setControlSignals = function(signals) { |
| + var controlSignals = {}; |
| + if ('dtr' in signals) { |
| + controlSignals.has_dtr = true; |
| + controlSignals.dtr = signals.dtr; |
| + } |
| + if ('rts' in signals) { |
| + controlSignals.has_rts = true; |
| + controlSignals.rts = signals.rts; |
| + } |
| + return this.remoteConnection_.setControlSignals(controlSignals).then( |
| + function(result) { |
| + return !!result.success; |
| + }); |
| + }; |
| + |
| + Connection.prototype.flush = function() { |
| + return this.remoteConnection_.flush().then(function(result) { |
| + return !!result.success; |
| + }); |
| + }; |
| + |
| + Connection.prototype.setPaused = function(paused) { |
| + this.paused_ = paused; |
| + }; |
| + |
| + var connections_ = {}; |
| + var nextConnectionId_ = 0; |
| + |
| + // Wrap all access to |connections_| through getConnections to avoid adding |
| + // any synchronous dependencies on it. This will likely be important when |
| + // supporting persistent connections by stashing them. |
| + function getConnections() { |
| + return Promise.resolve(connections_); |
| + } |
| + |
| + function getConnection(id) { |
| + return getConnections().then(function(connections) { |
| + if (!connections[id]) |
| + throw new Error ('Serial connection not found.'); |
| + return connections[id]; |
| + }); |
| + } |
| + |
| + function forwardToConnection(methodName) { |
| + return function(connectionId) { |
| + var args = $Array.slice(arguments, 1); |
| + return getConnection(connectionId).then(function(connection) { |
| + return $Function.apply(connection[methodName], connection, args); |
| + }); |
| + } |
| + } |
| + |
| + function allocateConnectionId() { |
| + return Promise.resolve(nextConnectionId_++); |
| + } |
| + |
| return { |
| getDevices: getDevices, |
| + createConnection: Connection.create, |
| + getConnection: getConnection, |
| + getConnections: getConnections, |
| }; |
| }); |