Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: content/browser/renderer_host/media/audio_output_delegate.cc

Issue 2443573003: Factor out AudioOutputDelegate from AudioRendererHost. (Closed)
Patch Set: Rebase. Comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "content/browser/renderer_host/media/audio_output_delegate.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "content/browser/media/audio_stream_monitor.h"
11 #include "content/browser/media/media_internals.h"
12 #include "content/public/browser/browser_thread.h"
13
14 namespace content {
15
16 AudioOutputDelegate::AudioOutputDelegate(
17 EventHandler* handler,
18 media::AudioManager* audio_manager,
19 std::unique_ptr<media::AudioLog> audio_log,
20 AudioMirroringManager* mirroring_manager,
21 MediaObserver* media_observer,
22 int stream_id,
23 int render_frame_id,
24 int render_process_id,
25 const media::AudioParameters& params,
26 const std::string& output_device_id)
27 : handler_(handler),
28 audio_log_(std::move(audio_log)),
29 mirroring_manager_(mirroring_manager),
30 reader_(AudioSyncReader::Create(params)),
31 controller_(media::AudioOutputController::Create(audio_manager,
32 this,
33 params,
34 output_device_id,
35 reader_.get())),
36 stream_id_(stream_id),
37 render_frame_id_(render_frame_id),
38 render_process_id_(render_process_id),
39 weak_factory_(this) {
40 DCHECK(handler_);
41 DCHECK(audio_log_);
42 DCHECK(controller_);
43 if (media_observer)
o1ka 2016/11/22 13:24:03 Do it in Create() instead?
Max Morin 2016/11/22 16:04:29 Done.
44 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id_);
45 if (mirroring_manager_)
o1ka 2016/11/22 13:24:03 Instead of keeping pointer in AudioOutputDelegate,
Max Morin 2016/11/22 16:04:29 Very well. Seems like it just makes the code more
o1ka 2016/11/22 21:48:16 To me it looks fine. Maybe replacing Owned and lam
Max Morin 2016/11/25 15:32:35 This is fine. Another possibility: ScopedDiverterR
46 mirroring_manager_->AddDiverter(render_process_id_, render_frame_id_,
47 controller_.get());
48
49 audio_log_->OnCreated(stream_id, params, output_device_id);
50 }
51
52 AudioOutputDelegate::~AudioOutputDelegate() {
53 DCHECK_CURRENTLY_ON(BrowserThread::IO);
54 DCHECK(!playing_);
55 DCHECK(!handler_);
56
57 // De-register the controller from the AudioMirroringManager now that the
58 // controller has closed the AudioOutputStream and shut itself down. This
59 // ensures that calling RemoveDiverter() here won't trigger the controller to
60 // re-start the default AudioOutputStream and cause a brief audio blip to come
61 // out the user's speakers. http://crbug.com/474432
62 mirroring_manager_->RemoveDiverter(controller_.get());
63 }
64
65 void AudioOutputDelegate::Deleter::operator()(AudioOutputDelegate* delegate) {
66 DCHECK_CURRENTLY_ON(BrowserThread::IO);
67 delegate->UpdatePlayingState(false);
68 delegate->handler_ = nullptr;
69 delegate->audio_log_->OnClosed(delegate->stream_id_);
70 // |controller_| will call the closure (on IO thread) when it's done closing,
71 // and it is only after that call that we can delete |delegate|. By giving the
72 // closure ownership of |delegate|, we keep delegate alive until |controller_|
73 // is closed.
74 delegate->controller_->Close(
75 base::Bind([](AudioOutputDelegate*) {}, base::Owned(delegate)));
76 }
77
78 // static
79 AudioOutputDelegate::UniquePtr AudioOutputDelegate::Create(
80 EventHandler* handler,
81 media::AudioManager* audio_manager,
82 std::unique_ptr<media::AudioLog> audio_log,
83 AudioMirroringManager* mirroring_manager,
84 MediaObserver* media_observer,
85 int stream_id,
86 int render_frame_id,
87 int render_process_id,
88 const media::AudioParameters& params,
89 const std::string& output_device_id) {
90 return UniquePtr(new AudioOutputDelegate(
91 handler, audio_manager, std::move(audio_log), mirroring_manager,
92 media_observer, stream_id, render_frame_id, render_process_id, params,
93 output_device_id));
94 }
95
96 void AudioOutputDelegate::OnPlayStream() {
97 DCHECK_CURRENTLY_ON(BrowserThread::IO);
98 controller_->Play();
99 audio_log_->OnStarted(stream_id_);
100 }
101
102 void AudioOutputDelegate::OnPauseStream() {
103 DCHECK_CURRENTLY_ON(BrowserThread::IO);
104 controller_->Pause();
105 audio_log_->OnStopped(stream_id_);
106 }
107
108 void AudioOutputDelegate::OnSetVolume(double volume) {
109 DCHECK_CURRENTLY_ON(BrowserThread::IO);
110 controller_->SetVolume(volume);
o1ka 2016/11/22 13:24:03 We may want to sanitize volume here (https://cs.ch
Max Morin 2016/11/22 16:04:29 Makes more sense to sanitize in the IPC layer. Ide
o1ka 2016/11/22 21:48:16 Acknowledged.
111 audio_log_->OnSetVolume(stream_id_, volume);
112 }
113
114 void AudioOutputDelegate::OnControllerCreated() {
115 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
116 BrowserThread::PostTask(
117 BrowserThread::IO, FROM_HERE,
118 base::Bind(&AudioOutputDelegate::OnControllerCreated,
119 weak_factory_.GetWeakPtr()));
120 return;
121 }
122 if (!handler_)
123 return;
124
125 handler_->OnStreamCreated(stream_id_, reader_->shared_memory(),
126 reader_->foreign_socket());
127 }
128
129 void AudioOutputDelegate::OnControllerPlaying() {
130 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
131 BrowserThread::PostTask(
132 BrowserThread::IO, FROM_HERE,
133 base::Bind(&AudioOutputDelegate::OnControllerPlaying,
134 weak_factory_.GetWeakPtr()));
135 return;
136 }
137 if (!handler_)
138 return;
139
140 UpdatePlayingState(true);
141 }
142
143 void AudioOutputDelegate::OnControllerPaused() {
144 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
145 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
146 base::Bind(&AudioOutputDelegate::OnControllerPaused,
147 weak_factory_.GetWeakPtr()));
148 return;
149 }
150 if (!handler_)
151 return;
152
153 UpdatePlayingState(false);
154 }
155
156 void AudioOutputDelegate::OnControllerError() {
157 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
158 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
159 base::Bind(&AudioOutputDelegate::OnControllerError,
160 weak_factory_.GetWeakPtr()));
161 return;
162 }
163 audio_log_->OnError(stream_id_);
164
165 if (!handler_)
166 return;
167
168 handler_->OnStreamError(stream_id_);
169 }
170
171 void AudioOutputDelegate::UpdatePlayingState(bool playing) {
172 DCHECK_CURRENTLY_ON(BrowserThread::IO);
173 DCHECK(handler_);
174 if (playing != playing_) {
175 playing_ = playing;
176 handler_->OnStreamStateChanged(playing_);
177 if (playing) {
178 // Note that this takes a reference to |controller_|, and
o1ka 2016/11/22 13:24:03 (just in case you are fixing nits I pointed to: ex
Max Morin 2016/11/22 16:04:29 Acknowledged.
179 // (Start|Stop)MonitoringStream calls are async, so we don't have a
180 // guarantee for when the controller is destroyed.
181 AudioStreamMonitor::StartMonitoringStream(
182 render_process_id_, render_frame_id_, stream_id_,
183 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip,
184 controller_));
185 } else {
186 AudioStreamMonitor::StopMonitoringStream(render_process_id_,
187 render_frame_id_, stream_id_);
188 }
189 }
190 }
191
192 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698