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

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

Issue 571333002: Add serialization support to the JS DataSender and DataReceiver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@stash-service
Patch Set: Created 6 years, 2 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
5 define('data_receiver', [ 5 define('data_receiver', [
6 'async_waiter', 6 'async_waiter',
7 'device/serial/data_stream.mojom', 7 'device/serial/data_stream.mojom',
8 'device/serial/data_stream_serialization.mojom',
8 'mojo/public/js/bindings/core', 9 'mojo/public/js/bindings/core',
9 'mojo/public/js/bindings/router', 10 'mojo/public/js/bindings/router',
10 ], function(asyncWaiter, dataStream, core, router) { 11 ], function(asyncWaiter, dataStream, serialization, core, router) {
11 /** 12 /**
12 * @module data_receiver 13 * @module data_receiver
13 */ 14 */
14 15
15 /** 16 /**
16 * @typedef module:data_receiver~PendingError
17 * @type {Object}
18 * @property {number} error - the error
19 * @property {number} offset - the location of the error
20 * @private
21 */
22
23 /**
24 * A pending receive operation. 17 * A pending receive operation.
25 * @constructor 18 * @constructor
26 * @alias module:data_receiver~PendingReceive 19 * @alias module:data_receiver~PendingReceive
27 * @private 20 * @private
28 */ 21 */
29 function PendingReceive() { 22 function PendingReceive() {
30 /** 23 /**
31 * The promise that will be resolved or rejected when this receive completes 24 * The promise that will be resolved or rejected when this receive completes
32 * or fails, respectively. 25 * or fails, respectively.
33 * @type {Promise.<ArrayBuffer>} 26 * @type {Promise.<ArrayBuffer>}
(...skipping 28 matching lines...) Expand all
62 * Dispatches received data to the promise returned by 55 * Dispatches received data to the promise returned by
63 * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. 56 * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}.
64 * @param {ArrayBuffer} data The data to dispatch. 57 * @param {ArrayBuffer} data The data to dispatch.
65 */ 58 */
66 PendingReceive.prototype.dispatchData = function(data) { 59 PendingReceive.prototype.dispatchData = function(data) {
67 this.dataCallback_(data); 60 this.dataCallback_(data);
68 }; 61 };
69 62
70 /** 63 /**
71 * Dispatches an error if the offset of the error has been reached. 64 * Dispatches an error if the offset of the error has been reached.
72 * @param {module:data_receiver~PendingError} error The error to dispatch. 65 * @param {module:device/serial/data_stream_serialization~PendingReceiveError}
66 * error The error to dispatch.
73 * @param {number} bytesReceived The number of bytes that have been received. 67 * @param {number} bytesReceived The number of bytes that have been received.
74 */ 68 */
75 PendingReceive.prototype.dispatchError = function(error, bytesReceived) { 69 PendingReceive.prototype.dispatchError = function(error, bytesReceived) {
76 if (bytesReceived != error.offset) 70 if (bytesReceived != error.offset)
77 return false; 71 return false;
78 72
79 var e = new Error(); 73 var e = new Error();
80 e.error = error.error; 74 e.error = error.error;
81 this.errorCallback_(e); 75 this.errorCallback_(e);
82 return true; 76 return true;
(...skipping 12 matching lines...) Expand all
95 /** 89 /**
96 * A DataReceiver that receives data from a DataSource. 90 * A DataReceiver that receives data from a DataSource.
97 * @param {MojoHandle} handle The handle to the DataSource. 91 * @param {MojoHandle} handle The handle to the DataSource.
98 * @param {number} bufferSize How large a buffer the data pipe should use. 92 * @param {number} bufferSize How large a buffer the data pipe should use.
99 * @param {number} fatalErrorValue The receive error value to report in the 93 * @param {number} fatalErrorValue The receive error value to report in the
100 * event of a fatal error. 94 * event of a fatal error.
101 * @constructor 95 * @constructor
102 * @alias module:data_receiver.DataReceiver 96 * @alias module:data_receiver.DataReceiver
103 */ 97 */
104 function DataReceiver(handle, bufferSize, fatalErrorValue) { 98 function DataReceiver(handle, bufferSize, fatalErrorValue) {
99 var dataPipeOptions = {
100 flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
101 elementNumBytes: 1,
102 capacityNumBytes: bufferSize,
103 };
104 var receivePipe = core.createDataPipe(dataPipeOptions);
105 this.init_(
106 handle, receivePipe.consumerHandle, fatalErrorValue, 0, null, false);
107 this.source_.init(receivePipe.producerHandle);
108 }
109
110 DataReceiver.prototype =
111 $Object.create(dataStream.DataSourceClientStub.prototype);
112
113 /**
114 * Closes this DataReceiver.
115 */
116 DataReceiver.prototype.close = function() {
117 if (this.shutDown_)
118 return;
119 this.shutDown_ = true;
120 this.router_.close();
121 this.waiter_.stop();
122 core.close(this.receivePipe_);
123 if (this.receive_) {
124 this.receive_.dispatchFatalError(this.fatalErrorValue_);
125 this.receive_ = null;
126 }
127 };
128
129 /**
130 * Initialize this DataReceiver.
131 * @param {MojoHandle} source A handle to the DataSource
132 * @param {MojoHandle} dataPipe A handle to use for receiving data from the
133 * DataSource.
134 * @param {number} fatalErrorValue The error to dispatch in the event of a
135 * fatal error.
136 * @param {number} bytesReceived The number of bytes already received.
137 * @param
138 * {module:device/serial/data_stream_serialization~PendingReceiveError?}
139 * pendingError The pending error if there is one.
140 * @param {boolean} paused Whether the DataSource is paused.
141 * @private
142 */
143 DataReceiver.prototype.init_ = function(source,
144 dataPipe,
145 fatalErrorValue,
146 bytesReceived,
147 pendingError,
148 paused) {
105 /** 149 /**
106 * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the 150 * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the
107 * connection to the DataSource. 151 * connection to the DataSource.
108 * @private 152 * @private
109 */ 153 */
110 this.router_ = new router.Router(handle); 154 this.router_ = new router.Router(source);
111 /** 155 /**
112 * The connection to the DataSource. 156 * The connection to the DataSource.
113 * @private 157 * @private
114 */ 158 */
115 this.source_ = new dataStream.DataSourceProxy(this.router_); 159 this.source_ = new dataStream.DataSourceProxy(this.router_);
116 this.router_.setIncomingReceiver(this); 160 this.router_.setIncomingReceiver(this);
117 var dataPipeOptions = {
118 flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
119 elementNumBytes: 1,
120 capacityNumBytes: bufferSize,
121 };
122 var receivePipe = core.createDataPipe(dataPipeOptions);
123 this.source_.init(receivePipe.producerHandle);
124 /** 161 /**
125 * The handle to the data pipe to use for receiving data. 162 * The handle to the data pipe to use for receiving data.
126 * @private 163 * @private
127 */ 164 */
128 this.receivePipe_ = receivePipe.consumerHandle; 165 this.receivePipe_ = dataPipe;
129 /** 166 /**
130 * The current receive operation. 167 * The current receive operation.
131 * @type {module:data_receiver~PendingReceive} 168 * @type {module:data_receiver~PendingReceive}
132 * @private 169 * @private
133 */ 170 */
134 this.receive_ = null; 171 this.receive_ = null;
135 /** 172 /**
136 * The error to be dispatched in the event of a fatal error. 173 * The error to be dispatched in the event of a fatal error.
137 * @type {number} 174 * @type {number}
138 * @private 175 * @private
139 */ 176 */
140 this.fatalErrorValue_ = fatalErrorValue; 177 this.fatalErrorValue_ = fatalErrorValue;
141 /** 178 /**
142 * The async waiter used to wait for 179 * The async waiter used to wait for
143 * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable. 180 * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable.
144 * @type module:async_waiter.AsyncWaiter 181 * @type module:async_waiter.AsyncWaiter
145 * @private 182 * @private
146 */ 183 */
147 this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, 184 this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_,
148 core.HANDLE_SIGNAL_READABLE, 185 core.HANDLE_SIGNAL_READABLE,
149 this.onHandleReady_.bind(this)); 186 this.onHandleReady_.bind(this));
150 /** 187 /**
151 * The number of bytes received from the DataSource. 188 * The number of bytes received from the DataSource.
152 * @type {number} 189 * @type {number}
153 * @private 190 * @private
154 */ 191 */
155 this.bytesReceived_ = 0; 192 this.bytesReceived_ = bytesReceived;
156 /** 193 /**
157 * The pending error if there is one. 194 * The pending error if there is one.
158 * @type module:data_receiver~PendingError 195 * @type module:device/serial/data_stream_serialization~PendingReceiveError
159 * @private 196 * @private
160 */ 197 */
161 this.pendingError_ = null; 198 this.pendingError_ = pendingError;
162 /** 199 /**
163 * Whether the DataSource is paused. 200 * Whether the DataSource is paused.
164 * @type {boolean} 201 * @type {boolean}
165 * @private 202 * @private
166 */ 203 */
167 this.paused_ = false; 204 this.paused_ = paused;
168 /** 205 /**
169 * Whether this DataReceiver has shut down. 206 * Whether this DataReceiver has shut down.
170 * @type {boolean} 207 * @type {boolean}
171 * @private 208 * @private
172 */ 209 */
173 this.shutDown_ = false; 210 this.shutDown_ = false;
174 } 211 };
175
176 DataReceiver.prototype =
177 $Object.create(dataStream.DataSourceClientStub.prototype);
178 212
179 /** 213 /**
180 * Closes this DataReceiver. 214 * Serializes this DataReceiver.
215 * This will cancel a receive if one is in progress.
216 * @return {Promise.<?SerializedDataReceiver>} A promise that will resolve to
Ken Rockot(use gerrit already) 2014/09/24 16:08:02 Assuming we follow the Google style guide here (an
Sam McNally 2014/09/25 05:01:39 Done.
217 * the serialization of this DataReceiver. If this DataReceiver has shut
218 * down, the promise will resolve to null.
181 */ 219 */
182 DataReceiver.prototype.close = function() { 220 DataReceiver.prototype.serialize = function() {
183 if (this.shutDown_) 221 if (this.shutDown_)
184 return; 222 return Promise.resolve(null);
185 this.shutDown_ = true; 223
186 this.router_.close();
187 this.waiter_.stop(); 224 this.waiter_.stop();
188 core.close(this.receivePipe_);
189 if (this.receive_) { 225 if (this.receive_) {
190 this.receive_.dispatchFatalError(this.fatalErrorValue_); 226 this.receive_.dispatchFatalError(this.fatalErrorValue_);
191 this.receive_ = null; 227 this.receive_ = null;
192 } 228 }
229 var serialized = new serialization.SerializedDataReceiver();
230 serialized.source = this.router_.connector_.handle_;
231 serialized.data_pipe = this.receivePipe_;
232 serialized.fatal_error_value = this.fatalErrorValue_;
233 serialized.bytes_received = this.bytesReceived_;
234 serialized.paused = this.paused_;
235 serialized.pending_error = this.pendingError_;
236 this.router_.connector_.handle_ = null;
237 this.router_.close();
238 this.shutDown_ = true;
239 return Promise.resolve(serialized);
193 }; 240 };
194 241
195 /** 242 /**
243 * Deserializes a SerializedDataReceiver.
244 * @param {?SerializedDataReceiver} serialized The serialized DataReceiver.
245 * @return {DataReceiver} The deserialized DataReceiver.
246 */
247 DataReceiver.deserialize = function(serialized) {
248 var receiver = $Object.create(DataReceiver.prototype);
249 receiver.deserialize_(serialized);
250 return receiver;
251 };
252
253 /**
254 * Deserializes a SerializedDataReceiver into this DataReceiver.
255 * @param {?SerializedDataReceiver} serialized The serialized DataReceiver.
256 * @private
257 */
258 DataReceiver.prototype.deserialize_ = function(serialized) {
259 if (!serialized) {
260 this.shutDown_ = true;
261 return;
262 }
263 this.init_(serialized.source,
264 serialized.data_pipe,
265 serialized.fatal_error_value,
266 serialized.bytes_received,
267 serialized.pending_error,
268 serialized.paused);
269 };
270
271 /**
196 * Receive data from the DataSource. 272 * Receive data from the DataSource.
197 * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error 273 * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error
198 * occurs, the promise will reject with an Error object with a property 274 * occurs, the promise will reject with an Error object with a property
199 * error containing the error code. 275 * error containing the error code.
200 * @throws Will throw if this has encountered a fatal error or another receive 276 * @throws Will throw if this has encountered a fatal error or another receive
201 * is in progress. 277 * is in progress.
202 */ 278 */
203 DataReceiver.prototype.receive = function() { 279 DataReceiver.prototype.receive = function() {
204 if (this.shutDown_) 280 if (this.shutDown_)
205 throw new Error('System error'); 281 throw new Error('DataReceiver has been closed');
206 if (this.receive_) 282 if (this.receive_)
207 throw new Error('Receive already in progress.'); 283 throw new Error('Receive already in progress.');
208 var receive = new PendingReceive(); 284 var receive = new PendingReceive();
209 var promise = receive.getPromise(); 285 var promise = receive.getPromise();
210 if (this.pendingError_ && 286 if (this.pendingError_ &&
211 receive.dispatchError(this.pendingError_, this.bytesReceived_)) { 287 receive.dispatchError(this.pendingError_, this.bytesReceived_)) {
212 this.pendingError_ = null; 288 this.pendingError_ = null;
213 this.paused_ = true; 289 this.paused_ = true;
214 return promise; 290 return promise;
215 } 291 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 /** 325 /**
250 * Invoked by the DataSource when an error is encountered. 326 * Invoked by the DataSource when an error is encountered.
251 * @param {number} offset The location at which the error occurred. 327 * @param {number} offset The location at which the error occurred.
252 * @param {number} error The error that occurred. 328 * @param {number} error The error that occurred.
253 * @private 329 * @private
254 */ 330 */
255 DataReceiver.prototype.onError = function(offset, error) { 331 DataReceiver.prototype.onError = function(offset, error) {
256 if (this.shutDown_) 332 if (this.shutDown_)
257 return; 333 return;
258 334
259 /** 335 var pendingError = new serialization.PendingReceiveError();
260 * @type module:data_receiver~PendingError 336 pendingError.error = error;
261 */ 337 pendingError.offset = offset;
262 var pendingError = {
263 error: error,
264 offset: offset,
265 };
266 if (this.receive_ && 338 if (this.receive_ &&
267 this.receive_.dispatchError(pendingError, this.bytesReceived_)) { 339 this.receive_.dispatchError(pendingError, this.bytesReceived_)) {
268 this.receive_ = null; 340 this.receive_ = null;
269 this.waiter_.stop(); 341 this.waiter_.stop();
270 this.paused_ = true; 342 this.paused_ = true;
271 return; 343 return;
272 } 344 }
273 this.pendingError_ = pendingError; 345 this.pendingError_ = pendingError;
274 }; 346 };
275 347
276 return {DataReceiver: DataReceiver}; 348 return {DataReceiver: DataReceiver};
277 }); 349 });
OLDNEW
« no previous file with comments | « extensions/renderer/api/serial/serial_api_unittest.cc ('k') | extensions/renderer/resources/data_sender.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698