Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / remoting / webapp / crd / js / log_to_server.js
blob8b87f1b5c4efc7273b3cb4ce5f43f36ae5926294
1 // Copyright (c) 2012 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  * Module for sending log entries to the server.
8  */
10 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16  * @param {remoting.SignalStrategy} signalStrategy Signal strategy.
17  * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection.
18  * @constructor
19  */
20 remoting.LogToServer = function(signalStrategy, mode) {
21   /** @private */
22   this.statsAccumulator_ = new remoting.StatsAccumulator();
23   /** @private */
24   this.sessionId_ = '';
25   /** @private */
26   this.sessionIdGenerationTime_ = 0;
27   /** @private */
28   this.sessionStartTime_ = 0;
29   /** @private */
30   this.signalStrategy_ = signalStrategy;
31   /** @private */
32   this.mode_ = mode;
33   /** @type {string} @private */
34   this.connectionType_ = '';
36   this.setSessionId_();
37   signalStrategy.sendConnectionSetupResults(this);
40 // Constants used for generating a session ID.
41 /** @private */
42 remoting.LogToServer.SESSION_ID_ALPHABET_ =
43     'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
44 /** @private */
45 remoting.LogToServer.SESSION_ID_LEN_ = 20;
47 // The maximum age of a session ID, in milliseconds.
48 remoting.LogToServer.MAX_SESSION_ID_AGE = 24 * 60 * 60 * 1000;
50 // The time over which to accumulate connection statistics before logging them
51 // to the server, in milliseconds.
52 remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME = 60 * 1000;
54 /**
55  * Logs a client session state change.
56  *
57  * @param {remoting.ClientSession.State} state
58  * @param {remoting.Error} connectionError
59  */
60 remoting.LogToServer.prototype.logClientSessionStateChange =
61     function(state, connectionError) {
62   this.maybeExpireSessionId_();
63   // Set the session start time if we haven't done so already.
64   if (remoting.LogToServer.isStartOfSession_(state)) {
65     if (this.sessionStartTime_ == 0) {
66       this.sessionStartTime_ = new Date().getTime();
67     }
68   }
69   // Log the session state change.
70   var entry = remoting.ServerLogEntry.makeClientSessionStateChange(
71       state, connectionError, this.mode_);
72   entry.addHostFields();
73   entry.addChromeVersionField();
74   entry.addWebappVersionField();
75   entry.addSessionIdField(this.sessionId_);
76   // Maybe clear the session start time, and log the session duration.
77   if (remoting.LogToServer.shouldAddDuration_(state) &&
78       (this.sessionStartTime_ != 0)) {
79     entry.addSessionDurationField(
80         (new Date().getTime() - this.sessionStartTime_) / 1000.0);
81     if (remoting.LogToServer.isEndOfSession_(state)) {
82       this.sessionStartTime_ = 0;
83     }
84   }
85   this.log_(entry);
86   // Don't accumulate connection statistics across state changes.
87   this.logAccumulatedStatistics_();
88   this.statsAccumulator_.empty();
89   // Maybe clear the session ID.
90   if (remoting.LogToServer.isEndOfSession_(state)) {
91     this.clearSessionId_();
92   }
95 /**
96  * Set the connection type (direct, stun relay).
97  *
98  * @param {string} connectionType
99  */
100 remoting.LogToServer.prototype.setConnectionType = function(connectionType) {
101   this.connectionType_ = connectionType;
105  * @param {remoting.SignalStrategy.Type} strategyType
106  * @param {remoting.FallbackSignalStrategy.Progress} progress
107  * @param {number} elapsedTimeInMs
108  */
109 remoting.LogToServer.prototype.logSignalStrategyProgress =
110     function(strategyType, progress, elapsedTimeInMs) {
111   this.maybeExpireSessionId_();
112   var entry = remoting.ServerLogEntry.makeSignalStrategyProgress(
113       this.sessionId_, strategyType, progress, elapsedTimeInMs);
114   this.log_(entry);
118  * Whether a session state is one of the states that occurs at the start of
119  * a session.
121  * @private
122  * @param {remoting.ClientSession.State} state
123  * @return {boolean}
124  */
125 remoting.LogToServer.isStartOfSession_ = function(state) {
126   return ((state == remoting.ClientSession.State.CONNECTING) ||
127       (state == remoting.ClientSession.State.INITIALIZING) ||
128       (state == remoting.ClientSession.State.CONNECTED));
132  * Whether a session state is one of the states that occurs at the end of
133  * a session.
135  * @private
136  * @param {remoting.ClientSession.State} state
137  * @return {boolean}
138  */
139 remoting.LogToServer.isEndOfSession_ = function(state) {
140   return ((state == remoting.ClientSession.State.CLOSED) ||
141       (state == remoting.ClientSession.State.FAILED) ||
142       (state == remoting.ClientSession.State.CONNECTION_DROPPED) ||
143       (state == remoting.ClientSession.State.CONNECTION_CANCELED));
147  * Whether the duration should be added to the log entry for this state.
149  * @private
150  * @param {remoting.ClientSession.State} state
151  * @return {boolean}
152  */
153 remoting.LogToServer.shouldAddDuration_ = function(state) {
154   // Duration is added to log entries at the end of the session, as well as at
155   // some intermediate states where it is relevant (e.g. to determine how long
156   // it took for a session to become CONNECTED).
157   return (remoting.LogToServer.isEndOfSession_(state) ||
158       (state == remoting.ClientSession.State.CONNECTED));
162  * Logs connection statistics.
163  * @param {Object<string, number>} stats The connection statistics
164  */
165 remoting.LogToServer.prototype.logStatistics = function(stats) {
166   this.maybeExpireSessionId_();
167   // Store the statistics.
168   this.statsAccumulator_.add(stats);
169   // Send statistics to the server if they've been accumulating for at least
170   // 60 seconds.
171   if (this.statsAccumulator_.getTimeSinceFirstValue() >=
172       remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME) {
173     this.logAccumulatedStatistics_();
174   }
178  * Moves connection statistics from the accumulator to the log server.
180  * If all the statistics are zero, then the accumulator is still emptied,
181  * but the statistics are not sent to the log server.
183  * @private
184  */
185 remoting.LogToServer.prototype.logAccumulatedStatistics_ = function() {
186   var entry = remoting.ServerLogEntry.makeStats(this.statsAccumulator_,
187                                                 this.connectionType_,
188                                                 this.mode_);
189   if (entry) {
190     entry.addHostFields();
191     entry.addChromeVersionField();
192     entry.addWebappVersionField();
193     entry.addSessionIdField(this.sessionId_);
194     this.log_(entry);
195   }
196   this.statsAccumulator_.empty();
200  * Sends a log entry to the server.
202  * @private
203  * @param {remoting.ServerLogEntry} entry
204  */
205 remoting.LogToServer.prototype.log_ = function(entry) {
206   // Send the stanza to the debug log.
207   console.log('Enqueueing log entry:');
208   entry.toDebugLog(1);
210   var stanza = '<cli:iq to="' + remoting.settings.DIRECTORY_BOT_JID + '" ' +
211                        'type="set" xmlns:cli="jabber:client">' +
212                  '<gr:log xmlns:gr="google:remoting">' +
213                    entry.toStanza() +
214                  '</gr:log>' +
215                '</cli:iq>';
216   this.signalStrategy_.sendMessage(stanza);
220  * Sets the session ID to a random string.
222  * @private
223  */
224 remoting.LogToServer.prototype.setSessionId_ = function() {
225   this.sessionId_ = remoting.LogToServer.generateSessionId_();
226   this.sessionIdGenerationTime_ = new Date().getTime();
230  * Clears the session ID.
232  * @private
233  */
234 remoting.LogToServer.prototype.clearSessionId_ = function() {
235   this.sessionId_ = '';
236   this.sessionIdGenerationTime_ = 0;
240  * Sets a new session ID, if the current session ID has reached its maximum age.
242  * This method also logs the old and new session IDs to the server, in separate
243  * log entries.
245  * @private
246  */
247 remoting.LogToServer.prototype.maybeExpireSessionId_ = function() {
248   if ((this.sessionId_ != '') &&
249       (new Date().getTime() - this.sessionIdGenerationTime_ >=
250       remoting.LogToServer.MAX_SESSION_ID_AGE)) {
251     // Log the old session ID.
252     var entry = remoting.ServerLogEntry.makeSessionIdOld(this.sessionId_,
253                                                          this.mode_);
254     this.log_(entry);
255     // Generate a new session ID.
256     this.setSessionId_();
257     // Log the new session ID.
258     entry = remoting.ServerLogEntry.makeSessionIdNew(this.sessionId_,
259                                                      this.mode_);
260     this.log_(entry);
261   }
265  * Generates a string that can be used as a session ID.
267  * @private
268  * @return {string} a session ID
269  */
270 remoting.LogToServer.generateSessionId_ = function() {
271   var idArray = [];
272   for (var i = 0; i < remoting.LogToServer.SESSION_ID_LEN_; i++) {
273     var index =
274         Math.random() * remoting.LogToServer.SESSION_ID_ALPHABET_.length;
275     idArray.push(
276         remoting.LogToServer.SESSION_ID_ALPHABET_.slice(index, index + 1));
277   }
278   return idArray.join('');