Blink roll 178200:178213
[chromium-blink-merge.git] / remoting / webapp / smart_reconnector.js
blob7cc50bfb0257fb4f0a30b5514851a994a00de259
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.
5 /**
6  * @fileoverview
7  * Class handling reconnecting the session when it is disconnected due to
8  * network failure.
9  *
10  * The SmartReconnector listens for changes in connection state of
11  * |clientSession| to determine if a reconnection is needed.  It then calls into
12  * |connector| to reconnect the session.
13  */
15 'use strict';
17 /** @suppress {duplicate} */
18 var remoting = remoting || {};
20 /**
21  * @constructor
22  * @param {remoting.SessionConnector} connector This is used to reconnect the
23  *    the session when necessary
24  * @param {remoting.ClientSession} clientSession This represents the current
25  *    remote desktop connection.  It is used to monitor the changes in
26  *    connection state.
27  * @implements {base.Disposable}
28  */
29 remoting.SmartReconnector = function(connector, clientSession) {
30   /** @private */
31   this.connector_ = connector;
33   /** @private */
34   this.clientSession_ = clientSession;
36   /** @private */
37   this.reconnectTimerId_ = null;
39   /** @private */
40   this.connectionTimeoutTimerId_ = null;
42   /** @private */
43   this.bound_ = {
44     reconnect: this.reconnect_.bind(this),
45     reconnectAsync: this.reconnectAsync_.bind(this),
46     startReconnectTimeout: this.startReconnectTimeout_.bind(this),
47     stateChanged: this.stateChanged_.bind(this),
48     videoChannelStateChanged: this.videoChannelStateChanged_.bind(this)
49   };
51   clientSession.addEventListener(
52       remoting.ClientSession.Events.stateChanged,
53       this.bound_.stateChanged);
54   clientSession.addEventListener(
55       remoting.ClientSession.Events.videoChannelStateChanged,
56       this.bound_.videoChannelStateChanged);
59 // The online event only means the network adapter is enabled, but
60 // it doesn't necessarily mean that we have a working internet connection.
61 // Therefore, delay the connection by |kReconnectDelay| to allow for the network
62 // to connect.
63 remoting.SmartReconnector.kReconnectDelay = 2000;
65 // If the video channel is inactive for 10 seconds reconnect the session.
66 remoting.SmartReconnector.kConnectionTimeout = 10000;
68 remoting.SmartReconnector.prototype = {
69   reconnect_: function() {
70     this.cancelPending_();
71     remoting.disconnect();
72     remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
73     this.connector_.reconnect();
74   },
76   reconnectAsync_: function() {
77     this.cancelPending_();
78     remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
79     this.reconnectTimerId_ = window.setTimeout(
80         this.bound_.reconnect, remoting.SmartReconnector.kReconnectDelay);
81   },
83   /**
84    * @param {remoting.ClientSession.StateEvent} event
85    */
86   stateChanged_: function(event) {
87     var State = remoting.ClientSession.State;
88     if (event.previous === State.CONNECTED && event.current === State.FAILED) {
89       this.cancelPending_();
90       if (navigator.onLine) {
91         this.reconnect_();
92       } else {
93         window.addEventListener('online', this.bound_.reconnectAsync, false);
94       }
95     }
96   },
98   /**
99    * @param {boolean} active  True if the video channel is active.
100    */
101   videoChannelStateChanged_: function (active) {
102     this.cancelPending_();
103     if (!active) {
104       window.addEventListener(
105           'online', this.bound_.startReconnectTimeout, false);
106     }
107   },
109   startReconnectTimeout_: function () {
110     this.cancelPending_();
111     this.connectionTimeoutTimerId_ = window.setTimeout(
112           this.bound_.reconnect, remoting.SmartReconnector.kConnectionTimeout);
113   },
115   cancelPending_: function() {
116     window.removeEventListener(
117         'online', this.bound_.startReconnectTimeout, false);
118     window.removeEventListener('online', this.bound_.reconnectAsync, false);
119     window.clearTimeout(this.reconnectTimerId_);
120     window.clearTimeout(this.connectionTimeoutTimerId_);
121     this.reconnectTimerId_ = null;
122     this.connectionTimeoutTimerId_ = null;
123   },
125   dispose: function() {
126     this.clientSession_.removeEventListener(
127         remoting.ClientSession.Events.stateChanged,
128         this.bound_.stateChanged);
129     this.clientSession_.removeEventListener(
130         remoting.ClientSession.Events.videoChannelStateChanged,
131         this.bound_.videoChannelStateChanged);
132   }