ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / resources / net_internals / source_entry.js
blobbf4259d7049d0cb0b13b90735a80f48c688da31c
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.
5 var SourceEntry = (function() {
6   'use strict';
8   /**
9    * A SourceEntry gathers all log entries with the same source.
10    *
11    * @constructor
12    */
13   function SourceEntry(logEntry, maxPreviousSourceId) {
14     this.maxPreviousSourceId_ = maxPreviousSourceId;
15     this.entries_ = [];
16     this.description_ = '';
18     // Set to true on most net errors.
19     this.isError_ = false;
21     // If the first entry is a BEGIN_PHASE, set to false.
22     // Set to true when an END_PHASE matching the first entry is encountered.
23     this.isInactive_ = true;
25     if (logEntry.phase == EventPhase.PHASE_BEGIN)
26       this.isInactive_ = false;
28     this.update(logEntry);
29   }
31   SourceEntry.prototype = {
32     update: function(logEntry) {
33       // Only the last event should have the same type first event,
34       if (!this.isInactive_ &&
35           logEntry.phase == EventPhase.PHASE_END &&
36           logEntry.type == this.entries_[0].type) {
37         this.isInactive_ = true;
38       }
40       // If we have a net error code, update |this.isError_| if appropriate.
41       if (logEntry.params) {
42         var netErrorCode = logEntry.params.net_error;
43         // Skip both cases where netErrorCode is undefined, and cases where it
44         // is 0, indicating no actual error occurred.
45         if (netErrorCode) {
46           // Ignore error code caused by not finding an entry in the cache.
47           if (logEntry.type != EventType.HTTP_CACHE_OPEN_ENTRY ||
48               netErrorCode != NetError.ERR_FAILED) {
49             this.isError_ = true;
50           }
51         }
52       }
54       var prevStartEntry = this.getStartEntry_();
55       this.entries_.push(logEntry);
56       var curStartEntry = this.getStartEntry_();
58       // If we just got the first entry for this source.
59       if (prevStartEntry != curStartEntry)
60         this.updateDescription_();
61     },
63     updateDescription_: function() {
64       var e = this.getStartEntry_();
65       this.description_ = '';
66       if (!e)
67         return;
69       if (e.source.type == EventSourceType.NONE) {
70         // NONE is what we use for global events that aren't actually grouped
71         // by a "source ID", so we will just stringize the event's type.
72         this.description_ = EventTypeNames[e.type];
73         return;
74       }
76       if (e.params == undefined) {
77         return;
78       }
80       switch (e.source.type) {
81         case EventSourceType.URL_REQUEST:
82         // TODO(ricea): Remove SOCKET_STREAM after M41 is released.
83         case EventSourceType.SOCKET_STREAM:
84         case EventSourceType.HTTP_STREAM_JOB:
85         case EventSourceType.ASYNC_REVALIDATION:
86           this.description_ = e.params.url;
87           break;
88         case EventSourceType.CONNECT_JOB:
89           this.description_ = e.params.group_name;
90           break;
91         case EventSourceType.HOST_RESOLVER_IMPL_JOB:
92         case EventSourceType.HOST_RESOLVER_IMPL_PROC_TASK:
93           this.description_ = e.params.host;
94           break;
95         case EventSourceType.DISK_CACHE_ENTRY:
96         case EventSourceType.MEMORY_CACHE_ENTRY:
97           this.description_ = e.params.key;
98           break;
99         case EventSourceType.QUIC_SESSION:
100           if (e.params.host != undefined)
101             this.description_ = e.params.host;
102           break;
103         case EventSourceType.HTTP2_SESSION:
104           if (e.params.host)
105             this.description_ = e.params.host + ' (' + e.params.proxy + ')';
106           break;
107         case EventSourceType.HTTP_PIPELINED_CONNECTION:
108           if (e.params.host_and_port)
109             this.description_ = e.params.host_and_port;
110           break;
111         case EventSourceType.SOCKET:
112         case EventSourceType.PROXY_CLIENT_SOCKET:
113           // Use description of parent source, if any.
114           if (e.params.source_dependency != undefined) {
115             var parentId = e.params.source_dependency.id;
116             this.description_ =
117                 SourceTracker.getInstance().getDescription(parentId);
118           }
119           break;
120         case EventSourceType.UDP_SOCKET:
121           if (e.params.address != undefined) {
122             this.description_ = e.params.address;
123             // If the parent of |this| is a HOST_RESOLVER_IMPL_JOB, use
124             // '<DNS Server IP> [<host we're resolving>]'.
125             if (this.entries_[0].type == EventType.SOCKET_ALIVE &&
126                 this.entries_[0].params &&
127                 this.entries_[0].params.source_dependency != undefined) {
128               var parentId = this.entries_[0].params.source_dependency.id;
129               var parent = SourceTracker.getInstance().getSourceEntry(parentId);
130               if (parent &&
131                   parent.getSourceType() ==
132                       EventSourceType.HOST_RESOLVER_IMPL_JOB &&
133                   parent.getDescription().length > 0) {
134                 this.description_ += ' [' + parent.getDescription() + ']';
135               }
136             }
137           }
138           break;
139         case EventSourceType.ASYNC_HOST_RESOLVER_REQUEST:
140         case EventSourceType.DNS_TRANSACTION:
141           this.description_ = e.params.hostname;
142           break;
143         case EventSourceType.DOWNLOAD:
144           switch (e.type) {
145             case EventType.DOWNLOAD_FILE_RENAMED:
146               this.description_ = e.params.new_filename;
147               break;
148             case EventType.DOWNLOAD_FILE_OPENED:
149               this.description_ = e.params.file_name;
150               break;
151             case EventType.DOWNLOAD_ITEM_ACTIVE:
152               this.description_ = e.params.file_name;
153               break;
154           }
155           break;
156         case EventSourceType.FILESTREAM:
157           this.description_ = e.params.file_name;
158           break;
159         case EventSourceType.IPV6_PROBE_JOB:
160           if (e.type == EventType.IPV6_PROBE_RUNNING &&
161               e.phase == EventPhase.PHASE_END) {
162             this.description_ = e.params.ipv6_supported ? 'IPv6 Supported' :
163                                                           'IPv6 Not Supported';
164           }
165           break;
166       }
168       if (this.description_ == undefined)
169         this.description_ = '';
170     },
172     /**
173      * Returns a description for this source log stream, which will be displayed
174      * in the list view. Most often this is a URL that identifies the request,
175      * or a hostname for a connect job, etc...
176      */
177     getDescription: function() {
178       return this.description_;
179     },
181     /**
182      * Returns the starting entry for this source. Conceptually this is the
183      * first entry that was logged to this source. However, we skip over the
184      * TYPE_REQUEST_ALIVE entries which wrap TYPE_URL_REQUEST_START_JOB
185      * entries.
186      */
187     getStartEntry_: function() {
188       if (this.entries_.length < 1)
189         return undefined;
190       if (this.entries_[0].source.type == EventSourceType.FILESTREAM) {
191         var e = this.findLogEntryByType_(EventType.FILE_STREAM_OPEN);
192         if (e != undefined)
193           return e;
194       }
195       if (this.entries_[0].source.type == EventSourceType.DOWNLOAD) {
196         // If any rename occurred, use the last name
197         e = this.findLastLogEntryStartByType_(
198             EventType.DOWNLOAD_FILE_RENAMED);
199         if (e != undefined)
200           return e;
201         // Otherwise, if the file was opened, use that name
202         e = this.findLogEntryByType_(EventType.DOWNLOAD_FILE_OPENED);
203         if (e != undefined)
204           return e;
205         // History items are never opened, so use the activation info
206         e = this.findLogEntryByType_(EventType.DOWNLOAD_ITEM_ACTIVE);
207         if (e != undefined)
208           return e;
209       }
210       if (this.entries_.length >= 2) {
211         // Needed for compatability with log dumps prior to M26.
212         // TODO(mmenke):  Remove this.
213         if (this.entries_[0].type == EventType.SOCKET_POOL_CONNECT_JOB &&
214             this.entries_[0].params == undefined) {
215           return this.entries_[1];
216         }
217         if (this.entries_[1].type == EventType.UDP_CONNECT)
218           return this.entries_[1];
219         if (this.entries_[0].type == EventType.REQUEST_ALIVE &&
220             this.entries_[0].params == undefined) {
221           var startIndex = 1;
222           // Skip over delegate events for URL_REQUESTs.
223           for (; startIndex + 1 < this.entries_.length; ++startIndex) {
224             var type = this.entries_[startIndex].type;
225             if (type != EventType.URL_REQUEST_DELEGATE &&
226                 type != EventType.DELEGATE_INFO) {
227               break;
228             }
229           }
230           return this.entries_[startIndex];
231         }
232         if (this.entries_[1].type == EventType.IPV6_PROBE_RUNNING)
233           return this.entries_[1];
234       }
235       return this.entries_[0];
236     },
238     /**
239      * Returns the first entry with the specified type, or undefined if not
240      * found.
241      */
242     findLogEntryByType_: function(type) {
243       for (var i = 0; i < this.entries_.length; ++i) {
244         if (this.entries_[i].type == type) {
245           return this.entries_[i];
246         }
247       }
248       return undefined;
249     },
251     /**
252      * Returns the beginning of the last entry with the specified type, or
253      * undefined if not found.
254      */
255     findLastLogEntryStartByType_: function(type) {
256       for (var i = this.entries_.length - 1; i >= 0; --i) {
257         if (this.entries_[i].type == type) {
258           if (this.entries_[i].phase != EventPhase.PHASE_END)
259             return this.entries_[i];
260         }
261       }
262       return undefined;
263     },
265     getLogEntries: function() {
266       return this.entries_;
267     },
269     getSourceTypeString: function() {
270       return EventSourceTypeNames[this.entries_[0].source.type];
271     },
273     getSourceType: function() {
274       return this.entries_[0].source.type;
275     },
277     getSourceId: function() {
278       return this.entries_[0].source.id;
279     },
281     /**
282      * Returns the largest source ID seen before this object was received.
283      * Used only for sorting SourceEntries without a source by source ID.
284      */
285     getMaxPreviousEntrySourceId: function() {
286       return this.maxPreviousSourceId_;
287     },
289     isInactive: function() {
290       return this.isInactive_;
291     },
293     isError: function() {
294       return this.isError_;
295     },
297     /**
298      * Returns time ticks of first event.
299      */
300     getStartTicks: function() {
301       return this.entries_[0].time;
302     },
304     /**
305      * Returns time of last event if inactive.  Returns current time otherwise.
306      * Returned time is a "time ticks" value.
307      */
308     getEndTicks: function() {
309       if (!this.isInactive_)
310         return timeutil.getCurrentTimeTicks();
311       return this.entries_[this.entries_.length - 1].time;
312     },
314     /**
315      * Returns the time between the first and last events with a matching
316      * source ID.  If source is still active, uses the current time for the
317      * last event.
318      */
319     getDuration: function() {
320       var startTime = this.getStartTicks();
321       var endTime = this.getEndTicks();
322       return endTime - startTime;
323     },
325     /**
326      * Prints descriptive text about |entries_| to a new node added to the end
327      * of |parent|.
328      */
329     printAsText: function(parent) {
330       var tablePrinter = this.createTablePrinter();
332       // Format the table for fixed-width text.
333       tablePrinter.toText(0, parent);
334     },
336     /**
337      * Creates a table printer for the SourceEntry.
338      */
339     createTablePrinter: function() {
340       return createLogEntryTablePrinter(
341           this.entries_,
342           SourceTracker.getInstance().getPrivacyStripping(),
343           SourceTracker.getInstance().getUseRelativeTimes() ?
344               timeutil.getBaseTime() : 0,
345           Constants.clientInfo.numericDate);
346     },
347   };
349   return SourceEntry;
350 })();