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