| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 * This class keeps track of all NetLog events. | |
| 7 * It receives events from the browser and when loading a log file, and passes | |
| 8 * them on to all its observers. | |
| 9 * | |
| 10 * @constructor | |
| 11 */ | |
| 12 function SourceTracker() { | |
| 13 this.observers_ = []; | |
| 14 | |
| 15 // True when cookies and authentication information should be removed from | |
| 16 // displayed events. When true, such information should be hidden from | |
| 17 // all pages. | |
| 18 this.enableSecurityStripping_ = true; | |
| 19 | |
| 20 this.clearEntries_(); | |
| 21 } | |
| 22 | |
| 23 /** | |
| 24 * Clears all log entries and SourceEntries and related state. | |
| 25 */ | |
| 26 SourceTracker.prototype.clearEntries_ = function() { | |
| 27 // Used for sorting entries with automatically assigned IDs. | |
| 28 this.maxReceivedSourceId_ = 0; | |
| 29 | |
| 30 // Next unique id to be assigned to a log entry without a source. | |
| 31 // Needed to simplify deletion, identify associated GUI elements, etc. | |
| 32 this.nextSourcelessEventId_ = -1; | |
| 33 | |
| 34 this.numPassivelyCapturedEvents_ = 0; | |
| 35 | |
| 36 // Ordered list of log entries. Needed to maintain original order when | |
| 37 // generating log dumps | |
| 38 this.capturedEvents_ = []; | |
| 39 | |
| 40 this.sourceEntries_ = {}; | |
| 41 }; | |
| 42 | |
| 43 /** | |
| 44 * Returns a list of all captured events. | |
| 45 */ | |
| 46 SourceTracker.prototype.getAllCapturedEvents = function() { | |
| 47 return this.capturedEvents_; | |
| 48 }; | |
| 49 | |
| 50 /** | |
| 51 * Returns a list of all SourceEntries. | |
| 52 */ | |
| 53 SourceTracker.prototype.getAllSourceEntries = function() { | |
| 54 return this.sourceEntries_; | |
| 55 }; | |
| 56 | |
| 57 /** | |
| 58 * Returns the number of events that were captured while we were | |
| 59 * listening for events. | |
| 60 */ | |
| 61 SourceTracker.prototype.getNumActivelyCapturedEvents = function() { | |
| 62 return this.capturedEvents_.length - this.numPassivelyCapturedEvents_; | |
| 63 }; | |
| 64 | |
| 65 /** | |
| 66 * Returns the number of events that were captured passively by the | |
| 67 * browser prior to when the net-internals page was started. | |
| 68 */ | |
| 69 SourceTracker.prototype.getNumPassivelyCapturedEvents = function() { | |
| 70 return this.numPassivelyCapturedEvents_; | |
| 71 }; | |
| 72 | |
| 73 /** | |
| 74 * Returns the specified SourceEntry. | |
| 75 */ | |
| 76 SourceTracker.prototype.getSourceEntry = function(id) { | |
| 77 return this.sourceEntries_[id]; | |
| 78 }; | |
| 79 | |
| 80 SourceTracker.prototype.onReceivedPassiveLogEntries = function(entries) { | |
| 81 // Due to an expected race condition, it is possible to receive actively | |
| 82 // captured log entries before the passively logged entries are received. | |
| 83 // | |
| 84 // When that happens, we create a copy of the actively logged entries, delete | |
| 85 // all entries, and, after handling all the passively logged entries, add back | |
| 86 // the deleted actively logged entries. | |
| 87 var earlyActivelyCapturedEvents = this.capturedEvents_.slice(0); | |
| 88 if (earlyActivelyCapturedEvents.length > 0) | |
| 89 this.deleteAllSourceEntries(); | |
| 90 | |
| 91 this.numPassivelyCapturedEvents_ = entries.length; | |
| 92 for (var i = 0; i < entries.length; ++i) | |
| 93 entries[i].wasPassivelyCaptured = true; | |
| 94 this.onReceivedLogEntries(entries); | |
| 95 | |
| 96 // Add back early actively captured events, if any. | |
| 97 if (earlyActivelyCapturedEvents.length) | |
| 98 this.onReceivedLogEntries(earlyActivelyCapturedEvents); | |
| 99 }; | |
| 100 | |
| 101 /** | |
| 102 * Sends each entry to all log observers, and updates |capturedEvents_|. | |
| 103 * Also assigns unique ids to log entries without a source. | |
| 104 */ | |
| 105 SourceTracker.prototype.onReceivedLogEntries = function(logEntries) { | |
| 106 for (var e = 0; e < logEntries.length; ++e) { | |
| 107 var logEntry = logEntries[e]; | |
| 108 | |
| 109 // Assign unique ID, if needed. | |
| 110 if (logEntry.source.id == 0) { | |
| 111 logEntry.source.id = this.nextSourcelessEventId_; | |
| 112 --this.nextSourcelessEventId_; | |
| 113 } else if (this.maxReceivedSourceId_ < logEntry.source.id) { | |
| 114 this.maxReceivedSourceId_ = logEntry.source.id; | |
| 115 } | |
| 116 | |
| 117 var sourceEntry = this.sourceEntries_[logEntry.source.id]; | |
| 118 if (!sourceEntry) { | |
| 119 sourceEntry = new SourceEntry(logEntry, this.maxReceivedSourceId_); | |
| 120 this.sourceEntries_[logEntry.source.id] = sourceEntry; | |
| 121 } else { | |
| 122 sourceEntry.update(logEntry); | |
| 123 } | |
| 124 this.capturedEvents_.push(logEntry); | |
| 125 | |
| 126 // TODO(mmenke): Send a list of all updated source entries instead, | |
| 127 // eliminating duplicates, to reduce CPU usage. | |
| 128 for (var i = 0; i < this.observers_.length; ++i) | |
| 129 this.observers_[i].onSourceEntryUpdated(sourceEntry); | |
| 130 } | |
| 131 }; | |
| 132 | |
| 133 /** | |
| 134 * Deletes captured events with source IDs in |sourceEntryIds|. | |
| 135 */ | |
| 136 SourceTracker.prototype.deleteSourceEntries = function(sourceEntryIds) { | |
| 137 var sourceIdDict = {}; | |
| 138 for (var i = 0; i < sourceEntryIds.length; i++) { | |
| 139 sourceIdDict[sourceEntryIds[i]] = true; | |
| 140 delete this.sourceEntries_[sourceEntryIds[i]]; | |
| 141 } | |
| 142 | |
| 143 var newEventList = []; | |
| 144 for (var i = 0; i < this.capturedEvents_.length; ++i) { | |
| 145 var id = this.capturedEvents_[i].source.id; | |
| 146 if (id in sourceIdDict) { | |
| 147 if (this.capturedEvents_[i].wasPassivelyCaptured) | |
| 148 --this.numPassivelyCapturedEvents_; | |
| 149 continue; | |
| 150 } | |
| 151 newEventList.push(this.capturedEvents_[i]); | |
| 152 } | |
| 153 this.capturedEvents_ = newEventList; | |
| 154 | |
| 155 for (var i = 0; i < this.observers_.length; ++i) | |
| 156 this.observers_[i].onSourceEntriesDeleted(sourceEntryIds); | |
| 157 }; | |
| 158 | |
| 159 /** | |
| 160 * Deletes all captured events. | |
| 161 */ | |
| 162 SourceTracker.prototype.deleteAllSourceEntries = function() { | |
| 163 this.clearEntries_(); | |
| 164 for (var i = 0; i < this.observers_.length; ++i) | |
| 165 this.observers_[i].onAllSourceEntriesDeleted(); | |
| 166 }; | |
| 167 | |
| 168 /** | |
| 169 * Sets the value of |enableSecurityStripping_| and informs log observers | |
| 170 * of the change. | |
| 171 */ | |
| 172 SourceTracker.prototype.setSecurityStripping = | |
| 173 function(enableSecurityStripping) { | |
| 174 this.enableSecurityStripping_ = enableSecurityStripping; | |
| 175 for (var i = 0; i < this.observers_.length; ++i) { | |
| 176 if (this.observers_[i].onSecurityStrippingChanged) | |
| 177 this.observers_[i].onSecurityStrippingChanged(); | |
| 178 } | |
| 179 }; | |
| 180 | |
| 181 /** | |
| 182 * Returns whether or not cookies and authentication information should be | |
| 183 * displayed for events that contain them. | |
| 184 */ | |
| 185 SourceTracker.prototype.getSecurityStripping = function() { | |
| 186 return this.enableSecurityStripping_; | |
| 187 }; | |
| 188 | |
| 189 /** | |
| 190 * Adds a listener of log entries. |observer| will be called back when new log | |
| 191 * data arrives, source entries are deleted, or security stripping changes | |
| 192 * through: | |
| 193 * | |
| 194 * observer.onSourceEntryUpdated(sourceEntry) | |
| 195 * observer.deleteSourceEntries(sourceEntryIds) | |
| 196 * ovserver.deleteAllSourceEntries() | |
| 197 * observer.onSecurityStrippingChanged() | |
| 198 */ | |
| 199 SourceTracker.prototype.addObserver = function(observer) { | |
| 200 this.observers_.push(observer); | |
| 201 }; | |
| OLD | NEW |