| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 log_util = (function() { | 5 log_util = (function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Creates a new log dump. |events| is a list of all events, |polledData| is | 9 * Creates a new log dump. |events| is a list of all events, |polledData| is |
| 10 * an object containing the results of each poll, |tabData| is an object | 10 * an object containing the results of each poll, |tabData| is an object |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * |constants| needed to interpret the data. This also includes some | 24 * |constants| needed to interpret the data. This also includes some |
| 25 * browser state information. | 25 * browser state information. |
| 26 * |events| from the NetLog. | 26 * |events| from the NetLog. |
| 27 * |polledData| from each PollableDataHelper available on the source OS. | 27 * |polledData| from each PollableDataHelper available on the source OS. |
| 28 * |tabData| containing any tab-specific state that's not present in | 28 * |tabData| containing any tab-specific state that's not present in |
| 29 * |polledData|. | 29 * |polledData|. |
| 30 * | 30 * |
| 31 * |polledData| and |tabData| may be empty objects, or may be missing data for | 31 * |polledData| and |tabData| may be empty objects, or may be missing data for |
| 32 * tabs not present on the OS the log is from. | 32 * tabs not present on the OS the log is from. |
| 33 */ | 33 */ |
| 34 function createLogDump(userComments, constants, events, polledData, tabData, | 34 function createLogDump( |
| 35 numericDate, privacyStripping) { | 35 userComments, constants, events, polledData, tabData, numericDate, |
| 36 privacyStripping) { |
| 36 if (privacyStripping) | 37 if (privacyStripping) |
| 37 events = events.map(stripPrivacyInfo); | 38 events = events.map(stripPrivacyInfo); |
| 38 | 39 |
| 39 var logDump = { | 40 var logDump = { |
| 40 'userComments': userComments, | 41 'userComments': userComments, |
| 41 'constants': constants, | 42 'constants': constants, |
| 42 'events': events, | 43 'events': events, |
| 43 'polledData': polledData, | 44 'polledData': polledData, |
| 44 'tabData': tabData | 45 'tabData': tabData |
| 45 }; | 46 }; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 57 * |oldLogDump|. The other parts of the log dump come from current | 58 * |oldLogDump|. The other parts of the log dump come from current |
| 58 * net-internals state. | 59 * net-internals state. |
| 59 */ | 60 */ |
| 60 function createUpdatedLogDump(userComments, oldLogDump, privacyStripping) { | 61 function createUpdatedLogDump(userComments, oldLogDump, privacyStripping) { |
| 61 var numericDate = null; | 62 var numericDate = null; |
| 62 if (oldLogDump.constants.clientInfo && | 63 if (oldLogDump.constants.clientInfo && |
| 63 oldLogDump.constants.clientInfo.numericDate) { | 64 oldLogDump.constants.clientInfo.numericDate) { |
| 64 numericDate = oldLogDump.constants.clientInfo.numericDate; | 65 numericDate = oldLogDump.constants.clientInfo.numericDate; |
| 65 } | 66 } |
| 66 var logDump = createLogDump( | 67 var logDump = createLogDump( |
| 67 userComments, | 68 userComments, Constants, |
| 68 Constants, | |
| 69 EventsTracker.getInstance().getAllCapturedEvents(), | 69 EventsTracker.getInstance().getAllCapturedEvents(), |
| 70 oldLogDump.polledData, | 70 oldLogDump.polledData, getTabData_(), numericDate, privacyStripping); |
| 71 getTabData_(), | |
| 72 numericDate, | |
| 73 privacyStripping); | |
| 74 return JSON.stringify(logDump); | 71 return JSON.stringify(logDump); |
| 75 } | 72 } |
| 76 | 73 |
| 77 /** | 74 /** |
| 78 * Creates a full log dump using |polledData| and the return value of each | 75 * Creates a full log dump using |polledData| and the return value of each |
| 79 * tab's saveState function and passes it to |callback|. | 76 * tab's saveState function and passes it to |callback|. |
| 80 */ | 77 */ |
| 81 function onUpdateAllCompleted(userComments, callback, privacyStripping, | 78 function onUpdateAllCompleted( |
| 82 polledData) { | 79 userComments, callback, privacyStripping, polledData) { |
| 83 var logDump = createLogDump( | 80 var logDump = createLogDump( |
| 84 userComments, | 81 userComments, Constants, |
| 85 Constants, | 82 EventsTracker.getInstance().getAllCapturedEvents(), polledData, |
| 86 EventsTracker.getInstance().getAllCapturedEvents(), | 83 getTabData_(), timeutil.getCurrentTime(), privacyStripping); |
| 87 polledData, | |
| 88 getTabData_(), | |
| 89 timeutil.getCurrentTime(), | |
| 90 privacyStripping); | |
| 91 callback(JSON.stringify(logDump)); | 84 callback(JSON.stringify(logDump)); |
| 92 } | 85 } |
| 93 | 86 |
| 94 /** | 87 /** |
| 95 * Called to create a new log dump. Must not be called once a dump has been | 88 * Called to create a new log dump. Must not be called once a dump has been |
| 96 * loaded. Once a log dump has been created, |callback| is passed the dumped | 89 * loaded. Once a log dump has been created, |callback| is passed the dumped |
| 97 * text as a string. | 90 * text as a string. |
| 98 */ | 91 */ |
| 99 function createLogDumpAsync(userComments, callback, privacyStripping) { | 92 function createLogDumpAsync(userComments, callback, privacyStripping) { |
| 100 g_browser.updateAllInfo( | 93 g_browser.updateAllInfo(onUpdateAllCompleted.bind( |
| 101 onUpdateAllCompleted.bind(null, userComments, callback, | 94 null, userComments, callback, privacyStripping)); |
| 102 privacyStripping)); | |
| 103 } | 95 } |
| 104 | 96 |
| 105 /** | 97 /** |
| 106 * Gather any tab-specific state information prior to creating a log dump. | 98 * Gather any tab-specific state information prior to creating a log dump. |
| 107 */ | 99 */ |
| 108 function getTabData_() { | 100 function getTabData_() { |
| 109 var tabData = {}; | 101 var tabData = {}; |
| 110 var tabSwitcher = MainView.getInstance().tabSwitcher(); | 102 var tabSwitcher = MainView.getInstance().tabSwitcher(); |
| 111 var tabIdToView = tabSwitcher.getAllTabViews(); | 103 var tabIdToView = tabSwitcher.getAllTabViews(); |
| 112 for (var tabId in tabIdToView) { | 104 for (var tabId in tabIdToView) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 if (errorString.length > 0) | 148 if (errorString.length > 0) |
| 157 return 'Load failed:\n\n' + errorString; | 149 return 'Load failed:\n\n' + errorString; |
| 158 | 150 |
| 159 if (typeof(logDump.polledData) != 'object') | 151 if (typeof(logDump.polledData) != 'object') |
| 160 logDump.polledData = {}; | 152 logDump.polledData = {}; |
| 161 if (typeof(logDump.tabData) != 'object') | 153 if (typeof(logDump.tabData) != 'object') |
| 162 logDump.tabData = {}; | 154 logDump.tabData = {}; |
| 163 | 155 |
| 164 if (logDump.constants.logFormatVersion != Constants.logFormatVersion) { | 156 if (logDump.constants.logFormatVersion != Constants.logFormatVersion) { |
| 165 return 'Unable to load different log version.' + | 157 return 'Unable to load different log version.' + |
| 166 ' Found ' + logDump.constants.logFormatVersion + | 158 ' Found ' + logDump.constants.logFormatVersion + ', Expected ' + |
| 167 ', Expected ' + Constants.logFormatVersion; | 159 Constants.logFormatVersion; |
| 168 } | 160 } |
| 169 | 161 |
| 170 g_browser.receivedConstants(logDump.constants); | 162 g_browser.receivedConstants(logDump.constants); |
| 171 | 163 |
| 172 // Check for validity of each log entry, and then add the ones that pass. | 164 // Check for validity of each log entry, and then add the ones that pass. |
| 173 // Since the events are kept around, and we can't just hide a single view | 165 // Since the events are kept around, and we can't just hide a single view |
| 174 // on a bad event, we have more error checking for them than other data. | 166 // on a bad event, we have more error checking for them than other data. |
| 175 var validEvents = []; | 167 var validEvents = []; |
| 176 var numDeprecatedPassiveEvents = 0; | 168 var numDeprecatedPassiveEvents = 0; |
| 177 for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) { | 169 for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) { |
| 178 var event = logDump.events[eventIndex]; | 170 var event = logDump.events[eventIndex]; |
| 179 if (typeof event == 'object' && | 171 if (typeof event == 'object' && typeof event.source == 'object' && |
| 180 typeof event.source == 'object' && | |
| 181 typeof event.time == 'string' && | 172 typeof event.time == 'string' && |
| 182 typeof EventTypeNames[event.type] == 'string' && | 173 typeof EventTypeNames[event.type] == 'string' && |
| 183 typeof EventSourceTypeNames[event.source.type] == 'string' && | 174 typeof EventSourceTypeNames[event.source.type] == 'string' && |
| 184 getKeyWithValue(EventPhase, event.phase) != '?') { | 175 getKeyWithValue(EventPhase, event.phase) != '?') { |
| 185 if (event.wasPassivelyCaptured) { | 176 if (event.wasPassivelyCaptured) { |
| 186 // NOTE: Up until Chrome 18, log dumps included "passively captured" | 177 // NOTE: Up until Chrome 18, log dumps included "passively captured" |
| 187 // events. These are no longer supported, so skip past them | 178 // events. These are no longer supported, so skip past them |
| 188 // to avoid confusing the rest of the code. | 179 // to avoid confusing the rest of the code. |
| 189 numDeprecatedPassiveEvents++; | 180 numDeprecatedPassiveEvents++; |
| 190 continue; | 181 continue; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 for (var tabId in tabIdToView) { | 217 for (var tabId in tabIdToView) { |
| 227 var view = tabIdToView[tabId]; | 218 var view = tabIdToView[tabId]; |
| 228 view.onLoadLogStart(logDump.polledData, logDump.tabData[tabId]); | 219 view.onLoadLogStart(logDump.polledData, logDump.tabData[tabId]); |
| 229 } | 220 } |
| 230 EventsTracker.getInstance().addLogEntries(validEvents); | 221 EventsTracker.getInstance().addLogEntries(validEvents); |
| 231 | 222 |
| 232 var numInvalidEvents = logDump.events.length - | 223 var numInvalidEvents = logDump.events.length - |
| 233 (validEvents.length + numDeprecatedPassiveEvents); | 224 (validEvents.length + numDeprecatedPassiveEvents); |
| 234 if (numInvalidEvents > 0) { | 225 if (numInvalidEvents > 0) { |
| 235 errorString += 'Unable to load ' + numInvalidEvents + | 226 errorString += 'Unable to load ' + numInvalidEvents + |
| 236 ' events, due to invalid data.\n\n'; | 227 ' events, due to invalid data.\n\n'; |
| 237 } | 228 } |
| 238 | 229 |
| 239 if (numDeprecatedPassiveEvents > 0) { | 230 if (numDeprecatedPassiveEvents > 0) { |
| 240 errorString += 'Discarded ' + numDeprecatedPassiveEvents + | 231 errorString += 'Discarded ' + numDeprecatedPassiveEvents + |
| 241 ' passively collected events. Use an older version of Chrome to' + | 232 ' passively collected events. Use an older version of Chrome to' + |
| 242 ' load this dump if you want to see them.\n\n'; | 233 ' load this dump if you want to see them.\n\n'; |
| 243 } | 234 } |
| 244 | 235 |
| 245 // Update all views with data from the file. Show only those views which | 236 // Update all views with data from the file. Show only those views which |
| 246 // successfully load the data. | 237 // successfully load the data. |
| 247 for (var tabId in tabIdToView) { | 238 for (var tabId in tabIdToView) { |
| 248 var view = tabIdToView[tabId]; | 239 var view = tabIdToView[tabId]; |
| 249 var showView = false; | 240 var showView = false; |
| 250 // The try block eliminates the need for checking every single value | 241 // The try block eliminates the need for checking every single value |
| 251 // before trying to access it. | 242 // before trying to access it. |
| 252 try { | 243 try { |
| 253 if (view.onLoadLogFinish(logDump.polledData, | 244 if (view.onLoadLogFinish( |
| 254 logDump.tabData[tabId], | 245 logDump.polledData, logDump.tabData[tabId], logDump)) { |
| 255 logDump)) { | |
| 256 showView = true; | 246 showView = true; |
| 257 } | 247 } |
| 258 } catch (error) { | 248 } catch (error) { |
| 259 errorString += 'Caught error while calling onLoadLogFinish: ' + | 249 errorString += |
| 260 error + '\n\n'; | 250 'Caught error while calling onLoadLogFinish: ' + error + '\n\n'; |
| 261 } | 251 } |
| 262 tabSwitcher.showTabLink(tabId, showView); | 252 tabSwitcher.showTabLink(tabId, showView); |
| 263 } | 253 } |
| 264 | 254 |
| 265 return errorString + 'Log loaded.'; | 255 return errorString + 'Log loaded.'; |
| 266 } | 256 } |
| 267 | 257 |
| 268 /** | 258 /** |
| 269 * Loads a log dump from the string |logFileContents|, which can be either a | 259 * Loads a log dump from the string |logFileContents|, which can be either a |
| 270 * full net-internals dump, or a NetLog dump only. Returns a string | 260 * full net-internals dump, or a NetLog dump only. Returns a string |
| 271 * containing a log of the load. | 261 * containing a log of the load. |
| 272 */ | 262 */ |
| 273 function loadLogFile(logFileContents, fileName) { | 263 function loadLogFile(logFileContents, fileName) { |
| 274 // Try and parse the log dump as a single JSON string. If this succeeds, | 264 // Try and parse the log dump as a single JSON string. If this succeeds, |
| 275 // it's most likely a full log dump. Otherwise, it may be a dump created by | 265 // it's most likely a full log dump. Otherwise, it may be a dump created by |
| 276 // --log-net-log. | 266 // --log-net-log. |
| 277 var parsedDump = null; | 267 var parsedDump = null; |
| 278 var errorString = ''; | 268 var errorString = ''; |
| 279 try { | 269 try { |
| 280 parsedDump = JSON.parse(logFileContents); | 270 parsedDump = JSON.parse(logFileContents); |
| 281 } catch (error) { | 271 } catch (error) { |
| 282 try { | 272 try { |
| 283 // We may have a --log-net-log=blah log dump. If so, remove the comma | 273 // We may have a --log-net-log=blah log dump. If so, remove the comma |
| 284 // after the final good entry, and add the necessary close brackets. | 274 // after the final good entry, and add the necessary close brackets. |
| 285 var end = Math.max(logFileContents.lastIndexOf(',\n'), | 275 var end = Math.max( |
| 286 logFileContents.lastIndexOf(',\r')); | 276 logFileContents.lastIndexOf(',\n'), |
| 277 logFileContents.lastIndexOf(',\r')); |
| 287 if (end != -1) { | 278 if (end != -1) { |
| 288 parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}'); | 279 parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}'); |
| 289 errorString += 'Log file truncated. Events may be missing.\n'; | 280 errorString += 'Log file truncated. Events may be missing.\n'; |
| 290 } | 281 } |
| 291 } | 282 } catch (error2) { |
| 292 catch (error2) { | |
| 293 } | 283 } |
| 294 } | 284 } |
| 295 | 285 |
| 296 if (!parsedDump) | 286 if (!parsedDump) |
| 297 return 'Unable to parse log dump as JSON file.'; | 287 return 'Unable to parse log dump as JSON file.'; |
| 298 return errorString + loadLogDump(parsedDump, fileName); | 288 return errorString + loadLogDump(parsedDump, fileName); |
| 299 } | 289 } |
| 300 | 290 |
| 301 // Exports. | 291 // Exports. |
| 302 return { | 292 return { |
| 303 createUpdatedLogDump: createUpdatedLogDump, | 293 createUpdatedLogDump: createUpdatedLogDump, |
| 304 createLogDumpAsync: createLogDumpAsync, | 294 createLogDumpAsync: createLogDumpAsync, |
| 305 loadLogFile: loadLogFile | 295 loadLogFile: loadLogFile |
| 306 }; | 296 }; |
| 307 })(); | 297 })(); |
| OLD | NEW |