Home | History | Annotate | Download | only in net_internals
      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 var 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     this.clearEntries_();
     27 
     28     EventsTracker.getInstance().addLogEntryObserver(this);
     29   }
     30 
     31   cr.addSingletonGetter(SourceTracker);
     32 
     33   SourceTracker.prototype = {
     34     /**
     35      * Clears all log entries and SourceEntries and related state.
     36      */
     37     clearEntries_: function() {
     38       // Used for sorting entries with automatically assigned IDs.
     39       this.maxReceivedSourceId_ = 0;
     40 
     41       // Next unique id to be assigned to a log entry without a source.
     42       // Needed to identify associated GUI elements, etc.
     43       this.nextSourcelessEventId_ = -1;
     44 
     45       // Ordered list of log entries.  Needed to maintain original order when
     46       // generating log dumps
     47       this.capturedEvents_ = [];
     48 
     49       this.sourceEntries_ = {};
     50     },
     51 
     52     /**
     53      * Returns a list of all SourceEntries.
     54      */
     55     getAllSourceEntries: function() {
     56       return this.sourceEntries_;
     57     },
     58 
     59     /**
     60      * Returns the description of the specified SourceEntry, or an empty string
     61      * if it doesn't exist.
     62      */
     63     getDescription: function(id) {
     64       var entry = this.getSourceEntry(id);
     65       if (entry)
     66         return entry.getDescription();
     67       return '';
     68     },
     69 
     70     /**
     71      * Returns the specified SourceEntry.
     72      */
     73     getSourceEntry: function(id) {
     74       return this.sourceEntries_[id];
     75     },
     76 
     77     /**
     78      * Sends each entry to all observers and updates |capturedEvents_|.
     79      * Also assigns unique ids to log entries without a source.
     80      */
     81     onReceivedLogEntries: function(logEntries) {
     82       // List source entries with new log entries.  Sorted chronologically, by
     83       // first new log entry.
     84       var updatedSourceEntries = [];
     85 
     86       var updatedSourceEntryIdMap = {};
     87 
     88       for (var e = 0; e < logEntries.length; ++e) {
     89         var logEntry = logEntries[e];
     90 
     91         // Assign unique ID, if needed.
     92         // TODO(mmenke):  Remove this, and all other code to handle 0 source
     93         //                IDs when M19 hits stable.
     94         if (logEntry.source.id == 0) {
     95           logEntry.source.id = this.nextSourcelessEventId_;
     96           --this.nextSourcelessEventId_;
     97         } else if (this.maxReceivedSourceId_ < logEntry.source.id) {
     98           this.maxReceivedSourceId_ = logEntry.source.id;
     99         }
    100 
    101         // Create/update SourceEntry object.
    102         var sourceEntry = this.sourceEntries_[logEntry.source.id];
    103         if (!sourceEntry) {
    104           sourceEntry = new SourceEntry(logEntry, this.maxReceivedSourceId_);
    105           this.sourceEntries_[logEntry.source.id] = sourceEntry;
    106         } else {
    107           sourceEntry.update(logEntry);
    108         }
    109 
    110         // Add to updated SourceEntry list, if not already in it.
    111         if (!updatedSourceEntryIdMap[logEntry.source.id]) {
    112           updatedSourceEntryIdMap[logEntry.source.id] = sourceEntry;
    113           updatedSourceEntries.push(sourceEntry);
    114         }
    115       }
    116 
    117       this.capturedEvents_ = this.capturedEvents_.concat(logEntries);
    118       for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
    119         this.sourceEntryObservers_[i].onSourceEntriesUpdated(
    120             updatedSourceEntries);
    121       }
    122     },
    123 
    124     /**
    125      * Called when all log events have been deleted.
    126      */
    127     onAllLogEntriesDeleted: function() {
    128       this.clearEntries_();
    129       for (var i = 0; i < this.sourceEntryObservers_.length; ++i)
    130         this.sourceEntryObservers_[i].onAllSourceEntriesDeleted();
    131     },
    132 
    133     /**
    134      * Sets the value of |privacyStripping_| and informs log observers
    135      * of the change.
    136      */
    137     setPrivacyStripping: function(privacyStripping) {
    138       this.privacyStripping_ = privacyStripping;
    139       for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
    140         if (this.sourceEntryObservers_[i].onPrivacyStrippingChanged)
    141           this.sourceEntryObservers_[i].onPrivacyStrippingChanged();
    142       }
    143     },
    144 
    145     /**
    146      * Returns whether or not cookies and authentication information should be
    147      * displayed for events that contain them.
    148      */
    149     getPrivacyStripping: function() {
    150       return this.privacyStripping_;
    151     },
    152 
    153     /**
    154      * Adds a listener of SourceEntries. |observer| will be called back when
    155      * SourceEntries are added or modified, source entries are deleted, or
    156      * privacy stripping changes:
    157      *
    158      *   observer.onSourceEntriesUpdated(sourceEntries)
    159      *   observer.onAllSourceEntriesDeleted()
    160      *   observer.onPrivacyStrippingChanged()
    161      */
    162     addSourceEntryObserver: function(observer) {
    163       this.sourceEntryObservers_.push(observer);
    164     }
    165   };
    166 
    167   return SourceTracker;
    168 })();
    169