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/**
8 * @fileoverview ProfilingView glues the TimelineView control to
9 * TracingController.
10 */
11cr.define('tracing', function() {
12  /**
13   * ProfilingView
14   * @constructor
15   * @extends {ui.TabPanel}
16   */
17  var ProfilingView = cr.ui.define(cr.ui.TabPanel);
18
19  ProfilingView.prototype = {
20    __proto__: cr.ui.TabPanel.prototype,
21
22    traceEvents_: [],
23    systemTraceEvents_: [],
24
25    decorate: function() {
26      cr.ui.TabPanel.prototype.decorate.apply(this);
27      this.classList.add('profiling-view');
28
29      // make the <list>/add/save/record element
30      this.recordBn_ = document.createElement('button');
31      this.recordBn_.className = 'record';
32      this.recordBn_.textContent = 'Record';
33      this.recordBn_.addEventListener('click', this.onRecord_.bind(this));
34
35      this.saveBn_ = document.createElement('button');
36      this.saveBn_.textContent = 'Save';
37      this.saveBn_.addEventListener('click', this.onSave_.bind(this));
38
39      this.loadBn_ = document.createElement('button');
40      this.loadBn_.textContent = 'Load';
41      this.loadBn_.addEventListener('click', this.onLoad_.bind(this));
42
43      if (cr.isChromeOS) {
44        this.systemTracingBn_ = document.createElement('input');
45        this.systemTracingBn_.type = 'checkbox';
46        this.systemTracingBn_.checked = true;
47
48        var systemTracingLabelEl = document.createElement('div');
49        systemTracingLabelEl.className = 'label';
50        systemTracingLabelEl.textContent = 'System events';
51        systemTracingLabelEl.appendChild(this.systemTracingBn_);
52      }
53
54      this.timelineView_ = new tracing.TimelineView();
55      this.timelineView_.leftControls.appendChild(this.recordBn_);
56      this.timelineView_.leftControls.appendChild(this.saveBn_);
57      this.timelineView_.leftControls.appendChild(this.loadBn_);
58      if (cr.isChromeOS)
59        this.timelineView_.leftControls.appendChild(this.systemTracingBn_);
60
61      this.appendChild(this.timelineView_);
62
63      document.addEventListener('keypress', this.onKeypress_.bind(this));
64
65      this.refresh_();
66    },
67
68    didSetTracingController_: function(value, oldValue) {
69      if (oldValue)
70        throw 'Can only set tracing controller once.';
71
72      this.tracingController_.addEventListener('traceEnded',
73          this.onRecordDone_.bind(this));
74      this.tracingController_.addEventListener('loadTraceFileComplete',
75          this.onLoadTraceFileComplete_.bind(this));
76      this.tracingController_.addEventListener('saveTraceFileComplete',
77          this.onSaveTraceFileComplete_.bind(this));
78      this.tracingController_.addEventListener('loadTraceFileCanceled',
79          this.onLoadTraceFileCanceled_.bind(this));
80      this.tracingController_.addEventListener('saveTraceFileCanceled',
81          this.onSaveTraceFileCanceled_.bind(this));
82      this.refresh_();
83    },
84
85    refresh_: function() {
86      if (!this.tracingController_)
87        return;
88
89      var traceEvents = this.tracingController_.traceEvents;
90      var hasEvents = traceEvents && traceEvents.length;
91
92      this.saveBn_.disabled = !hasEvents;
93
94      if (!hasEvents) return;
95
96      var m = new tracing.TimelineModel();
97      m.importEvents(traceEvents, true,
98                     [this.tracingController_.systemTraceEvents]);
99      this.timelineView_.model = m;
100    },
101
102    onKeypress_: function(event) {
103      if (event.keyCode == 114 && !this.tracingController_.isTracingEnabled) {
104        this.onRecord_();
105      }
106    },
107
108    get timelineView() {
109      return this.timelineView_;
110    },
111
112    ///////////////////////////////////////////////////////////////////////////
113
114    onRecord_: function() {
115      var systemTracingEnabled;
116      if (this.systemTracingBn_)
117        systemTracingEnabled = this.systemTracingBn_.checked;
118      else
119        systemTracingEnabled = false;
120      this.tracingController_.beginTracing(systemTracingEnabled);
121    },
122
123    onRecordDone_: function() {
124      this.refresh_();
125    },
126
127    ///////////////////////////////////////////////////////////////////////////
128
129    onSave_: function() {
130      this.overlayEl_ = new tracing.Overlay();
131      this.overlayEl_.className = 'profiling-overlay';
132
133      var labelEl = document.createElement('div');
134      labelEl.className = 'label';
135      labelEl.textContent = 'Saving...';
136      this.overlayEl_.appendChild(labelEl);
137      this.overlayEl_.visible = true;
138
139      this.tracingController_.beginSaveTraceFile();
140    },
141
142    onSaveTraceFileComplete_: function(e) {
143      this.overlayEl_.visible = false;
144      this.overlayEl_ = undefined;
145    },
146
147    onSaveTraceFileCanceled_: function(e) {
148      this.overlayEl_.visible = false;
149      this.overlayEl_ = undefined;
150    },
151
152    ///////////////////////////////////////////////////////////////////////////
153
154    onLoad_: function() {
155      this.overlayEl_ = new tracing.Overlay();
156      this.overlayEl_.className = 'profiling-overlay';
157
158      var labelEl = document.createElement('div');
159      labelEl.className = 'label';
160      labelEl.textContent = 'Loading...';
161      this.overlayEl_.appendChild(labelEl);
162      this.overlayEl_.visible = true;
163
164      this.tracingController_.beginLoadTraceFile();
165    },
166
167    onLoadTraceFileComplete_: function(e) {
168      this.overlayEl_.visible = false;
169      this.overlayEl_ = undefined;
170
171      this.refresh_();
172    },
173
174    onLoadTraceFileCanceled_: function(e) {
175      this.overlayEl_.visible = false;
176      this.overlayEl_ = undefined;
177    }
178  };
179
180  cr.defineProperty(ProfilingView, 'tracingController', cr.PropertyKind.JS,
181                    ProfilingView.prototype.didSetTracingController_);
182
183  return {
184    ProfilingView: ProfilingView
185  };
186});
187