Index: extensions/renderer/resources/data_receiver.js |
diff --git a/extensions/renderer/resources/data_receiver.js b/extensions/renderer/resources/data_receiver.js |
index 9224e967bc92293f8c60e8cb1374c7ceeba5dd0f..38d0567f54492887a432191a8eed08b3d3b80fd4 100644 |
--- a/extensions/renderer/resources/data_receiver.js |
+++ b/extensions/renderer/resources/data_receiver.js |
@@ -5,22 +5,15 @@ |
define('data_receiver', [ |
'async_waiter', |
'device/serial/data_stream.mojom', |
+ 'device/serial/data_stream_serialization.mojom', |
'mojo/public/js/bindings/core', |
'mojo/public/js/bindings/router', |
-], function(asyncWaiter, dataStream, core, router) { |
+], function(asyncWaiter, dataStream, serialization, core, router) { |
/** |
* @module data_receiver |
*/ |
/** |
- * @typedef module:data_receiver~PendingError |
- * @type {Object} |
- * @property {number} error - the error |
- * @property {number} offset - the location of the error |
- * @private |
- */ |
- |
- /** |
* A pending receive operation. |
* @constructor |
* @alias module:data_receiver~PendingReceive |
@@ -30,7 +23,7 @@ define('data_receiver', [ |
/** |
* The promise that will be resolved or rejected when this receive completes |
* or fails, respectively. |
- * @type {Promise.<ArrayBuffer>} |
+ * @type {!Promise.<ArrayBuffer>} |
* @private |
*/ |
this.promise_ = new Promise(function(resolve, reject) { |
@@ -61,7 +54,7 @@ define('data_receiver', [ |
/** |
* Dispatches received data to the promise returned by |
* [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. |
- * @param {ArrayBuffer} data The data to dispatch. |
+ * @param {!ArrayBuffer} data The data to dispatch. |
*/ |
PendingReceive.prototype.dispatchData = function(data) { |
this.dataCallback_(data); |
@@ -69,7 +62,7 @@ define('data_receiver', [ |
/** |
* Dispatches an error if the offset of the error has been reached. |
- * @param {module:data_receiver~PendingError} error The error to dispatch. |
+ * @param {!PendingReceiveError} error The error to dispatch. |
* @param {number} bytesReceived The number of bytes that have been received. |
*/ |
PendingReceive.prototype.dispatchError = function(error, bytesReceived) { |
@@ -94,7 +87,7 @@ define('data_receiver', [ |
/** |
* A DataReceiver that receives data from a DataSource. |
- * @param {MojoHandle} handle The handle to the DataSource. |
+ * @param {!MojoHandle} handle The handle to the DataSource. |
* @param {number} bufferSize How large a buffer the data pipe should use. |
* @param {number} fatalErrorValue The receive error value to report in the |
* event of a fatal error. |
@@ -102,30 +95,72 @@ define('data_receiver', [ |
* @alias module:data_receiver.DataReceiver |
*/ |
function DataReceiver(handle, bufferSize, fatalErrorValue) { |
+ var dataPipeOptions = { |
+ flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
+ elementNumBytes: 1, |
+ capacityNumBytes: bufferSize, |
+ }; |
+ var receivePipe = core.createDataPipe(dataPipeOptions); |
+ this.init_( |
+ handle, receivePipe.consumerHandle, fatalErrorValue, 0, null, false); |
+ this.source_.init(receivePipe.producerHandle); |
+ } |
+ |
+ DataReceiver.prototype = |
+ $Object.create(dataStream.DataSourceClientStub.prototype); |
+ |
+ /** |
+ * Closes this DataReceiver. |
+ */ |
+ DataReceiver.prototype.close = function() { |
+ if (this.shutDown_) |
+ return; |
+ this.shutDown_ = true; |
+ this.router_.close(); |
+ this.waiter_.stop(); |
+ core.close(this.receivePipe_); |
+ if (this.receive_) { |
+ this.receive_.dispatchFatalError(this.fatalErrorValue_); |
+ this.receive_ = null; |
+ } |
+ }; |
+ |
+ /** |
+ * Initialize this DataReceiver. |
+ * @param {!MojoHandle} source A handle to the DataSource |
+ * @param {!MojoHandle} dataPipe A handle to use for receiving data from the |
+ * DataSource. |
+ * @param {number} fatalErrorValue The error to dispatch in the event of a |
+ * fatal error. |
+ * @param {number} bytesReceived The number of bytes already received. |
+ * @param {PendingReceiveError} pendingError The pending error if there is |
+ * one. |
+ * @param {boolean} paused Whether the DataSource is paused. |
+ * @private |
+ */ |
+ DataReceiver.prototype.init_ = function(source, |
+ dataPipe, |
+ fatalErrorValue, |
+ bytesReceived, |
+ pendingError, |
+ paused) { |
/** |
* The [Router]{@link module:mojo/public/js/bindings/router.Router} for the |
* connection to the DataSource. |
* @private |
*/ |
- this.router_ = new router.Router(handle); |
+ this.router_ = new router.Router(source); |
/** |
* The connection to the DataSource. |
* @private |
*/ |
this.source_ = new dataStream.DataSourceProxy(this.router_); |
this.router_.setIncomingReceiver(this); |
- var dataPipeOptions = { |
- flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
- elementNumBytes: 1, |
- capacityNumBytes: bufferSize, |
- }; |
- var receivePipe = core.createDataPipe(dataPipeOptions); |
- this.source_.init(receivePipe.producerHandle); |
/** |
* The handle to the data pipe to use for receiving data. |
* @private |
*/ |
- this.receivePipe_ = receivePipe.consumerHandle; |
+ this.receivePipe_ = dataPipe; |
/** |
* The current receive operation. |
* @type {module:data_receiver~PendingReceive} |
@@ -134,14 +169,15 @@ define('data_receiver', [ |
this.receive_ = null; |
/** |
* The error to be dispatched in the event of a fatal error. |
- * @type {number} |
+ * @const {number} |
* @private |
*/ |
this.fatalErrorValue_ = fatalErrorValue; |
/** |
* The async waiter used to wait for |
- * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable. |
- * @type module:async_waiter.AsyncWaiter |
+ * |[receivePipe_]{@link module:data_receiver.DataReceiver#receivePipe_}| to |
+ * be readable. |
+ * @type {!module:async_waiter.AsyncWaiter} |
* @private |
*/ |
this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, |
@@ -152,44 +188,83 @@ define('data_receiver', [ |
* @type {number} |
* @private |
*/ |
- this.bytesReceived_ = 0; |
+ this.bytesReceived_ = bytesReceived; |
/** |
* The pending error if there is one. |
- * @type module:data_receiver~PendingError |
+ * @type {PendingReceiveError} |
* @private |
*/ |
- this.pendingError_ = null; |
+ this.pendingError_ = pendingError; |
/** |
* Whether the DataSource is paused. |
* @type {boolean} |
* @private |
*/ |
- this.paused_ = false; |
+ this.paused_ = paused; |
/** |
* Whether this DataReceiver has shut down. |
* @type {boolean} |
* @private |
*/ |
this.shutDown_ = false; |
- } |
- |
- DataReceiver.prototype = |
- $Object.create(dataStream.DataSourceClientStub.prototype); |
+ }; |
/** |
- * Closes this DataReceiver. |
+ * Serializes this DataReceiver. |
+ * This will cancel a receive if one is in progress. |
+ * @return {!Promise.<SerializedDataReceiver>} A promise that will resolve to |
+ * the serialization of this DataReceiver. If this DataReceiver has shut |
+ * down, the promise will resolve to null. |
*/ |
- DataReceiver.prototype.close = function() { |
+ DataReceiver.prototype.serialize = function() { |
if (this.shutDown_) |
- return; |
- this.shutDown_ = true; |
- this.router_.close(); |
+ return Promise.resolve(null); |
+ |
this.waiter_.stop(); |
- core.close(this.receivePipe_); |
if (this.receive_) { |
this.receive_.dispatchFatalError(this.fatalErrorValue_); |
this.receive_ = null; |
} |
+ var serialized = new serialization.SerializedDataReceiver(); |
+ serialized.source = this.router_.connector_.handle_; |
+ serialized.data_pipe = this.receivePipe_; |
+ serialized.fatal_error_value = this.fatalErrorValue_; |
+ serialized.bytes_received = this.bytesReceived_; |
+ serialized.paused = this.paused_; |
+ serialized.pending_error = this.pendingError_; |
+ this.router_.connector_.handle_ = null; |
+ this.router_.close(); |
+ this.shutDown_ = true; |
+ return Promise.resolve(serialized); |
+ }; |
+ |
+ /** |
+ * Deserializes a SerializedDataReceiver. |
+ * @param {SerializedDataReceiver} serialized The serialized DataReceiver. |
+ * @return {!DataReceiver} The deserialized DataReceiver. |
+ */ |
+ DataReceiver.deserialize = function(serialized) { |
+ var receiver = $Object.create(DataReceiver.prototype); |
+ receiver.deserialize_(serialized); |
+ return receiver; |
+ }; |
+ |
+ /** |
+ * Deserializes a SerializedDataReceiver into this DataReceiver. |
+ * @param {SerializedDataReceiver} serialized The serialized DataReceiver. |
+ * @private |
+ */ |
+ DataReceiver.prototype.deserialize_ = function(serialized) { |
+ if (!serialized) { |
+ this.shutDown_ = true; |
+ return; |
+ } |
+ this.init_(serialized.source, |
+ serialized.data_pipe, |
+ serialized.fatal_error_value, |
+ serialized.bytes_received, |
+ serialized.pending_error, |
+ serialized.paused); |
}; |
/** |
@@ -202,7 +277,7 @@ define('data_receiver', [ |
*/ |
DataReceiver.prototype.receive = function() { |
if (this.shutDown_) |
- throw new Error('System error'); |
+ throw new Error('DataReceiver has been closed'); |
if (this.receive_) |
throw new Error('Receive already in progress.'); |
var receive = new PendingReceive(); |
@@ -223,8 +298,9 @@ define('data_receiver', [ |
}; |
/** |
- * Invoked when |handle_| is ready to read. Reads from the data pipe if the |
- * wait is successful. |
+ * Invoked when |
+ * |[receivePipe_]{@link module:data_receiver.DataReceiver#receivePipe_}| is |
+ * ready to read. Reads from the data pipe if the wait is successful. |
* @param {number} waitResult The result of the asynchronous wait. |
* @private |
*/ |
@@ -256,13 +332,9 @@ define('data_receiver', [ |
if (this.shutDown_) |
return; |
- /** |
- * @type module:data_receiver~PendingError |
- */ |
- var pendingError = { |
- error: error, |
- offset: offset, |
- }; |
+ var pendingError = new serialization.PendingReceiveError(); |
+ pendingError.error = error; |
+ pendingError.offset = offset; |
if (this.receive_ && |
this.receive_.dispatchError(pendingError, this.bytesReceived_)) { |
this.receive_ = null; |