blob: 58f5a71872eea3cbdc94bb77c29b66d6df86ce1a [file] [log] [blame]
Hongchan Choi7dd0b3e2019-05-13 21:19:031// Copyright 2019 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/**
6 * @implements {SDK.SDKModelObserver<!WebAudio.WebAudioModel>}
7 */
8WebAudio.WebAudioView = class extends UI.ThrottledWidget {
9 constructor() {
10 super(true, 1000);
11 this.element.classList.add('web-audio-drawer');
12 this.registerRequiredCSS('web_audio/webAudio.css');
13
14 // Creates the toolbar.
15 const toolbarContainer = this.contentElement.createChild(
16 'div', 'web-audio-toolbar-container vbox');
17 this._contextSelector = new WebAudio.AudioContextSelector(ls`BaseAudioContexts`);
18 const toolbar = new UI.Toolbar('web-audio-toolbar', toolbarContainer);
19 toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));
20 toolbar.appendSeparator();
21 toolbar.appendToolbarItem(this._contextSelector.toolbarItem());
22
23 // Creates the detail view.
24 this._detailViewContainer = this.contentElement.createChild('div', 'vbox flex-auto');
25
26 // Creates the landing page.
27 this._landingPage = new UI.VBox();
28 this._landingPage.contentElement.classList.add('web-audio-landing-page', 'fill');
29 this._landingPage.contentElement.appendChild(UI.html`
30 <div>
31 <p>${ls`Open a page that uses Web Audio API to start monitoring.`}</p>
32 </div>
33 `);
34 this._landingPage.show(this._detailViewContainer);
35
36 // Creates the summary bar.
37 this._summaryBarContainer = this.contentElement.createChild('div', 'web-audio-summary-container');
38
39 this._contextSelector.addEventListener(WebAudio.AudioContextSelector.Events.ContextSelected, event => {
40 const context =
41 /** @type {!Protocol.WebAudio.BaseAudioContext} */ (event.data);
42 this._updateDetailView(context);
43 this.doUpdate();
44 });
45
46 SDK.targetManager.observeModels(WebAudio.WebAudioModel, this);
47 }
48
49 /**
50 * @override
51 */
52 wasShown() {
Hongchan Choide21c962019-06-06 22:15:0853 super.wasShown();
Hongchan Choi7dd0b3e2019-05-13 21:19:0354 for (const model of SDK.targetManager.models(WebAudio.WebAudioModel))
55 this._addEventListeners(model);
56 }
57
58 /**
59 * @override
60 */
61 willHide() {
62 for (const model of SDK.targetManager.models(WebAudio.WebAudioModel))
63 this._removeEventListeners(model);
64 }
65
66 /**
67 * @override
68 * @param {!WebAudio.WebAudioModel} webAudioModel
69 */
70 modelAdded(webAudioModel) {
71 if (this.isShowing())
72 this._addEventListeners(webAudioModel);
73 }
74
75 /**
76 * @override
77 * @param {!WebAudio.WebAudioModel} webAudioModel
78 */
79 modelRemoved(webAudioModel) {
80 this._removeEventListeners(webAudioModel);
81 }
82
83 /**
84 * @override
85 * @return {!Promise<?>}
86 */
87 async doUpdate() {
88 await this._pollRealtimeData();
89 this.update();
90 }
91
92 /**
93 * @param {!WebAudio.WebAudioModel} webAudioModel
94 */
95 _addEventListeners(webAudioModel) {
96 webAudioModel.ensureEnabled();
97 webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextCreated, this._contextCreated, this);
98 webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextDestroyed, this._contextDestroyed, this);
99 webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextChanged, this._contextChanged, this);
Hongchan Choi2aae57a2019-05-23 20:42:41100 webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ModelReset, this._reset, this);
Hongchan Choi7dd0b3e2019-05-13 21:19:03101 }
102
103 /**
104 * @param {!WebAudio.WebAudioModel} webAudioModel
105 */
106 _removeEventListeners(webAudioModel) {
107 webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextCreated, this._contextCreated, this);
108 webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextDestroyed, this._contextDestroyed, this);
109 webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextChanged, this._contextChanged, this);
Hongchan Choi2aae57a2019-05-23 20:42:41110 webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ModelReset, this._reset, this);
Hongchan Choi7dd0b3e2019-05-13 21:19:03111 }
112
113 /**
114 * @param {!Common.Event} event
115 */
116 _contextCreated(event) {
117 this._contextSelector.contextCreated(event);
118 }
119
120 /**
121 * @param {!Common.Event} event
122 */
123 _contextDestroyed(event) {
124 this._contextSelector.contextDestroyed(event);
125 }
126
127 /**
128 * @param {!Common.Event} event
129 */
130 _contextChanged(event) {
131 this._contextSelector.contextChanged(event);
132 }
133
134 _reset() {
135 if (this._landingPage.isShowing())
136 this._landingPage.detach();
137 this._contextSelector.reset();
138 this._detailViewContainer.removeChildren();
139 this._landingPage.show(this._detailViewContainer);
140 }
141
142 /**
143 * @param {!Protocol.WebAudio.BaseAudioContext} context
144 */
145 _updateDetailView(context) {
146 if (this._landingPage.isShowing())
147 this._landingPage.detach();
148 const detailBuilder = new WebAudio.ContextDetailBuilder(context);
149 this._detailViewContainer.removeChildren();
150 this._detailViewContainer.appendChild(detailBuilder.getFragment());
151 }
152
153 /**
Hongchan Choi65088332019-08-08 01:12:33154 * @param {!Protocol.WebAudio.GraphObjectId} contextId
Hongchan Choi7dd0b3e2019-05-13 21:19:03155 * @param {!Protocol.WebAudio.ContextRealtimeData} contextRealtimeData
156 */
157 _updateSummaryBar(contextId, contextRealtimeData) {
158 const summaryBuilder =
159 new WebAudio.AudioContextSummaryBuilder(contextId, contextRealtimeData);
160 this._summaryBarContainer.removeChildren();
161 this._summaryBarContainer.appendChild(summaryBuilder.getFragment());
162 }
163
164 _clearSummaryBar() {
165 this._summaryBarContainer.removeChildren();
166 }
167
168 async _pollRealtimeData() {
169 const context = this._contextSelector.selectedContext();
170 if (!context) {
171 this._clearSummaryBar();
172 return;
173 }
174
175 for (const model of SDK.targetManager.models(WebAudio.WebAudioModel)) {
176 // Display summary only for real-time context.
177 if (context.contextType === 'realtime') {
178 const realtimeData = await model.requestRealtimeData(context.contextId);
Hongchan Choi17a74252019-06-05 18:27:58179 if (realtimeData)
Hongchan Choi7dd0b3e2019-05-13 21:19:03180 this._updateSummaryBar(context.contextId, realtimeData);
181 } else {
182 this._clearSummaryBar();
183 }
184 }
185 }
186};