| Index: extensions/renderer/resources/serial_service.js
|
| diff --git a/extensions/renderer/resources/serial_service.js b/extensions/renderer/resources/serial_service.js
|
| deleted file mode 100644
|
| index ea6abc407848efde2ffecbb506622314289da419..0000000000000000000000000000000000000000
|
| --- a/extensions/renderer/resources/serial_service.js
|
| +++ /dev/null
|
| @@ -1,554 +0,0 @@
|
| -// 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.
|
| -
|
| -define('serial_service', [
|
| - 'content/public/renderer/frame_interfaces',
|
| - 'data_receiver',
|
| - 'data_sender',
|
| - 'device/serial/serial.mojom',
|
| - 'device/serial/serial_serialization.mojom',
|
| - 'mojo/public/js/core',
|
| - 'mojo/public/js/router',
|
| - 'stash_client',
|
| -], function (frameInterfaces,
|
| - dataReceiver,
|
| - dataSender,
|
| - serialMojom,
|
| - serialization,
|
| - core,
|
| - routerModule,
|
| - stashClient) {
|
| - /**
|
| - * 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.
|
| - */
|
| -
|
| - var service = new serialMojom.SerialService.proxyClass(
|
| - new routerModule.Router(
|
| - frameInterfaces.getInterface(serialMojom.SerialService.name)));
|
| -
|
| - function getDevices() {
|
| - return service.getDevices().then(function(response) {
|
| - return $Array.map(response.devices, function(device) {
|
| - var result = {path: device.path};
|
| - if (device.has_vendor_id)
|
| - result.vendorId = device.vendor_id;
|
| - if (device.has_product_id)
|
| - result.productId = device.product_id;
|
| - if (device.display_name)
|
| - result.displayName = device.display_name;
|
| - return result;
|
| - });
|
| - });
|
| - }
|
| -
|
| - 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,
|
| - };
|
| - var SEND_ERROR_TO_MOJO = {
|
| - undefined: serialMojom.SendError.NONE,
|
| - 'disconnected': serialMojom.SendError.DISCONNECTED,
|
| - 'pending': serialMojom.SendError.PENDING,
|
| - 'timeout': serialMojom.SendError.TIMEOUT,
|
| - 'system_error': serialMojom.SendError.SYSTEM_ERROR,
|
| - };
|
| - var RECEIVE_ERROR_TO_MOJO = {
|
| - undefined: serialMojom.ReceiveError.NONE,
|
| - 'disconnected': serialMojom.ReceiveError.DISCONNECTED,
|
| - 'device_lost': serialMojom.ReceiveError.DEVICE_LOST,
|
| - 'timeout': serialMojom.ReceiveError.TIMEOUT,
|
| - 'break': serialMojom.ReceiveError.BREAK,
|
| - 'frame_error': serialMojom.ReceiveError.FRAME_ERROR,
|
| - 'overrun': serialMojom.ReceiveError.OVERRUN,
|
| - 'buffer_overflow': serialMojom.ReceiveError.BUFFER_OVERFLOW,
|
| - 'parity_error': serialMojom.ReceiveError.PARITY_ERROR,
|
| - 'system_error': serialMojom.ReceiveError.SYSTEM_ERROR,
|
| - };
|
| -
|
| - 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);
|
| - var SEND_ERROR_FROM_MOJO = invertMap(SEND_ERROR_TO_MOJO);
|
| - var RECEIVE_ERROR_FROM_MOJO = invertMap(RECEIVE_ERROR_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],
|
| - };
|
| - }
|
| -
|
| - // Update client-side options |clientOptions| from the user-provided
|
| - // |options|.
|
| - function updateClientOptions(clientOptions, options) {
|
| - if ('name' in options)
|
| - clientOptions.name = options.name;
|
| - if ('receiveTimeout' in options)
|
| - clientOptions.receiveTimeout = options.receiveTimeout;
|
| - if ('sendTimeout' in options)
|
| - clientOptions.sendTimeout = options.sendTimeout;
|
| - if ('bufferSize' in options)
|
| - clientOptions.bufferSize = options.bufferSize;
|
| - if ('persistent' in options)
|
| - clientOptions.persistent = options.persistent;
|
| - };
|
| -
|
| - function Connection(connection, router, receivePipe, receiveClientPipe,
|
| - sendPipe, id, options) {
|
| - var state = new serialization.ConnectionState();
|
| - state.connectionId = id;
|
| - updateClientOptions(state, options);
|
| - var receiver = new dataReceiver.DataReceiver(
|
| - receivePipe, receiveClientPipe, state.bufferSize,
|
| - serialMojom.ReceiveError.DISCONNECTED);
|
| - var sender = new dataSender.DataSender(sendPipe, state.bufferSize,
|
| - serialMojom.SendError.DISCONNECTED);
|
| - this.init_(state,
|
| - connection,
|
| - router,
|
| - receiver,
|
| - sender,
|
| - null,
|
| - serialMojom.ReceiveError.NONE);
|
| - connections_.set(id, this);
|
| - this.startReceive_();
|
| - }
|
| -
|
| - // Initializes this Connection from the provided args.
|
| - Connection.prototype.init_ = function(state,
|
| - connection,
|
| - router,
|
| - receiver,
|
| - sender,
|
| - queuedReceiveData,
|
| - queuedReceiveError) {
|
| - this.state_ = state;
|
| -
|
| - // queuedReceiveData_ or queuedReceiveError_ will store the receive result
|
| - // or error, respectively, if a receive completes or fails while this
|
| - // connection is paused. At most one of the the two may be non-null: a
|
| - // receive completed while paused will only set one of them, no further
|
| - // receives will be performed while paused and a queued result is dispatched
|
| - // before any further receives are initiated when unpausing.
|
| - if (queuedReceiveError != serialMojom.ReceiveError.NONE)
|
| - this.queuedReceiveError_ = {error: queuedReceiveError};
|
| - if (queuedReceiveData) {
|
| - this.queuedReceiveData_ = new ArrayBuffer(queuedReceiveData.length);
|
| - new Int8Array(this.queuedReceiveData_).set(queuedReceiveData);
|
| - }
|
| - this.router_ = router;
|
| - this.remoteConnection_ = connection;
|
| - this.receivePipe_ = receiver;
|
| - this.sendPipe_ = sender;
|
| - this.sendInProgress_ = false;
|
| - };
|
| -
|
| - Connection.create = function(path, options) {
|
| - options = options || {};
|
| - var serviceOptions = getServiceOptions(options);
|
| - var pipe = core.createMessagePipe();
|
| - var sendPipe = core.createMessagePipe();
|
| - var receivePipe = core.createMessagePipe();
|
| - var receivePipeClient = core.createMessagePipe();
|
| - service.connect(path,
|
| - serviceOptions,
|
| - pipe.handle0,
|
| - sendPipe.handle0,
|
| - receivePipe.handle0,
|
| - receivePipeClient.handle0);
|
| - var router = new routerModule.Router(pipe.handle1);
|
| - var connection = new serialMojom.Connection.proxyClass(router);
|
| - return connection.getInfo().then(convertServiceInfo).then(function(info) {
|
| - return Promise.all([info, allocateConnectionId()]);
|
| - }).catch(function(e) {
|
| - router.close();
|
| - core.close(sendPipe.handle1);
|
| - core.close(receivePipe.handle1);
|
| - core.close(receivePipeClient.handle1);
|
| - throw e;
|
| - }).then(function(results) {
|
| - var info = results[0];
|
| - var id = results[1];
|
| - var serialConnectionClient = new Connection(connection,
|
| - router,
|
| - receivePipe.handle1,
|
| - receivePipeClient.handle1,
|
| - sendPipe.handle1,
|
| - 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();
|
| - this.receivePipe_.close();
|
| - this.sendPipe_.close();
|
| - clearTimeout(this.receiveTimeoutId_);
|
| - clearTimeout(this.sendTimeoutId_);
|
| - connections_.delete(this.state_.connectionId);
|
| - return true;
|
| - };
|
| -
|
| - Connection.prototype.getClientInfo_ = function() {
|
| - return {
|
| - connectionId: this.state_.connectionId,
|
| - paused: this.state_.paused,
|
| - persistent: this.state_.persistent,
|
| - name: this.state_.name,
|
| - receiveTimeout: this.state_.receiveTimeout,
|
| - sendTimeout: this.state_.sendTimeout,
|
| - bufferSize: this.state_.bufferSize,
|
| - };
|
| - };
|
| -
|
| - 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.setOptions = function(options) {
|
| - updateClientOptions(this.state_, 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.state_.paused = paused;
|
| - if (paused) {
|
| - clearTimeout(this.receiveTimeoutId_);
|
| - this.receiveTimeoutId_ = null;
|
| - } else if (!this.receiveInProgress_) {
|
| - this.startReceive_();
|
| - }
|
| - };
|
| -
|
| - Connection.prototype.send = function(data) {
|
| - if (this.sendInProgress_)
|
| - return Promise.resolve({bytesSent: 0, error: 'pending'});
|
| -
|
| - if (this.state_.sendTimeout) {
|
| - this.sendTimeoutId_ = setTimeout(function() {
|
| - this.sendPipe_.cancel(serialMojom.SendError.TIMEOUT);
|
| - }.bind(this), this.state_.sendTimeout);
|
| - }
|
| - this.sendInProgress_ = true;
|
| - return this.sendPipe_.send(data).then(function(bytesSent) {
|
| - return {bytesSent: bytesSent};
|
| - }).catch(function(e) {
|
| - return {
|
| - bytesSent: e.bytesSent,
|
| - error: SEND_ERROR_FROM_MOJO[e.error],
|
| - };
|
| - }).then(function(result) {
|
| - if (this.sendTimeoutId_)
|
| - clearTimeout(this.sendTimeoutId_);
|
| - this.sendTimeoutId_ = null;
|
| - this.sendInProgress_ = false;
|
| - return result;
|
| - }.bind(this));
|
| - };
|
| -
|
| - Connection.prototype.startReceive_ = function() {
|
| - this.receiveInProgress_ = true;
|
| - var receivePromise = null;
|
| - // If we have a queued receive result, dispatch it immediately instead of
|
| - // starting a new receive.
|
| - if (this.queuedReceiveData_) {
|
| - receivePromise = Promise.resolve(this.queuedReceiveData_);
|
| - this.queuedReceiveData_ = null;
|
| - } else if (this.queuedReceiveError_) {
|
| - receivePromise = Promise.reject(this.queuedReceiveError_);
|
| - this.queuedReceiveError_ = null;
|
| - } else {
|
| - receivePromise = this.receivePipe_.receive();
|
| - }
|
| - receivePromise.then(this.onDataReceived_.bind(this)).catch(
|
| - this.onReceiveError_.bind(this));
|
| - this.startReceiveTimeoutTimer_();
|
| - };
|
| -
|
| - Connection.prototype.onDataReceived_ = function(data) {
|
| - this.startReceiveTimeoutTimer_();
|
| - this.receiveInProgress_ = false;
|
| - if (this.state_.paused) {
|
| - this.queuedReceiveData_ = data;
|
| - return;
|
| - }
|
| - if (this.onData) {
|
| - this.onData(data);
|
| - }
|
| - if (!this.state_.paused) {
|
| - this.startReceive_();
|
| - }
|
| - };
|
| -
|
| - Connection.prototype.onReceiveError_ = function(e) {
|
| - clearTimeout(this.receiveTimeoutId_);
|
| - this.receiveInProgress_ = false;
|
| - if (this.state_.paused) {
|
| - this.queuedReceiveError_ = e;
|
| - return;
|
| - }
|
| - var error = e.error;
|
| - this.state_.paused = true;
|
| - if (this.onError)
|
| - this.onError(RECEIVE_ERROR_FROM_MOJO[error]);
|
| - };
|
| -
|
| - Connection.prototype.startReceiveTimeoutTimer_ = function() {
|
| - clearTimeout(this.receiveTimeoutId_);
|
| - if (this.state_.receiveTimeout && !this.state_.paused) {
|
| - this.receiveTimeoutId_ = setTimeout(this.onReceiveTimeout_.bind(this),
|
| - this.state_.receiveTimeout);
|
| - }
|
| - };
|
| -
|
| - Connection.prototype.onReceiveTimeout_ = function() {
|
| - if (this.onError)
|
| - this.onError('timeout');
|
| - this.startReceiveTimeoutTimer_();
|
| - };
|
| -
|
| - Connection.prototype.serialize = function() {
|
| - connections_.delete(this.state_.connectionId);
|
| - this.onData = null;
|
| - this.onError = null;
|
| - var handle = this.router_.connector_.handle_;
|
| - this.router_.connector_.handle_ = null;
|
| - this.router_.close();
|
| - clearTimeout(this.receiveTimeoutId_);
|
| - clearTimeout(this.sendTimeoutId_);
|
| -
|
| - // Serializing receivePipe_ will cancel an in-progress receive, which would
|
| - // pause the connection, so save it ahead of time.
|
| - var paused = this.state_.paused;
|
| - return Promise.all([
|
| - this.receivePipe_.serialize(),
|
| - this.sendPipe_.serialize(),
|
| - ]).then(function(serializedComponents) {
|
| - var queuedReceiveError = serialMojom.ReceiveError.NONE;
|
| - if (this.queuedReceiveError_)
|
| - queuedReceiveError = this.queuedReceiveError_.error;
|
| - this.state_.paused = paused;
|
| - var serialized = new serialization.SerializedConnection();
|
| - serialized.state = this.state_;
|
| - serialized.queuedReceiveError = queuedReceiveError;
|
| - serialized.queuedReceiveData =
|
| - this.queuedReceiveData_ ? new Int8Array(this.queuedReceiveData_) :
|
| - null;
|
| - serialized.connection = handle;
|
| - serialized.receiver = serializedComponents[0];
|
| - serialized.sender = serializedComponents[1];
|
| - return serialized;
|
| - }.bind(this));
|
| - };
|
| -
|
| - Connection.deserialize = function(serialized) {
|
| - var serialConnection = $Object.create(Connection.prototype);
|
| - var router = new routerModule.Router(serialized.connection);
|
| - var connection = new serialMojom.Connection.proxyClass(router);
|
| - var receiver = dataReceiver.DataReceiver.deserialize(serialized.receiver);
|
| - var sender = dataSender.DataSender.deserialize(serialized.sender);
|
| -
|
| - // Ensure that paused and persistent are booleans.
|
| - serialized.state.paused = !!serialized.state.paused;
|
| - serialized.state.persistent = !!serialized.state.persistent;
|
| - serialConnection.init_(serialized.state,
|
| - connection,
|
| - router,
|
| - receiver,
|
| - sender,
|
| - serialized.queuedReceiveData,
|
| - serialized.queuedReceiveError);
|
| - serialConnection.awaitingResume_ = true;
|
| - var connectionId = serialized.state.connectionId;
|
| - connections_.set(connectionId, serialConnection);
|
| - if (connectionId >= nextConnectionId_)
|
| - nextConnectionId_ = connectionId + 1;
|
| - return serialConnection;
|
| - };
|
| -
|
| - // Resume receives on a deserialized connection.
|
| - Connection.prototype.resumeReceives = function() {
|
| - if (!this.awaitingResume_)
|
| - return;
|
| - this.awaitingResume_ = false;
|
| - if (!this.state_.paused)
|
| - this.startReceive_();
|
| - };
|
| -
|
| - // All accesses to connections_ and nextConnectionId_ other than those
|
| - // involved in deserialization should ensure that
|
| - // connectionDeserializationComplete_ has resolved first.
|
| - var connectionDeserializationComplete_ = stashClient.retrieve(
|
| - 'serial', serialization.SerializedConnection).then(function(decoded) {
|
| - if (!decoded)
|
| - return;
|
| - return Promise.all($Array.map(decoded, Connection.deserialize));
|
| - });
|
| -
|
| - // The map of connection ID to connection object.
|
| - var connections_ = new Map();
|
| -
|
| - // The next connection ID to be allocated.
|
| - var nextConnectionId_ = 0;
|
| -
|
| - function getConnections() {
|
| - return connectionDeserializationComplete_.then(function() {
|
| - return new Map(connections_);
|
| - });
|
| - }
|
| -
|
| - function getConnection(id) {
|
| - return getConnections().then(function(connections) {
|
| - if (!connections.has(id))
|
| - throw new Error('Serial connection not found.');
|
| - return connections.get(id);
|
| - });
|
| - }
|
| -
|
| - function allocateConnectionId() {
|
| - return connectionDeserializationComplete_.then(function() {
|
| - return nextConnectionId_++;
|
| - });
|
| - }
|
| -
|
| - stashClient.registerClient(
|
| - 'serial', serialization.SerializedConnection, function() {
|
| - return connectionDeserializationComplete_.then(function() {
|
| - var clientPromises = [];
|
| - for (var connection of connections_.values()) {
|
| - if (connection.state_.persistent)
|
| - clientPromises.push(connection.serialize());
|
| - else
|
| - connection.close();
|
| - }
|
| - return Promise.all($Array.map(clientPromises, function(promise) {
|
| - return promise.then(function(serialization) {
|
| - return {
|
| - serialization: serialization,
|
| - monitorHandles: !serialization.paused,
|
| - };
|
| - });
|
| - }));
|
| - });
|
| - });
|
| -
|
| - return {
|
| - getDevices: getDevices,
|
| - createConnection: Connection.create,
|
| - getConnection: getConnection,
|
| - getConnections: getConnections,
|
| - // For testing.
|
| - Connection: Connection,
|
| - };
|
| -});
|
|
|