Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / src / tracing / tracks / process_track_base.js
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 'use strict';
6
7 tvcm.require('tcmalloc.heap_instance_track');
8 tvcm.require('tracing.analysis.object_snapshot_view');
9 tvcm.require('tracing.analysis.object_instance_view');
10 tvcm.require('tracing.tracks.container_track');
11 tvcm.require('tracing.tracks.counter_track');
12 tvcm.require('tracing.tracks.object_instance_track');
13 tvcm.require('tracing.tracks.spacing_track');
14 tvcm.require('tracing.tracks.thread_track');
15 tvcm.require('tracing.trace_model_settings');
16 tvcm.require('tracing.filter');
17 tvcm.require('tvcm.ui');
18 tvcm.require('tvcm.ui.dom_helpers');
19
20 tvcm.requireStylesheet('tracing.tracks.process_track_base');
21
22 tvcm.exportTo('tracing.tracks', function() {
23
24   var ObjectSnapshotView = tracing.analysis.ObjectSnapshotView;
25   var ObjectInstanceView = tracing.analysis.ObjectInstanceView;
26   var TraceModelSettings = tracing.TraceModelSettings;
27   var SpacingTrack = tracing.tracks.SpacingTrack;
28
29   /**
30    * Visualizes a Process by building ThreadTracks and CounterTracks.
31    * @constructor
32    */
33   var ProcessTrackBase =
34       tvcm.ui.define('process-track-base', tracing.tracks.ContainerTrack);
35
36   ProcessTrackBase.prototype = {
37
38     __proto__: tracing.tracks.ContainerTrack.prototype,
39
40     decorate: function(viewport) {
41       tracing.tracks.ContainerTrack.prototype.decorate.call(this, viewport);
42
43       this.processBase_ = undefined;
44
45       this.classList.add('process-track-base');
46       this.classList.add('expanded');
47
48       this.processNameEl_ = tvcm.ui.createSpan();
49       this.processNameEl_.classList.add('process-track-name');
50
51       this.headerEl_ = tvcm.ui.createDiv({className: 'process-track-header'});
52       this.headerEl_.appendChild(this.processNameEl_);
53       this.headerEl_.addEventListener('click', this.onHeaderClick_.bind(this));
54
55       this.appendChild(this.headerEl_);
56     },
57
58     get processBase() {
59       return this.processBase_;
60     },
61
62     set processBase(processBase) {
63       this.processBase_ = processBase;
64
65       if (this.processBase_) {
66         var modelSettings = new TraceModelSettings(this.processBase_.model);
67         var defaultValue;
68         if (this.processBase_.labels !== undefined &&
69             this.processBase_.labels.length == 1 &&
70             this.processBase_.labels[0] == 'chrome://tracing') {
71           defaultValue = false;
72         } else {
73           defaultValue = true;
74         }
75         this.expanded = modelSettings.getSettingFor(
76             this.processBase_, 'expanded', defaultValue);
77       }
78
79       this.updateContents_();
80     },
81
82     get expanded() {
83       return this.classList.contains('expanded');
84     },
85
86     set expanded(expanded) {
87       expanded = !!expanded;
88
89       if (this.expanded === expanded)
90         return;
91
92       this.classList.toggle('expanded');
93
94       // Expanding and collapsing tracks is, essentially, growing and shrinking
95       // the viewport. We dispatch a change event to trigger any processing
96       // to happen.
97       this.viewport_.dispatchChangeEvent();
98
99       if (!this.processBase_)
100         return;
101
102       var modelSettings = new TraceModelSettings(this.processBase_.model);
103       modelSettings.setSettingFor(this.processBase_, 'expanded', expanded);
104     },
105
106     get hasVisibleContent() {
107       if (this.expanded)
108         return this.children.length > 1;
109       return true;
110     },
111
112     onHeaderClick_: function(e) {
113       e.stopPropagation();
114       e.preventDefault();
115       this.expanded = !this.expanded;
116     },
117
118     updateContents_: function() {
119       this.tracks_.forEach(function(track) {
120         this.removeChild(track);
121       }, this);
122
123       if (!this.processBase_)
124         return;
125
126       this.processNameEl_.textContent = this.processBase_.userFriendlyName;
127       this.headerEl_.title = this.processBase_.userFriendlyDetails;
128
129       // Create the object instance tracks for this process.
130       this.willAppendTracks_();
131       this.appendObjectInstanceTracks_();
132       this.appendCounterTracks_();
133       this.appendThreadTracks_();
134       this.didAppendTracks_();
135     },
136
137     addEventsToTrackMap: function(eventToTrackMap) {
138       this.tracks_.forEach(function(track) {
139         track.addEventsToTrackMap(eventToTrackMap);
140       });
141     },
142
143     willAppendTracks_: function() {
144     },
145
146     didAppendTracks_: function() {
147     },
148
149     appendObjectInstanceTracks_: function() {
150       var instancesByTypeName =
151           this.processBase_.objects.getAllInstancesByTypeName();
152       var instanceTypeNames = tvcm.dictionaryKeys(instancesByTypeName);
153       instanceTypeNames.sort();
154
155       var didAppendAtLeastOneTrack = false;
156       instanceTypeNames.forEach(function(typeName) {
157         var allInstances = instancesByTypeName[typeName];
158
159         // If a object snapshot has a view it will be shown,
160         // unless the view asked for it to not be shown.
161         var instanceViewInfo = ObjectInstanceView.getViewInfo(typeName);
162         var snapshotViewInfo = ObjectSnapshotView.getViewInfo(typeName);
163         if (instanceViewInfo && !instanceViewInfo.options.showInTrackView)
164           instanceViewInfo = undefined;
165         if (snapshotViewInfo && !snapshotViewInfo.options.showInTrackView)
166           snapshotViewInfo = undefined;
167         var hasViewInfo = instanceViewInfo || snapshotViewInfo;
168
169         // There are some instances that don't merit their own track in
170         // the UI. Filter them out.
171         var visibleInstances = [];
172         for (var i = 0; i < allInstances.length; i++) {
173           var instance = allInstances[i];
174
175           // Do not create tracks for instances that have no snapshots.
176           if (instance.snapshots.length === 0)
177             continue;
178
179           // Do not create tracks for instances that have implicit snapshots
180           // and don't have a view.
181           if (instance.hasImplicitSnapshots && !hasViewInfo)
182             continue;
183
184           visibleInstances.push(instance);
185         }
186         if (visibleInstances.length === 0)
187           return;
188
189         // Look up the constructor for this track, or use the default
190         // constructor if none exists.
191         var trackConstructor =
192             tracing.tracks.ObjectInstanceTrack.getTrackConstructor(typeName);
193         if (!trackConstructor)
194           trackConstructor = tracing.tracks.ObjectInstanceTrack;
195         var track = new trackConstructor(this.viewport);
196         track.objectInstances = visibleInstances;
197         this.appendChild(track);
198         didAppendAtLeastOneTrack = true;
199       }, this);
200       if (didAppendAtLeastOneTrack)
201         this.appendChild(new SpacingTrack(this.viewport));
202     },
203
204     appendCounterTracks_: function() {
205       // Add counter tracks for this process.
206       var counters = tvcm.dictionaryValues(this.processBase.counters);
207       counters.sort(tracing.trace_model.Counter.compare);
208
209       // Create the counters for this process.
210       counters.forEach(function(counter) {
211         var track = new tracing.tracks.CounterTrack(this.viewport);
212         track.counter = counter;
213         this.appendChild(track);
214         this.appendChild(new SpacingTrack(this.viewport));
215       }.bind(this));
216     },
217
218     appendThreadTracks_: function() {
219       // Get a sorted list of threads.
220       var threads = tvcm.dictionaryValues(this.processBase.threads);
221       threads.sort(tracing.trace_model.Thread.compare);
222
223       // Create the threads.
224       threads.forEach(function(thread) {
225         var track = new tracing.tracks.ThreadTrack(this.viewport);
226         track.thread = thread;
227         if (!track.hasVisibleContent)
228           return;
229         this.appendChild(track);
230         this.appendChild(new SpacingTrack(this.viewport));
231       }.bind(this));
232     }
233   };
234
235   return {
236     ProcessTrackBase: ProcessTrackBase
237   };
238 });