Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / memory_inspector / memory_inspector / frontends / www_content / js / processes.js
1 // Copyright 2014 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 processes = new (function() {
6
7 this.PS_INTERVAL_SEC_ = 2;
8 this.DEV_STATS_INTERVAL_SEC_ = 2;
9 this.PROC_STATS_INTERVAL_SEC_ = 1;
10 this.TRACER_POLL_INTERVAL_SEC_ = 2;
11
12 this.selProcUri_ = null;
13 this.selProcName_ = null;
14 this.psTable_ = null;
15 this.psTableData_ = null;
16 this.memChart_ = null;
17 this.memChartData_ = null;
18 this.cpuChart_ = null;
19 this.cpuChartData_ = null;
20 this.procCpuChart_ = null;
21 this.procCpuChartData_ = null;
22 this.procMemChart_ = null;
23 this.procMemChartData_ = null;
24 this.tracerTaskId_ = null;
25
26 this.onDomReady_ = function() {
27   $('#device_tabs').tabs();
28   $('#device_tabs').on('tabsactivate', this.redrawPsStats_.bind(this));
29   $('#device_tabs').on('tabsactivate', this.redrawDevStats_.bind(this));
30
31   // Initialize the toolbar.
32   $('#ps-quick_snapshot').button({icons:{primary: 'ui-icon-image'}})
33       .click(this.snapshotSelectedProcess_.bind(this));
34   $('#ps-dump_mmaps').button({icons:{primary: 'ui-icon-calculator'}})
35       .click(this.dumpSelectedProcessMmaps_.bind(this));
36   $('#ps-full_profile').button({icons:{primary: 'ui-icon-clock'}})
37       .click(this.showTracingDialog_.bind(this));
38
39   // Set-up the tracer dialog.
40   $('#ps-tracer-dialog').dialog({autoOpen: false, modal: true, width: 400,
41       buttons: {'Start': this.startTracingSelectedProcess_.bind(this)}});
42   $('#ps-tracer-period').spinner({min: 0, step: 20});
43   $('#ps-tracer-snapshots').spinner({min: 1, max: 100});
44
45   // Create the process table.
46   this.psTable_ = new google.visualization.Table($('#ps-table')[0]);
47   google.visualization.events.addListener(
48       this.psTable_, 'select', this.onPsTableRowSelect_.bind(this));
49   $('#ps-table').on('dblclick', this.snapshotSelectedProcess_.bind(this));
50
51   // Create the device stats charts.
52   this.memChart_ = new google.visualization.PieChart($('#os-mem_chart')[0]);
53   this.cpuChart_ = new google.visualization.BarChart($('#os-cpu_chart')[0]);
54
55   // Create the selected process stats charts.
56   this.procCpuChart_ =
57       new google.visualization.ComboChart($('#proc-cpu_chart')[0]);
58   this.procMemChart_ =
59       new google.visualization.ComboChart($('#proc-mem_chart')[0]);
60 };
61
62 this.getSelectedProcessURI = function() {
63   return this.selProcUri_;
64 };
65
66 this.snapshotSelectedProcess_ = function() {
67   if (!this.selProcUri_)
68     return alert('Must select a process!');
69   mmap.dumpMmaps(this.selProcUri_, true);
70   rootUi.showTab('prof');
71 };
72
73 this.dumpSelectedProcessMmaps_ = function() {
74   if (!this.selProcUri_)
75     return alert('Must select a process!');
76   mmap.dumpMmaps(this.selProcUri_, false);
77   rootUi.showTab('mm');
78 };
79
80 this.showTracingDialog_ = function() {
81   if (!this.selProcUri_)
82     return alert('Must select a process!');
83   $('#ps-tracer-process').val(this.selProcName_);
84   $('#ps-tracer-dialog').dialog('open');
85 };
86
87 this.startTracingSelectedProcess_ = function() {
88   if (!this.selProcUri_)
89     return alert('The process ' + this.selProcUri_ + ' died.');
90   var traceNativeHeap = $('#ps-tracer-bt').prop('checked');
91
92   $('#ps-tracer-dialog').dialog('close');
93
94   if (traceNativeHeap && !devices.getSelectedDevice().isNativeTracingEnabled) {
95     var shouldProvision = confirm('Native heap tracing is not enabled.\n' +
96         'Do you want to enable it (will cause a reboot on Android)?');
97     if (shouldProvision) {
98       devices.initializeSelectedDevice(true);
99       alert('Wait device to complete reboot and then retry.');
100       return;
101     }
102   }
103
104   var postArgs = {interval: $('#ps-tracer-period').val(),
105                   count: $('#ps-tracer-snapshots').val(),
106                   traceNativeHeap: traceNativeHeap};
107
108   webservice.ajaxRequest('/tracer/start/' + this.selProcUri_,
109                          this.onStartTracerAjaxResponse_.bind(this),
110                          null,  // Use default error handler
111                          postArgs);
112 };
113
114 this.onStartTracerAjaxResponse_ = function(data) {
115   this.tracerTaskId_ = data;
116   timers.start('tracer',
117                this.pollTracerStatus_.bind(this),
118                this.TRACER_POLL_INTERVAL_SEC_);
119 };
120
121 this.pollTracerStatus_ = function() {
122   if (!this.tracerTaskId_) {
123     timers.stop('tracer');
124     return;
125   }
126   webservice.ajaxRequest('/tracer/status/' + this.tracerTaskId_,
127                          this.onTracerStatusAjaxResponse_.bind(this));
128 };
129
130 this.onTracerStatusAjaxResponse_ = function(data) {
131   var logMessages = '';
132   var completionRate = 0;
133   data.forEach(function(progress) {
134     completionRate = progress[0];
135     logMessages += '\n' + progress[1];
136   }, this);
137   rootUi.setProgress(completionRate);
138   rootUi.setStatusMessage(logMessages);
139
140   if (completionRate >= 100) {
141     tracerTaskId_ = null;
142     timers.stop('tracer');
143   }
144 };
145
146 this.refreshPsTable = function() {
147   var targetDevUri = devices.getSelectedURI();
148   if (!targetDevUri)
149     return this.stopPsTable();
150
151   var showAllParam = $('#ps-show_all').prop('checked') ? '?all=1' : '';
152   webservice.ajaxRequest('/ps/' + targetDevUri + showAllParam,
153                          this.onPsAjaxResponse_.bind(this),
154                          this.stopPsTable.bind(this));
155 };
156
157 this.startPsTable = function() {
158   timers.start('ps_table',
159                this.refreshPsTable.bind(this),
160                this.PS_INTERVAL_SEC_);
161 };
162
163 this.stopPsTable = function() {
164   this.selProcUri_ = null;
165   this.selProcName_ = null;
166   timers.stop('ps_table');
167 };
168
169 this.onPsTableRowSelect_ = function() {
170   var targetDevUri = devices.getSelectedURI();
171   if (!targetDevUri)
172     return;
173
174   var sel = this.psTable_.getSelection();
175   if (!sel.length || !this.psTableData_)
176     return;
177   var pid = this.psTableData_.getValue(sel[0].row, 0);
178   this.selProcUri_ = targetDevUri + '/' + pid;
179   this.selProcName_ = this.psTableData_.getValue(sel[0].row, 1);
180   this.startSelectedProcessStats();
181 };
182
183 this.onPsAjaxResponse_ = function(data) {
184   this.psTableData_ = new google.visualization.DataTable(data);
185   this.redrawPsTable_();
186 };
187
188 this.redrawPsTable_ = function(data) {
189   if (!this.psTableData_)
190     return;
191
192   // Redraw table preserving sorting info.
193   var sort = this.psTable_.getSortInfo() || {column: -1, ascending: false};
194   this.psTable_.draw(this.psTableData_, {sortColumn: sort.column,
195                                          sortAscending: sort.ascending});
196 };
197
198 this.refreshDeviceStats = function() {
199   var targetDevUri = devices.getSelectedURI();
200   if (!targetDevUri)
201     return this.stopDeviceStats();
202
203   webservice.ajaxRequest('/stats/' + targetDevUri,
204                          this.onDevStatsAjaxResponse_.bind(this),
205                          this.stopDeviceStats.bind(this));
206 };
207
208 this.startDeviceStats = function() {
209   timers.start('device_stats',
210                this.refreshDeviceStats.bind(this),
211                this.DEV_STATS_INTERVAL_SEC_);
212 };
213
214 this.stopDeviceStats = function() {
215   timers.stop('device_stats');
216 };
217
218 this.onDevStatsAjaxResponse_ = function(data) {
219   this.memChartData_ = new google.visualization.DataTable(data.mem);
220   this.cpuChartData_ = new google.visualization.DataTable(data.cpu);
221   this.redrawDevStats_();
222 };
223
224 this.redrawDevStats_ = function(data) {
225   if (!this.memChartData_ || !this.cpuChartData_)
226     return;
227
228   this.memChart_.draw(this.memChartData_,
229                        {title: 'System Memory Usage (MB)', is3D: true});
230   this.cpuChart_.draw(this.cpuChartData_,
231                        {title: 'CPU Usage',
232                         isStacked: true,
233                         hAxis: {maxValue: 100, viewWindow: {max: 100}}});
234 };
235
236 this.refreshSelectedProcessStats = function() {
237   if (!this.selProcUri_)
238     return this.stopSelectedProcessStats();
239
240   webservice.ajaxRequest('/stats/' + this.selProcUri_,
241                          this.onPsStatsAjaxResponse_.bind(this),
242                          this.stopSelectedProcessStats.bind(this));
243 };
244
245 this.startSelectedProcessStats = function() {
246   timers.start('proc_stats',
247                this.refreshSelectedProcessStats.bind(this),
248                this.PROC_STATS_INTERVAL_SEC_);
249   $('#device_tabs').tabs('option', 'active', 1);
250 };
251
252 this.stopSelectedProcessStats = function() {
253   timers.stop('proc_stats');
254 };
255
256 this.onPsStatsAjaxResponse_ = function(data) {
257   this.procCpuChartData_ = new google.visualization.DataTable(data.cpu);
258   this.procMemChartData_ = new google.visualization.DataTable(data.mem);
259   this.redrawPsStats_();
260 };
261
262 this.redrawPsStats_ = function() {
263   if (!this.procCpuChartData_ || !this.procMemChartData_)
264     return;
265
266   this.procCpuChart_.draw(this.procCpuChartData_, {
267       title: 'CPU stats for ' + this.selProcUri_,
268       seriesType: 'line',
269       vAxes: {0: {title: 'CPU %', maxValue: 100}, 1: {title: '# Threads'}},
270       series: {1: {type: 'bars', targetAxisIndex: 1}},
271       hAxis: {title: 'Run Time'},
272       legend: {alignment: 'end'},
273   });
274   this.procMemChart_.draw(this.procMemChartData_, {
275       title: 'Memory stats for ' + this.selProcUri_,
276       seriesType: 'line',
277       vAxes: {0: {title: 'VM Rss KB'}, 1: {title: '# Page Faults'}},
278       series: {1: {type: 'bars', targetAxisIndex: 1}},
279       hAxis: {title: 'Run Time'},
280       legend: {alignment: 'end'},
281   });
282 };
283
284 this.redraw = function() {
285   this.redrawPsTable_();
286   if ($('#device_tabs').tabs('option', 'active') == 0)
287     this.redrawDevStats_();
288   else
289     this.redrawPsStats_();
290 };
291
292 $(document).ready(this.onDomReady_.bind(this));
293
294 })();