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

Unified 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 missed GN change 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/resources/serial_custom_bindings.js ('k') | extensions/test/data/serial_unittest.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..00d137b1ea1cac14226803db8fd829650b2c83c7 100644
--- a/extensions/renderer/resources/serial_service.js
+++ b/extensions/renderer/resources/serial_service.js
@@ -5,21 +5,20 @@
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) {
+ /**
+ * A Javascript client for the serial service and connection Mojo services.
+ *
+ * This provides a thick client around the Mojo services, exposing a JS-style
+ * interface to serial connections and information about serial devices. This
+ * converts parameters and result between the Apps serial API types and the
+ * Mojo types.
+ */
- function defineService(proxy, handle) {
- if (!handle)
- handle = serviceProvider.connectToService(proxy.NAME_);
- var router = new routerModule.Router(handle);
- var service = new proxy(router);
- return {
- service: service,
- router: router,
- };
- }
-
- var service = defineService(serialMojom.SerialServiceProxy).service;
+ var service = new serialMojom.SerialServiceProxy(new routerModule.Router(
+ serviceProvider.connectToService(serialMojom.SerialServiceProxy.NAME_)));
function getDevices() {
return service.getDevices().then(function(response) {
@@ -36,7 +35,240 @@ 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);
+
+ 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 router = new routerModule.Router(pipe.handle1);
+ var connection = new serialMojom.ConnectionProxy(router);
+ return connection.getInfo().then(convertServiceInfo).then(
+ function(info) {
+ return Promise.all([info, allocateConnectionId()]);
+ }).catch(function(e) {
+ router.close();
+ throw e;
+ }).then(function(results) {
+ var info = results[0];
+ var id = results[1];
+ var serialConnectionClient = new Connection(
+ connection, 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 allocateConnectionId() {
+ return Promise.resolve(nextConnectionId_++);
+ }
+
return {
getDevices: getDevices,
+ createConnection: Connection.create,
+ getConnection: getConnection,
+ getConnections: getConnections,
};
});
« no previous file with comments | « extensions/renderer/resources/serial_custom_bindings.js ('k') | extensions/test/data/serial_unittest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698