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

Side by Side Diff: remoting/webapp/crd/js/fallback_signal_strategy.js

Issue 1133913002: [Chromoting] Move shared webapp JS files from crd/js -> base/js (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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 2015 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 'use strict';
6
7 /** @suppress {duplicate} */
8 var remoting = remoting || {};
9
10 /**
11 * A signal strategy encapsulating a primary and a back-up strategy. If the
12 * primary fails or times out, then the secondary is used. Information about
13 * which strategy was used, and why, is returned via |onProgressCallback|.
14 *
15 * @param {remoting.SignalStrategy} primary
16 * @param {remoting.SignalStrategy} secondary
17 *
18 * @implements {remoting.SignalStrategy}
19 * @constructor
20 */
21 remoting.FallbackSignalStrategy = function(primary,
22 secondary) {
23 /** @private {remoting.SignalStrategy} */
24 this.primary_ = primary;
25 this.primary_.setStateChangedCallback(this.onPrimaryStateChanged_.bind(this));
26
27 /** @private {remoting.SignalStrategy} */
28 this.secondary_ = secondary;
29 this.secondary_.setStateChangedCallback(
30 this.onSecondaryStateChanged_.bind(this));
31
32 /** @private {?function(remoting.SignalStrategy.State)} */
33 this.onStateChangedCallback_ = null;
34
35 /** @private {?function(Element):void} */
36 this.onIncomingStanzaCallback_ = null;
37
38 /**
39 * @private {number}
40 * @const
41 */
42 this.PRIMARY_CONNECT_TIMEOUT_MS_ = 10 * 1000;
43
44 /**
45 * @enum {string}
46 * @private
47 */
48 this.State = {
49 NOT_CONNECTED: 'not-connected',
50 PRIMARY_PENDING: 'primary-pending',
51 PRIMARY_SUCCEEDED: 'primary-succeeded',
52 SECONDARY_PENDING: 'secondary-pending',
53 SECONDARY_SUCCEEDED: 'secondary-succeeded',
54 SECONDARY_FAILED: 'secondary-failed',
55 CLOSED: 'closed'
56 };
57
58 /** @private {string} */
59 this.state_ = this.State.NOT_CONNECTED;
60
61 /** @private {?remoting.SignalStrategy.State} */
62 this.externalState_ = null;
63
64 /** @private {string} */
65 this.server_ = '';
66
67 /** @private {string} */
68 this.username_ = '';
69
70 /** @private {string} */
71 this.authToken_ = '';
72
73 /** @private {number} */
74 this.primaryConnectTimerId_ = 0;
75
76 /** @private {remoting.LogToServer} */
77 this.logToServer_ = null;
78
79 /**
80 * @type {Array<{strategyType: remoting.SignalStrategy.Type,
81 progress: remoting.FallbackSignalStrategy.Progress}>}
82 */
83 this.connectionSetupResults_ = [];
84
85 };
86
87 /**
88 * @enum {string}
89 */
90 remoting.FallbackSignalStrategy.Progress = {
91 SUCCEEDED: 'succeeded',
92 FAILED: 'failed',
93 TIMED_OUT: 'timed-out',
94 SUCCEEDED_LATE: 'succeeded-late',
95 FAILED_LATE: 'failed-late',
96 };
97
98 remoting.FallbackSignalStrategy.prototype.dispose = function() {
99 this.primary_.dispose();
100 this.secondary_.dispose();
101 };
102
103 /**
104 * @param {function(remoting.SignalStrategy.State):void} onStateChangedCallback
105 * Callback to call on state change.
106 */
107 remoting.FallbackSignalStrategy.prototype.setStateChangedCallback = function(
108 onStateChangedCallback) {
109 this.onStateChangedCallback_ = onStateChangedCallback;
110 };
111
112 /**
113 * @param {?function(Element):void} onIncomingStanzaCallback Callback to call on
114 * incoming messages.
115 */
116 remoting.FallbackSignalStrategy.prototype.setIncomingStanzaCallback =
117 function(onIncomingStanzaCallback) {
118 this.onIncomingStanzaCallback_ = onIncomingStanzaCallback;
119 if (this.state_ == this.State.PRIMARY_PENDING ||
120 this.state_ == this.State.PRIMARY_SUCCEEDED) {
121 this.primary_.setIncomingStanzaCallback(onIncomingStanzaCallback);
122 } else if (this.state_ == this.State.SECONDARY_PENDING ||
123 this.state_ == this.State.SECONDARY_SUCCEEDED) {
124 this.secondary_.setIncomingStanzaCallback(onIncomingStanzaCallback);
125 }
126 };
127
128 /**
129 * @param {string} server
130 * @param {string} username
131 * @param {string} authToken
132 */
133 remoting.FallbackSignalStrategy.prototype.connect =
134 function(server, username, authToken) {
135 base.debug.assert(this.state_ == this.State.NOT_CONNECTED);
136 base.debug.assert(this.onStateChangedCallback_ != null);
137 this.server_ = server;
138 this.username_ = username;
139 this.authToken_ = authToken;
140 this.state_ = this.State.PRIMARY_PENDING;
141 this.primary_.setIncomingStanzaCallback(this.onIncomingStanzaCallback_);
142 this.primary_.connect(server, username, authToken);
143 this.primaryConnectTimerId_ =
144 window.setTimeout(this.onPrimaryTimeout_.bind(this),
145 this.PRIMARY_CONNECT_TIMEOUT_MS_);
146 };
147
148 /**
149 * Sends a message. Can be called only in CONNECTED state.
150 * @param {string} message
151 */
152 remoting.FallbackSignalStrategy.prototype.sendMessage = function(message) {
153 this.getConnectedSignalStrategy_().sendMessage(message);
154 };
155
156 /**
157 * Send any messages accumulated during connection set-up.
158 *
159 * @param {remoting.LogToServer} logToServer The LogToServer instance for the
160 * connection.
161 */
162 remoting.FallbackSignalStrategy.prototype.sendConnectionSetupResults =
163 function(logToServer) {
164 this.logToServer_ = logToServer;
165 this.sendConnectionSetupResultsInternal_();
166 }
167
168 remoting.FallbackSignalStrategy.prototype.sendConnectionSetupResultsInternal_ =
169 function() {
170 for (var i = 0; i < this.connectionSetupResults_.length; ++i) {
171 var result = this.connectionSetupResults_[i];
172 this.logToServer_.logSignalStrategyProgress(result.strategyType,
173 result.progress);
174 }
175 this.connectionSetupResults_ = [];
176 };
177
178 /** @return {remoting.SignalStrategy.State} Current state */
179 remoting.FallbackSignalStrategy.prototype.getState = function() {
180 return (this.externalState_ === null)
181 ? remoting.SignalStrategy.State.NOT_CONNECTED
182 : this.externalState_;
183 };
184
185 /** @return {!remoting.Error} Error when in FAILED state. */
186 remoting.FallbackSignalStrategy.prototype.getError = function() {
187 base.debug.assert(this.state_ == this.State.SECONDARY_FAILED);
188 base.debug.assert(
189 this.secondary_.getState() == remoting.SignalStrategy.State.FAILED);
190 return this.secondary_.getError();
191 };
192
193 /** @return {string} Current JID when in CONNECTED state. */
194 remoting.FallbackSignalStrategy.prototype.getJid = function() {
195 return this.getConnectedSignalStrategy_().getJid();
196 };
197
198 /** @return {remoting.SignalStrategy.Type} The signal strategy type. */
199 remoting.FallbackSignalStrategy.prototype.getType = function() {
200 return this.getConnectedSignalStrategy_().getType();
201 };
202
203 /**
204 * @return {remoting.SignalStrategy} The active signal strategy, if the
205 * connection has succeeded.
206 * @private
207 */
208 remoting.FallbackSignalStrategy.prototype.getConnectedSignalStrategy_ =
209 function() {
210 if (this.state_ == this.State.PRIMARY_SUCCEEDED) {
211 base.debug.assert(
212 this.primary_.getState() == remoting.SignalStrategy.State.CONNECTED);
213 return this.primary_;
214 } else if (this.state_ == this.State.SECONDARY_SUCCEEDED) {
215 base.debug.assert(
216 this.secondary_.getState() == remoting.SignalStrategy.State.CONNECTED);
217 return this.secondary_;
218 } else {
219 base.debug.assert(
220 false,
221 'getConnectedSignalStrategy called in unconnected state');
222 return null;
223 }
224 };
225
226 /**
227 * @param {remoting.SignalStrategy.State} state
228 * @private
229 */
230 remoting.FallbackSignalStrategy.prototype.onPrimaryStateChanged_ =
231 function(state) {
232 switch (state) {
233 case remoting.SignalStrategy.State.CONNECTED:
234 if (this.state_ == this.State.PRIMARY_PENDING) {
235 window.clearTimeout(this.primaryConnectTimerId_);
236 this.updateProgress_(
237 this.primary_,
238 remoting.FallbackSignalStrategy.Progress.SUCCEEDED);
239 this.state_ = this.State.PRIMARY_SUCCEEDED;
240 } else {
241 this.updateProgress_(
242 this.primary_,
243 remoting.FallbackSignalStrategy.Progress.SUCCEEDED_LATE);
244 }
245 break;
246
247 case remoting.SignalStrategy.State.FAILED:
248 if (this.state_ == this.State.PRIMARY_PENDING) {
249 window.clearTimeout(this.primaryConnectTimerId_);
250 this.updateProgress_(
251 this.primary_,
252 remoting.FallbackSignalStrategy.Progress.FAILED);
253 this.connectSecondary_();
254 } else {
255 this.updateProgress_(
256 this.primary_,
257 remoting.FallbackSignalStrategy.Progress.FAILED_LATE);
258 }
259 return; // Don't notify the external callback
260
261 case remoting.SignalStrategy.State.CLOSED:
262 this.state_ = this.State.CLOSED;
263 break;
264 }
265
266 this.notifyExternalCallback_(state);
267 };
268
269 /**
270 * @param {remoting.SignalStrategy.State} state
271 * @private
272 */
273 remoting.FallbackSignalStrategy.prototype.onSecondaryStateChanged_ =
274 function(state) {
275 switch (state) {
276 case remoting.SignalStrategy.State.CONNECTED:
277 this.updateProgress_(
278 this.secondary_,
279 remoting.FallbackSignalStrategy.Progress.SUCCEEDED);
280 this.state_ = this.State.SECONDARY_SUCCEEDED;
281 break;
282
283 case remoting.SignalStrategy.State.FAILED:
284 this.updateProgress_(
285 this.secondary_,
286 remoting.FallbackSignalStrategy.Progress.FAILED);
287 this.state_ = this.State.SECONDARY_FAILED;
288 break;
289
290 case remoting.SignalStrategy.State.CLOSED:
291 this.state_ = this.State.CLOSED;
292 break;
293 }
294
295 this.notifyExternalCallback_(state);
296 };
297
298 /**
299 * Notify the external callback of a change in state if it's consistent with
300 * the allowed state transitions (ie, if it represents a later stage in the
301 * connection process). Suppress state transitions that would violate this,
302 * for example a CONNECTING -> NOT_CONNECTED transition when we switch from
303 * the primary to the secondary signal strategy.
304 *
305 * @param {remoting.SignalStrategy.State} state
306 * @private
307 */
308 remoting.FallbackSignalStrategy.prototype.notifyExternalCallback_ =
309 function(state) {
310 if (this.externalState_ === null || state > this.externalState_) {
311 this.externalState_ = state;
312 this.onStateChangedCallback_(state);
313 }
314 };
315
316 /**
317 * @private
318 */
319 remoting.FallbackSignalStrategy.prototype.connectSecondary_ = function() {
320 base.debug.assert(this.state_ == this.State.PRIMARY_PENDING);
321 base.debug.assert(this.server_ != '');
322 base.debug.assert(this.username_ != '');
323 base.debug.assert(this.authToken_ != '');
324
325 this.state_ = this.State.SECONDARY_PENDING;
326 this.primary_.setIncomingStanzaCallback(null);
327 this.secondary_.setIncomingStanzaCallback(this.onIncomingStanzaCallback_);
328 this.secondary_.connect(this.server_, this.username_, this.authToken_);
329 };
330
331 /**
332 * @private
333 */
334 remoting.FallbackSignalStrategy.prototype.onPrimaryTimeout_ = function() {
335 this.updateProgress_(
336 this.primary_,
337 remoting.FallbackSignalStrategy.Progress.TIMED_OUT);
338 this.connectSecondary_();
339 };
340
341 /**
342 * @param {remoting.SignalStrategy} strategy
343 * @param {remoting.FallbackSignalStrategy.Progress} progress
344 * @private
345 */
346 remoting.FallbackSignalStrategy.prototype.updateProgress_ = function(
347 strategy, progress) {
348 console.log('FallbackSignalStrategy progress: ' + strategy.getType() + ' ' +
349 progress);
350 this.connectionSetupResults_.push({
351 'strategyType': strategy.getType(),
352 'progress': progress
353 });
354 if (this.logToServer_) {
355 this.sendConnectionSetupResultsInternal_();
356 }
357 };
OLDNEW
« no previous file with comments | « remoting/webapp/crd/js/error_unittest.js ('k') | remoting/webapp/crd/js/fallback_signal_strategy_unittest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698