Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / remoting / webapp / crd / js / server_log_entry.js
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.
4
5 /**
6  * @fileoverview
7  * A class of server log entries.
8  */
9
10 'use strict';
11
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
14
15 /**
16  * @private
17  * @constructor
18  */
19 remoting.ServerLogEntry = function() {
20   /** @type Object.<string, string> */ this.dict = {};
21 };
22
23 /** @private */
24 remoting.ServerLogEntry.KEY_EVENT_NAME_ = 'event-name';
25 /** @private */
26 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_STATE_ = 'session-state';
27 /** @private */
28 remoting.ServerLogEntry.KEY_SESSION_ID_ = 'session-id';
29 /** @private */
30 remoting.ServerLogEntry.KEY_ROLE_ = 'role';
31 /** @private */
32 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_ = 'client';
33 /** @private */
34 remoting.ServerLogEntry.KEY_SESSION_STATE_ = 'session-state';
35 /** @private */
36 remoting.ServerLogEntry.KEY_CONNECTION_TYPE_ = 'connection-type';
37
38 /**
39  * @private
40  * @param {remoting.ClientSession.State} state
41  * @return {string}
42  */
43 remoting.ServerLogEntry.getValueForSessionState = function(state) {
44   switch(state) {
45     case remoting.ClientSession.State.UNKNOWN:
46       return 'unknown';
47     case remoting.ClientSession.State.CREATED:
48       return 'created';
49     case remoting.ClientSession.State.CONNECTING:
50       return 'connecting';
51     case remoting.ClientSession.State.INITIALIZING:
52       return 'initializing';
53     case remoting.ClientSession.State.CONNECTED:
54       return 'connected';
55     case remoting.ClientSession.State.CLOSED:
56       return 'closed';
57     case remoting.ClientSession.State.FAILED:
58       return 'connection-failed';
59     case remoting.ClientSession.State.CONNECTION_DROPPED:
60       return 'connection-dropped';
61     case remoting.ClientSession.State.CONNECTION_CANCELED:
62       return 'connection-canceled';
63     default:
64       return 'undefined-' + state;
65   }
66 };
67
68 /** @private */
69 remoting.ServerLogEntry.KEY_CONNECTION_ERROR_ = 'connection-error';
70
71 /**
72  * @private
73  * @param {remoting.Error} connectionError
74  * @return {string}
75  */
76 remoting.ServerLogEntry.getValueForError =
77     function(connectionError) {
78   switch(connectionError) {
79     case remoting.Error.NONE:
80       return 'none';
81     case remoting.Error.INVALID_ACCESS_CODE:
82       return 'invalid-access-code';
83     case remoting.Error.MISSING_PLUGIN:
84       return 'missing_plugin';
85     case remoting.Error.AUTHENTICATION_FAILED:
86       return 'authentication-failed';
87     case remoting.Error.HOST_IS_OFFLINE:
88       return 'host-is-offline';
89     case remoting.Error.INCOMPATIBLE_PROTOCOL:
90       return 'incompatible-protocol';
91     case remoting.Error.BAD_PLUGIN_VERSION:
92       return 'bad-plugin-version';
93     case remoting.Error.NETWORK_FAILURE:
94       return 'network-failure';
95     case remoting.Error.HOST_OVERLOAD:
96       return 'host-overload';
97     case remoting.Error.P2P_FAILURE:
98       return 'p2p-failure';
99     case remoting.Error.UNEXPECTED:
100       return 'unexpected';
101     default:
102       return 'unknown-' + connectionError;
103   }
104 };
105
106 /** @private */
107 remoting.ServerLogEntry.KEY_SESSION_DURATION_ = 'session-duration';
108
109 /** @private */
110 remoting.ServerLogEntry.VALUE_EVENT_NAME_CONNECTION_STATISTICS_ =
111     "connection-statistics";
112 /** @private */
113 remoting.ServerLogEntry.KEY_VIDEO_BANDWIDTH_ = "video-bandwidth";
114 /** @private */
115 remoting.ServerLogEntry.KEY_CAPTURE_LATENCY_ = "capture-latency";
116 /** @private */
117 remoting.ServerLogEntry.KEY_ENCODE_LATENCY_ = "encode-latency";
118 /** @private */
119 remoting.ServerLogEntry.KEY_DECODE_LATENCY_ = "decode-latency";
120 /** @private */
121 remoting.ServerLogEntry.KEY_RENDER_LATENCY_ = "render-latency";
122 /** @private */
123 remoting.ServerLogEntry.KEY_ROUNDTRIP_LATENCY_ = "roundtrip-latency";
124
125 /** @private */
126 remoting.ServerLogEntry.KEY_OS_NAME_ = 'os-name';
127 /** @private */
128 remoting.ServerLogEntry.VALUE_OS_NAME_WINDOWS_ = 'Windows';
129 /** @private */
130 remoting.ServerLogEntry.VALUE_OS_NAME_LINUX_ = 'Linux';
131 /** @private */
132 remoting.ServerLogEntry.VALUE_OS_NAME_MAC_ = 'Mac';
133 /** @private */
134 remoting.ServerLogEntry.VALUE_OS_NAME_CHROMEOS_ = 'ChromeOS';
135
136 /** @private */
137 remoting.ServerLogEntry.KEY_OS_VERSION_ = 'os-version';
138
139 /** @private */
140 remoting.ServerLogEntry.KEY_CPU_ = 'cpu';
141
142 /** @private */
143 remoting.ServerLogEntry.KEY_BROWSER_VERSION_ = 'browser-version';
144
145 /** @private */
146 remoting.ServerLogEntry.KEY_WEBAPP_VERSION_ = 'webapp-version';
147
148 /** @private */
149 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_OLD_ = 'session-id-old';
150
151 /** @private */
152 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_NEW_ = 'session-id-new';
153
154 /** @private */
155 remoting.ServerLogEntry.KEY_MODE_ = 'mode';
156 /** @private */
157 remoting.ServerLogEntry.VALUE_MODE_IT2ME_ = 'it2me';
158 /** @private */
159 remoting.ServerLogEntry.VALUE_MODE_ME2ME_ = 'me2me';
160 /** @private */
161 remoting.ServerLogEntry.VALUE_MODE_UNKNOWN_ = 'unknown';
162
163 /**
164  * Sets one field in this log entry.
165  *
166  * @private
167  * @param {string} key
168  * @param {string} value
169  */
170 remoting.ServerLogEntry.prototype.set = function(key, value) {
171   this.dict[key] = value;
172 };
173
174 /**
175  * Converts this object into an XML stanza.
176  *
177  * @return {string}
178  */
179 remoting.ServerLogEntry.prototype.toStanza = function() {
180   var stanza = '<gr:entry ';
181   for (var key in this.dict) {
182     stanza += escape(key) + '="' + escape(this.dict[key]) + '" ';
183   }
184   stanza += '/>';
185   return stanza;
186 };
187
188 /**
189  * Prints this object on the debug log.
190  *
191  * @param {number} indentLevel the indentation level
192  */
193 remoting.ServerLogEntry.prototype.toDebugLog = function(indentLevel) {
194   /** @type Array.<string> */ var fields = [];
195   for (var key in this.dict) {
196     fields.push(key + ': ' + this.dict[key]);
197   }
198   console.log(Array(indentLevel+1).join("  ") + fields.join(', '));
199 };
200
201 /**
202  * Makes a log entry for a change of client session state.
203  *
204  * @param {remoting.ClientSession.State} state
205  * @param {remoting.Error} connectionError
206  * @param {remoting.ClientSession.Mode} mode
207  * @return {remoting.ServerLogEntry}
208  */
209 remoting.ServerLogEntry.makeClientSessionStateChange = function(state,
210     connectionError, mode) {
211   var entry = new remoting.ServerLogEntry();
212   entry.set(remoting.ServerLogEntry.KEY_ROLE_,
213             remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
214   entry.set(remoting.ServerLogEntry.KEY_EVENT_NAME_,
215             remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_STATE_);
216   entry.set(remoting.ServerLogEntry.KEY_SESSION_STATE_,
217             remoting.ServerLogEntry.getValueForSessionState(state));
218   if (connectionError != remoting.Error.NONE) {
219     entry.set(remoting.ServerLogEntry.KEY_CONNECTION_ERROR_,
220               remoting.ServerLogEntry.getValueForError(connectionError));
221   }
222   entry.addModeField(mode);
223   return entry;
224 };
225
226 /**
227  * Adds a session duration to a log entry.
228  *
229  * @param {number} sessionDuration
230  */
231 remoting.ServerLogEntry.prototype.addSessionDurationField = function(
232     sessionDuration) {
233   this.set(remoting.ServerLogEntry.KEY_SESSION_DURATION_,
234       sessionDuration.toString());
235 };
236
237 /**
238  * Makes a log entry for a set of connection statistics.
239  * Returns null if all the statistics were zero.
240  *
241  * @param {remoting.StatsAccumulator} statsAccumulator
242  * @param {string} connectionType
243  * @param {remoting.ClientSession.Mode} mode
244  * @return {?remoting.ServerLogEntry}
245  */
246 remoting.ServerLogEntry.makeStats = function(statsAccumulator,
247                                              connectionType,
248                                              mode) {
249   var entry = new remoting.ServerLogEntry();
250   entry.set(remoting.ServerLogEntry.KEY_ROLE_,
251             remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
252   entry.set(remoting.ServerLogEntry.KEY_EVENT_NAME_,
253             remoting.ServerLogEntry.VALUE_EVENT_NAME_CONNECTION_STATISTICS_);
254   if (connectionType) {
255     entry.set(remoting.ServerLogEntry.KEY_CONNECTION_TYPE_,
256               connectionType);
257   }
258   entry.addModeField(mode);
259   var nonZero = false;
260   nonZero |= entry.addStatsField(
261       remoting.ServerLogEntry.KEY_VIDEO_BANDWIDTH_,
262       remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH, statsAccumulator);
263   nonZero |= entry.addStatsField(
264       remoting.ServerLogEntry.KEY_CAPTURE_LATENCY_,
265       remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY, statsAccumulator);
266   nonZero |= entry.addStatsField(
267       remoting.ServerLogEntry.KEY_ENCODE_LATENCY_,
268       remoting.ClientSession.STATS_KEY_ENCODE_LATENCY, statsAccumulator);
269   nonZero |= entry.addStatsField(
270       remoting.ServerLogEntry.KEY_DECODE_LATENCY_,
271       remoting.ClientSession.STATS_KEY_DECODE_LATENCY, statsAccumulator);
272   nonZero |= entry.addStatsField(
273       remoting.ServerLogEntry.KEY_RENDER_LATENCY_,
274       remoting.ClientSession.STATS_KEY_RENDER_LATENCY, statsAccumulator);
275   nonZero |= entry.addStatsField(
276       remoting.ServerLogEntry.KEY_ROUNDTRIP_LATENCY_,
277       remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY, statsAccumulator);
278   if (nonZero) {
279     return entry;
280   }
281   return null;
282 };
283
284 /**
285  * Adds one connection statistic to a log entry.
286  *
287  * @private
288  * @param {string} entryKey
289  * @param {string} statsKey
290  * @param {remoting.StatsAccumulator} statsAccumulator
291  * @return {boolean} whether the statistic is non-zero
292  */
293 remoting.ServerLogEntry.prototype.addStatsField = function(
294     entryKey, statsKey, statsAccumulator) {
295   var val = statsAccumulator.calcMean(statsKey);
296   this.set(entryKey, val.toFixed(2));
297   return (val != 0);
298 };
299
300 /**
301  * Makes a log entry for a "this session ID is old" event.
302  *
303  * @param {string} sessionId
304  * @param {remoting.ClientSession.Mode} mode
305  * @return {remoting.ServerLogEntry}
306  */
307 remoting.ServerLogEntry.makeSessionIdOld = function(sessionId, mode) {
308   var entry = new remoting.ServerLogEntry();
309   entry.set(remoting.ServerLogEntry.KEY_ROLE_,
310             remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
311   entry.set(remoting.ServerLogEntry.KEY_EVENT_NAME_,
312             remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_OLD_);
313   entry.addSessionIdField(sessionId);
314   entry.addModeField(mode);
315   return entry;
316 };
317
318 /**
319  * Makes a log entry for a "this session ID is new" event.
320  *
321  * @param {string} sessionId
322  * @param {remoting.ClientSession.Mode} mode
323  * @return {remoting.ServerLogEntry}
324  */
325 remoting.ServerLogEntry.makeSessionIdNew = function(sessionId, mode) {
326   var entry = new remoting.ServerLogEntry();
327   entry.set(remoting.ServerLogEntry.KEY_ROLE_,
328             remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
329   entry.set(remoting.ServerLogEntry.KEY_EVENT_NAME_,
330             remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_NEW_);
331   entry.addSessionIdField(sessionId);
332   entry.addModeField(mode);
333   return entry;
334 };
335
336 /**
337  * Adds a session ID field to this log entry.
338  *
339  * @param {string} sessionId
340  */
341 remoting.ServerLogEntry.prototype.addSessionIdField = function(sessionId) {
342   this.set(remoting.ServerLogEntry.KEY_SESSION_ID_, sessionId);
343 }
344
345 /**
346  * Adds fields describing the host to this log entry.
347  */
348 remoting.ServerLogEntry.prototype.addHostFields = function() {
349   var host = remoting.ServerLogEntry.getHostData();
350   if (host) {
351     if (host.os_name.length > 0) {
352       this.set(remoting.ServerLogEntry.KEY_OS_NAME_, host.os_name);
353     }
354     if (host.os_version.length > 0) {
355       this.set(remoting.ServerLogEntry.KEY_OS_VERSION_, host.os_version);
356     }
357     if (host.cpu.length > 0) {
358       this.set(remoting.ServerLogEntry.KEY_CPU_, host.cpu);
359     }
360   }
361 };
362
363 /**
364  * Extracts host data from the userAgent string.
365  *
366  * @private
367  * @return {{os_name:string, os_version:string, cpu:string} | null}
368  */
369 remoting.ServerLogEntry.getHostData = function() {
370   return remoting.ServerLogEntry.extractHostDataFrom(navigator.userAgent);
371 };
372
373 /**
374  * Extracts host data from the given userAgent string.
375  *
376  * @private
377  * @param {string} s
378  * @return {{os_name:string, os_version:string, cpu:string} | null}
379  */
380 remoting.ServerLogEntry.extractHostDataFrom = function(s) {
381   // Sample userAgent strings:
382   // 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 ' +
383   //   '(KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2'
384   // 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.8 ' +
385   //   '(KHTML, like Gecko) Chrome/17.0.933.0 Safari/535.8'
386   // 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 ' +
387   //   '(KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1'
388   // 'Mozilla/5.0 (X11; CrOS i686 14.811.154) AppleWebKit/535.1 ' +
389   //   '(KHTML, like Gecko) Chrome/14.0.835.204 Safari/535.1'
390   var match = new RegExp('Windows NT ([0-9\\.]*)').exec(s);
391   if (match && (match.length >= 2)) {
392     return {
393         'os_name': remoting.ServerLogEntry.VALUE_OS_NAME_WINDOWS_,
394         'os_version': match[1],
395         'cpu': ''
396     };
397   }
398   match = new RegExp('Linux ([a-zA-Z0-9_]*)').exec(s);
399   if (match && (match.length >= 2)) {
400     return {
401         'os_name': remoting.ServerLogEntry.VALUE_OS_NAME_LINUX_,
402         'os_version' : '',
403         'cpu': match[1]
404     };
405   }
406   match = new RegExp('([a-zA-Z]*) Mac OS X ([0-9_]*)').exec(s);
407   if (match && (match.length >= 3)) {
408     return {
409         'os_name': remoting.ServerLogEntry.VALUE_OS_NAME_MAC_,
410         'os_version': match[2].replace(/_/g, '.'),
411         'cpu': match[1]
412     };
413   }
414   match = new RegExp('CrOS ([a-zA-Z0-9]*) ([0-9.]*)').exec(s);
415   if (match && (match.length >= 3)) {
416     return {
417         'os_name': remoting.ServerLogEntry.VALUE_OS_NAME_CHROMEOS_,
418         'os_version': match[2],
419         'cpu': match[1]
420     };
421   }
422   return null;
423 };
424
425 /**
426  * Adds a field specifying the browser version to this log entry.
427  */
428 remoting.ServerLogEntry.prototype.addChromeVersionField = function() {
429   var version = remoting.getChromeVersion();
430   if (version != null) {
431     this.set(remoting.ServerLogEntry.KEY_BROWSER_VERSION_, version);
432   }
433 };
434
435 /**
436  * Adds a field specifying the webapp version to this log entry.
437  */
438 remoting.ServerLogEntry.prototype.addWebappVersionField = function() {
439   var manifest = chrome.runtime.getManifest();
440   if (manifest && manifest.version) {
441     this.set(remoting.ServerLogEntry.KEY_WEBAPP_VERSION_, manifest.version);
442   }
443 };
444
445 /**
446  * Adds a field specifying the mode to this log entry.
447  *
448  * @param {remoting.ClientSession.Mode} mode
449  */
450 remoting.ServerLogEntry.prototype.addModeField = function(mode) {
451   this.set(remoting.ServerLogEntry.KEY_MODE_,
452       remoting.ServerLogEntry.getModeField(mode));
453 };
454
455 /**
456  * Gets the value of the mode field to be put in a log entry.
457  *
458  * @private
459  * @param {remoting.ClientSession.Mode} mode
460  * @return {string}
461  */
462 remoting.ServerLogEntry.getModeField = function(mode) {
463   switch(mode) {
464     case remoting.ClientSession.Mode.IT2ME:
465       return remoting.ServerLogEntry.VALUE_MODE_IT2ME_;
466     case remoting.ClientSession.Mode.ME2ME:
467       return remoting.ServerLogEntry.VALUE_MODE_ME2ME_;
468     default:
469       return remoting.ServerLogEntry.VALUE_MODE_UNKNOWN_;
470   }
471 };