• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5var SourceTracker = (function() {
6  'use strict';
7
8  /**
9   * This class keeps track of all NetLog events, grouped into per-source
10   * streams. It receives events from EventsTracker, and passes
11   * them on to all its observers.
12   *
13   * @constructor
14   */
15  function SourceTracker() {
16    assertFirstConstructorCall(SourceTracker);
17
18    // Observers that only want to receive lists of updated SourceEntries.
19    this.sourceEntryObservers_ = [];
20
21    // True when cookies and authentication information should be removed from
22    // displayed events.  When true, such information should be hidden from
23    // all pages.
24    this.privacyStripping_ = true;
25
26    // True when times should be displayed as milliseconds since the first
27    // event, as opposed to milliseconds since January 1, 1970.
28    this.useRelativeTimes_ = true;
29
30    this.clearEntries_();
31
32    EventsTracker.getInstance().addLogEntryObserver(this);
33  }
34
35  cr.addSingletonGetter(SourceTracker);
36
37  SourceTracker.prototype = {
38    /**
39     * Clears all log entries and SourceEntries and related state.
40     */
41    clearEntries_: function() {
42      // Used for sorting entries with automatically assigned IDs.
43      this.maxReceivedSourceId_ = 0;
44
45      // Next unique id to be assigned to a log entry without a source.
46      // Needed to identify associated GUI elements, etc.
47      this.nextSourcelessEventId_ = -1;
48
49      // Ordered list of log entries.  Needed to maintain original order when
50      // generating log dumps
51      this.capturedEvents_ = [];
52
53      this.sourceEntries_ = {};
54    },
55
56    /**
57     * Returns a list of all SourceEntries.
58     */
59    getAllSourceEntries: function() {
60      return this.sourceEntries_;
61    },
62
63    /**
64     * Returns the description of the specified SourceEntry, or an empty string
65     * if it doesn't exist.
66     */
67    getDescription: function(id) {
68      var entry = this.getSourceEntry(id);
69      if (entry)
70        return entry.getDescription();
71      return '';
72    },
73
74    /**
75     * Returns the specified SourceEntry.
76     */
77    getSourceEntry: function(id) {
78      return this.sourceEntries_[id];
79    },
80
81    /**
82     * Sends each entry to all observers and updates |capturedEvents_|.
83     * Also assigns unique ids to log entries without a source.
84     */
85    onReceivedLogEntries: function(logEntries) {
86      // List source entries with new log entries.  Sorted chronologically, by
87      // first new log entry.
88      var updatedSourceEntries = [];
89
90      var updatedSourceEntryIdMap = {};
91
92      for (var e = 0; e < logEntries.length; ++e) {
93        var logEntry = logEntries[e];
94
95        // Assign unique ID, if needed.
96        // TODO(mmenke):  Remove this, and all other code to handle 0 source
97        //                IDs when M19 hits stable.
98        if (logEntry.source.id == 0) {
99          logEntry.source.id = this.nextSourcelessEventId_;
100          --this.nextSourcelessEventId_;
101        } else if (this.maxReceivedSourceId_ < logEntry.source.id) {
102          this.maxReceivedSourceId_ = logEntry.source.id;
103        }
104
105        // Create/update SourceEntry object.
106        var sourceEntry = this.sourceEntries_[logEntry.source.id];
107        if (!sourceEntry) {
108          sourceEntry = new SourceEntry(logEntry, this.maxReceivedSourceId_);
109          this.sourceEntries_[logEntry.source.id] = sourceEntry;
110        } else {
111          sourceEntry.update(logEntry);
112        }
113
114        // Add to updated SourceEntry list, if not already in it.
115        if (!updatedSourceEntryIdMap[logEntry.source.id]) {
116          updatedSourceEntryIdMap[logEntry.source.id] = sourceEntry;
117          updatedSourceEntries.push(sourceEntry);
118        }
119      }
120
121      this.capturedEvents_ = this.capturedEvents_.concat(logEntries);
122      for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
123        this.sourceEntryObservers_[i].onSourceEntriesUpdated(
124            updatedSourceEntries);
125      }
126    },
127
128    /**
129     * Called when all log events have been deleted.
130     */
131    onAllLogEntriesDeleted: function() {
132      this.clearEntries_();
133      for (var i = 0; i < this.sourceEntryObservers_.length; ++i)
134        this.sourceEntryObservers_[i].onAllSourceEntriesDeleted();
135    },
136
137    /**
138     * Sets the value of |privacyStripping_| and informs log observers
139     * of the change.
140     */
141    setPrivacyStripping: function(privacyStripping) {
142      this.privacyStripping_ = privacyStripping;
143      for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
144        if (this.sourceEntryObservers_[i].onPrivacyStrippingChanged)
145          this.sourceEntryObservers_[i].onPrivacyStrippingChanged();
146      }
147    },
148
149    /**
150     * Returns whether or not cookies and authentication information should be
151     * displayed for events that contain them.
152     */
153    getPrivacyStripping: function() {
154      return this.privacyStripping_;
155    },
156
157    /**
158     * Sets the value of |useRelativeTimes_| and informs log observers
159     * of the change.
160     */
161    setUseRelativeTimes: function(useRelativeTimes) {
162      this.useRelativeTimes_ = useRelativeTimes;
163      for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
164        if (this.sourceEntryObservers_[i].onUseRelativeTimesChanged)
165          this.sourceEntryObservers_[i].onUseRelativeTimesChanged();
166      }
167    },
168
169    /**
170     * Returns true if times should be displayed as milliseconds since the first
171     * event.
172     */
173    getUseRelativeTimes: function() {
174      return this.useRelativeTimes_;
175    },
176
177    /**
178     * Adds a listener of SourceEntries. |observer| will be called back when
179     * SourceEntries are added or modified, source entries are deleted, or
180     * privacy stripping changes:
181     *
182     *   observer.onSourceEntriesUpdated(sourceEntries)
183     *   observer.onAllSourceEntriesDeleted()
184     *   observer.onPrivacyStrippingChanged()
185     */
186    addSourceEntryObserver: function(observer) {
187      this.sourceEntryObservers_.push(observer);
188    }
189  };
190
191  return SourceTracker;
192})();
193