Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / importer / linux_perf / android_parser.html
1 <!DOCTYPE html>
2 <!--
3 Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7
8 <link rel="import" href="/tracing/importer/linux_perf/parser.html">
9 <link rel="import" href="/tracing/trace_model/counter_series.html">
10
11 <script>
12 'use strict';
13
14 /**
15  * @fileoverview Parses trace_marker events that were inserted in the trace by
16  * userland.
17  */
18 tvcm.exportTo('tracing.importer.linux_perf', function() {
19   var Parser = tracing.importer.linux_perf.Parser;
20
21   /**
22    * Parses linux trace mark events that were inserted in the trace by userland.
23    * @constructor
24    */
25   function AndroidParser(importer) {
26     Parser.call(this, importer);
27
28     importer.registerEventHandler('tracing_mark_write:android',
29         AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));
30     importer.registerEventHandler('0:android',
31         AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));
32
33     this.model_ = importer.model_;
34     this.ppids_ = {};
35   }
36
37   function parseArgs(argsString) {
38     var args = {};
39     if (argsString) {
40       var argsArray = argsString.split(';');
41       for (var i = 0; i < argsArray.length; ++i) {
42         var parts = argsArray[i].split('=');
43         if (parts[0])
44           args[parts.shift()] = parts.join('=');
45       }
46     }
47     return args;
48   }
49
50   AndroidParser.prototype = {
51     __proto__: Parser.prototype,
52
53     openAsyncSlice: function(thread, category, name, cookie, ts, args) {
54       var slice = new tracing.trace_model.AsyncSlice(
55           category, name, tvcm.ui.getStringColorId(name), ts, args);
56       var key = category + ':' + name + ':' + cookie;
57       slice.id = cookie;
58       slice.startThread = thread;
59
60       if (!this.openAsyncSlices) {
61         this.openAsyncSlices = { };
62       }
63       this.openAsyncSlices[key] = slice;
64     },
65
66     closeAsyncSlice: function(thread, category, name, cookie, ts, args) {
67       if (!this.openAsyncSlices) {
68         // No async slices have been started.
69         return;
70       }
71
72       var key = category + ':' + name + ':' + cookie;
73       var slice = this.openAsyncSlices[key];
74       if (!slice) {
75         // No async slices w/ this key have been started.
76         return;
77       }
78
79       for (var arg in args) {
80         if (slice.args[arg] !== undefined) {
81           this.model_.importWarning({
82             type: 'parse_error',
83             message: 'Both the S and F events of ' + slice.title +
84                 ' provided values for argument ' + arg + '.' +
85                 ' The value of the F event will be used.'
86           });
87         }
88         slice.args[arg] = args[arg];
89       }
90
91       slice.endThread = thread;
92       slice.duration = ts - slice.start;
93       slice.startThread.asyncSliceGroup.push(slice);
94       slice.subSlices = [new tracing.trace_model.Slice(slice.category,
95           slice.title, slice.colorId, slice.start, slice.args, slice.duration)];
96       delete this.openAsyncSlices[key];
97     },
98
99     traceMarkWriteAndroidEvent: function(eventName, cpuNumber, pid, ts,
100                                   eventBase) {
101       var eventData = eventBase.details.split('|');
102       switch (eventData[0]) {
103         case 'B':
104           var ppid = parseInt(eventData[1]);
105           var title = eventData[2];
106           var args = parseArgs(eventData[3]);
107           var category = eventData[4];
108           var thread = this.model_.getOrCreateProcess(ppid)
109               .getOrCreateThread(pid);
110           thread.name = eventBase.threadName;
111           if (!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)) {
112             this.model_.importWarning({
113               type: 'parse_error',
114               message: 'Timestamps are moving backward.'
115             });
116             return false;
117           }
118
119           this.ppids_[pid] = ppid;
120           thread.sliceGroup.beginSlice(category, title, ts, args);
121
122           break;
123
124         case 'E':
125           var ppid = this.ppids_[pid];
126           if (ppid === undefined) {
127             // Silently ignore unmatched E events.
128             break;
129           }
130
131           var thread = this.model_.getOrCreateProcess(ppid)
132               .getOrCreateThread(pid);
133           if (!thread.sliceGroup.openSliceCount) {
134             // Silently ignore unmatched E events.
135             break;
136           }
137
138           var slice = thread.sliceGroup.endSlice(ts);
139
140           var args = parseArgs(eventData[3]);
141           for (var arg in args) {
142             if (slice.args[arg] !== undefined) {
143               this.model_.importWarning({
144                 type: 'parse_error',
145                 message: 'Both the B and E events of ' + slice.title +
146                     ' provided values for argument ' + arg + '.' +
147                     ' The value of the E event will be used.'
148               });
149             }
150             slice.args[arg] = args[arg];
151           }
152
153           break;
154
155         case 'C':
156           var ppid = parseInt(eventData[1]);
157           var name = eventData[2];
158           var value = parseInt(eventData[3]);
159           var category = eventData[4];
160
161           var ctr = this.model_.getOrCreateProcess(ppid)
162               .getOrCreateCounter(category, name);
163           // Initialize the counter's series fields if needed.
164           if (ctr.numSeries === 0) {
165             ctr.addSeries(new tracing.trace_model.CounterSeries(value,
166                 tvcm.ui.getStringColorId(ctr.name + '.' + 'value')));
167           }
168
169           ctr.series.forEach(function(series) {
170             series.addCounterSample(ts, value);
171           });
172
173           break;
174
175         case 'S':
176           var ppid = parseInt(eventData[1]);
177           var name = eventData[2];
178           var cookie = parseInt(eventData[3]);
179           var args = parseArgs(eventData[4]);
180           var category = eventData[5];
181
182           var thread = this.model_.getOrCreateProcess(ppid)
183             .getOrCreateThread(pid);
184           thread.name = eventBase.threadName;
185
186           this.ppids_[pid] = ppid;
187           this.openAsyncSlice(thread, category, name, cookie, ts, args);
188
189           break;
190
191         case 'F':
192           var ppid = parseInt(eventData[1]);
193           if (ppid === undefined) {
194             // Silently ignore unmatched F events.
195             break;
196           }
197
198           var thread = this.model_.getOrCreateProcess(ppid)
199             .getOrCreateThread(pid);
200
201           var name = eventData[2];
202           var cookie = parseInt(eventData[3]);
203           var args = parseArgs(eventData[4]);
204           var category = eventData[5];
205
206           this.closeAsyncSlice(thread, category, name, cookie, ts, args);
207
208           break;
209
210         default:
211           return false;
212       }
213
214       return true;
215     }
216   };
217
218   Parser.registerSubtype(AndroidParser);
219
220   return {
221     AndroidParser: AndroidParser
222   };
223 });
224 </script>