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

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

Issue 2410743002: Remove the mojo serial interfaces and related infrastructure. (Closed)
Patch Set: Created 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 define('data_sender', [
6 'device/serial/data_stream.mojom',
7 'device/serial/data_stream_serialization.mojom',
8 'mojo/public/js/core',
9 'mojo/public/js/router',
10 ], function(dataStreamMojom, serialization, core, routerModule) {
11 /**
12 * @module data_sender
13 */
14
15 /**
16 * A pending send operation.
17 * @param {!ArrayBuffer} data The data to be sent.
18 * @constructor
19 * @alias module:data_sender~PendingSend
20 * @private
21 */
22 function PendingSend(data) {
23 /**
24 * The data to be sent.
25 * @type {ArrayBuffer}
26 * @private
27 */
28 this.data_ = data;
29 /**
30 * The total length of data to be sent.
31 * @type {number}
32 * @private
33 */
34 this.length_ = data.byteLength;
35 /**
36 * The promise that will be resolved or rejected when this send completes
37 * or fails, respectively.
38 * @type {!Promise<number>}
39 * @private
40 */
41 this.promise_ = new Promise(function(resolve, reject) {
42 /**
43 * The callback to call on success.
44 * @type {Function}
45 * @private
46 */
47 this.successCallback_ = resolve;
48 /**
49 * The callback to call with the error on failure.
50 * @type {Function}
51 * @private
52 */
53 this.errorCallback_ = reject;
54 }.bind(this));
55 }
56
57 /**
58 * Returns the promise that will be resolved when this operation completes or
59 * rejected if an error occurs.
60 * @return {!Promise<number>} A promise to the number of bytes sent.
61 */
62 PendingSend.prototype.getPromise = function() {
63 return this.promise_;
64 };
65
66 /**
67 * Invoked when the DataSink reports that bytes have been sent. Resolves the
68 * promise returned by
69 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} once all
70 * bytes have been reported as sent.
71 */
72 PendingSend.prototype.reportBytesSent = function() {
73 this.successCallback_(this.length_);
74 };
75
76 /**
77 * Invoked when the DataSink reports an error. Rejects the promise returned by
78 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} unless the
79 * error occurred after this send, that is, unless numBytes is greater than
80 * the nubmer of outstanding bytes.
81 * @param {number} numBytes The number of bytes sent.
82 * @param {number} error The error reported by the DataSink.
83 */
84 PendingSend.prototype.reportBytesSentAndError = function(numBytes, error) {
85 var e = new Error();
86 e.error = error;
87 e.bytesSent = numBytes;
88 this.errorCallback_(e);
89 };
90
91 /**
92 * Writes pending data into the data pipe.
93 * @param {!DataSink} sink The DataSink to receive the data.
94 * @return {!Object} result The send result.
95 * @return {boolean} result.completed Whether all of the pending data was
96 * sent.
97 */
98 PendingSend.prototype.sendData = function(sink) {
99 var dataSent = sink.onData(new Uint8Array(this.data_));
100 this.data_ = null;
101 return dataSent;
102 };
103
104 /**
105 * A DataSender that sends data to a DataSink.
106 * @param {!MojoHandle} sink The handle to the DataSink.
107 * @param {number} bufferSize How large a buffer to use for data.
108 * @param {number} fatalErrorValue The send error value to report in the
109 * event of a fatal error.
110 * @constructor
111 * @alias module:data_sender.DataSender
112 */
113 function DataSender(sink, bufferSize, fatalErrorValue) {
114 this.init_(sink, fatalErrorValue);
115 }
116
117 /**
118 * Closes this DataSender.
119 */
120 DataSender.prototype.close = function() {
121 if (this.shutDown_)
122 return;
123 this.shutDown_ = true;
124 this.router_.close();
125 while (this.sendsAwaitingAck_.length) {
126 this.sendsAwaitingAck_.pop().reportBytesSentAndError(
127 0, this.fatalErrorValue_);
128 }
129 this.callCancelCallback_();
130 };
131
132 /**
133 * Initialize this DataSender.
134 * @param {!MojoHandle} sink A handle to the DataSink.
135 * @param {number} fatalErrorValue The error to dispatch in the event of a
136 * fatal error.
137 * @private
138 */
139 DataSender.prototype.init_ = function(sink, fatalErrorValue) {
140 /**
141 * The error to be dispatched in the event of a fatal error.
142 * @const {number}
143 * @private
144 */
145 this.fatalErrorValue_ = fatalErrorValue;
146 /**
147 * Whether this DataSender has shut down.
148 * @type {boolean}
149 * @private
150 */
151 this.shutDown_ = false;
152 /**
153 * The [Router]{@link module:mojo/public/js/router.Router} for the
154 * connection to the DataSink.
155 * @private
156 */
157 this.router_ = new routerModule.Router(sink);
158 /**
159 * The connection to the DataSink.
160 * @private
161 */
162 this.sink_ = new dataStreamMojom.DataSink.proxyClass(this.router_);
163 /**
164 * A queue of sends that have sent their data to the DataSink, but have not
165 * been received by the DataSink.
166 * @type {!module:data_sender~PendingSend[]}
167 * @private
168 */
169 this.sendsAwaitingAck_ = [];
170
171 /**
172 * The callback that will resolve a pending cancel if one is in progress.
173 * @type {?Function}
174 * @private
175 */
176 this.pendingCancel_ = null;
177
178 /**
179 * The promise that will be resolved when a pending cancel completes if one
180 * is in progress.
181 * @type {Promise}
182 * @private
183 */
184 this.cancelPromise_ = null;
185 };
186
187 /**
188 * Serializes this DataSender.
189 * This will cancel any sends in progress before the returned promise
190 * resolves.
191 * @return {!Promise<SerializedDataSender>} A promise that will resolve to
192 * the serialization of this DataSender. If this DataSender has shut down,
193 * the promise will resolve to null.
194 */
195 DataSender.prototype.serialize = function() {
196 if (this.shutDown_)
197 return Promise.resolve(null);
198
199 var readyToSerialize = Promise.resolve();
200 if (this.sendsAwaitingAck_.length) {
201 if (this.pendingCancel_)
202 readyToSerialize = this.cancelPromise_;
203 else
204 readyToSerialize = this.cancel(this.fatalErrorValue_);
205 }
206 return readyToSerialize.then(function() {
207 var serialized = new serialization.SerializedDataSender();
208 serialized.sink = this.router_.connector_.handle_;
209 serialized.fatal_error_value = this.fatalErrorValue_;
210 this.router_.connector_.handle_ = null;
211 this.router_.close();
212 this.shutDown_ = true;
213 return serialized;
214 }.bind(this));
215 };
216
217 /**
218 * Deserializes a SerializedDataSender.
219 * @param {SerializedDataSender} serialized The serialized DataSender.
220 * @return {!DataSender} The deserialized DataSender.
221 */
222 DataSender.deserialize = function(serialized) {
223 var sender = $Object.create(DataSender.prototype);
224 sender.deserialize_(serialized);
225 return sender;
226 };
227
228 /**
229 * Deserializes a SerializedDataSender into this DataSender.
230 * @param {SerializedDataSender} serialized The serialized DataSender.
231 * @private
232 */
233 DataSender.prototype.deserialize_ = function(serialized) {
234 if (!serialized) {
235 this.shutDown_ = true;
236 return;
237 }
238 this.init_(serialized.sink, serialized.fatal_error_value,
239 serialized.buffer_size);
240 };
241
242 /**
243 * Sends data to the DataSink.
244 * @return {!Promise<number>} A promise to the number of bytes sent. If an
245 * error occurs, the promise will reject with an Error object with a
246 * property error containing the error code.
247 * @throws Will throw if this has encountered a fatal error or a cancel is in
248 * progress.
249 */
250 DataSender.prototype.send = function(data) {
251 if (this.shutDown_)
252 throw new Error('DataSender has been closed');
253 if (this.pendingCancel_)
254 throw new Error('Cancel in progress');
255 var send = new PendingSend(data);
256 this.sendsAwaitingAck_.push(send);
257 send.sendData(this.sink_).then(this.reportBytesSentAndError.bind(this));
258 return send.getPromise();
259 };
260
261 /**
262 * Requests the cancellation of any in-progress sends. Calls to
263 * [send()]{@link module:data_sender.DataSender#send} will fail until the
264 * cancel has completed.
265 * @param {number} error The error to report for cancelled sends.
266 * @return {!Promise} A promise that will resolve when the cancel completes.
267 * @throws Will throw if this has encountered a fatal error or another cancel
268 * is in progress.
269 */
270 DataSender.prototype.cancel = function(error) {
271 if (this.shutDown_)
272 throw new Error('DataSender has been closed');
273 if (this.pendingCancel_)
274 throw new Error('Cancel already in progress');
275 if (this.sendsAwaitingAck_.length == 0)
276 return Promise.resolve();
277
278 this.sink_.cancel(error);
279 this.cancelPromise_ = new Promise(function(resolve) {
280 this.pendingCancel_ = resolve;
281 }.bind(this));
282 return this.cancelPromise_;
283 };
284
285 /**
286 * Calls and clears the pending cancel callback if one is pending.
287 * @private
288 */
289 DataSender.prototype.callCancelCallback_ = function() {
290 if (this.pendingCancel_) {
291 this.cancelPromise_ = null;
292 this.pendingCancel_();
293 this.pendingCancel_ = null;
294 }
295 };
296
297 /**
298 * Invoked by the DataSink to report that data has been successfully sent.
299 * @private
300 */
301 DataSender.prototype.reportBytesSent = function() {
302 var result = this.sendsAwaitingAck_[0].reportBytesSent();
303 this.sendsAwaitingAck_.shift();
304
305 // A cancel is completed when all of the sends that were in progress have
306 // completed or failed. This is the case where all sends complete
307 // successfully.
308 if (this.sendsAwaitingAck_.length == 0)
309 this.callCancelCallback_();
310 };
311
312 /**
313 * Invoked by the DataSink to report an error in sending data.
314 * @param {number} numBytes The number of bytes sent.
315 * @param {number} error The error reported by the DataSink.
316 * @private
317 */
318 DataSender.prototype.reportBytesSentAndError = function(result) {
319 var numBytes = result.bytes_sent;
320 var error = result.error;
321 if (!error) {
322 this.reportBytesSent();
323 return;
324 }
325 var result =
326 this.sendsAwaitingAck_[0].reportBytesSentAndError(numBytes, error);
327 this.sendsAwaitingAck_.shift();
328 if (this.sendsAwaitingAck_.length)
329 return;
330 this.callCancelCallback_();
331 this.sink_.clearError();
332 };
333
334 return {DataSender: DataSender};
335 });
OLDNEW
« no previous file with comments | « extensions/renderer/resources/data_receiver.js ('k') | extensions/renderer/resources/extensions_renderer_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698