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

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

Issue 2443573003: Factor out AudioOutputDelegate from AudioRendererHost. (Closed)
Patch Set: . Created 4 years 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 int stream_id,
21 int render_frame_id,
22 int render_process_id,
23 const media::AudioParameters& params,
24 const std::string& output_device_id)
25 : handler_(handler),
26 audio_log_(std::move(audio_log)),
27 reader_(AudioSyncReader::Create(params)),
28 controller_(media::AudioOutputController::Create(audio_manager,
DaleCurtis 2016/11/29 20:31:22 This should probably be constructed last since it'
29 this,
30 params,
31 output_device_id,
32 reader_.get())),
33 stream_id_(stream_id),
34 render_frame_id_(render_frame_id),
35 render_process_id_(render_process_id),
36 weak_factory_(this) {
37 DCHECK(handler_);
38 DCHECK(audio_manager);
39 DCHECK(audio_log_);
40 DCHECK(controller_);
41 audio_log_->OnCreated(stream_id, params, output_device_id);
42 }
43
44 AudioOutputDelegate::~AudioOutputDelegate() {
45 DCHECK_CURRENTLY_ON(BrowserThread::IO);
46 DCHECK(!playing_);
47 DCHECK(!handler_);
48 }
49
50 void AudioOutputDelegate::Deleter::operator()(AudioOutputDelegate* delegate) {
51 DCHECK_CURRENTLY_ON(BrowserThread::IO);
52 delegate->UpdatePlayingState(false);
53 delegate->handler_ = nullptr;
54 delegate->audio_log_->OnClosed(delegate->stream_id_);
55
DaleCurtis 2016/11/29 20:31:22 Early return if !mirroring_manager (don't forget t
miu 2016/11/29 21:36:27 Should only be. IIRC, the only reason the mirrorin
Max Morin 2016/12/01 16:08:37 We must wait until the controller is closed before
56 scoped_refptr<media::AudioOutputController> controller =
DaleCurtis 2016/11/29 20:31:22 .swap?
57 delegate->controller_;
58
59 // |controller| will call the closure (on IO thread) when it's done closing,
60 // and it is only after that call that we can delete |delegate|. By giving the
61 // closure ownership of |delegate|, we keep delegate alive until |controller|
62 // is closed.
63 //
64 // The mirroring manager is a singleton, so Unretained is fine.
65 delegate->controller_->Close(base::Bind(
66 [](AudioOutputDelegate*, AudioMirroringManager* mirroring_manager,
67 scoped_refptr<media::AudioOutputController> controller) {
68 // De-register the controller from the AudioMirroringManager now that
69 // the controller has closed the AudioOutputStream and shut itself down.
70 // This ensures that calling RemoveDiverter() here won't trigger the
71 // controller to re-start the default AudioOutputStream and cause a
72 // brief audio blip to come out the user's speakers.
73 // http://crbug.com/474432
74 //
75 // It's fine if the task is canceled during shutdown, since the
76 // mirroring manager doesn't require that all diverters are
77 // removed.
78 if (mirroring_manager)
79 mirroring_manager->RemoveDiverter(controller.get());
80 },
81 base::Owned(delegate), base::Unretained(mirroring_manager_), controller));
DaleCurtis 2016/11/29 20:31:23 std::move(controller)?
Max Morin 2016/12/01 16:08:37 I simplified this code, PTAL.
82 }
83
84 // static
85 AudioOutputDelegate::UniquePtr AudioOutputDelegate::Create(
86 EventHandler* handler,
87 media::AudioManager* audio_manager,
88 std::unique_ptr<media::AudioLog> audio_log,
89 AudioMirroringManager* mirroring_manager,
90 MediaObserver* media_observer,
91 int stream_id,
92 int render_frame_id,
93 int render_process_id,
94 const media::AudioParameters& params,
95 const std::string& output_device_id) {
96 if (media_observer)
97 media_observer->OnCreatingAudioStream(render_process_id, render_frame_id);
98 UniquePtr delegate = UniquePtr(
99 new AudioOutputDelegate(handler, audio_manager, std::move(audio_log),
100 stream_id, render_frame_id, render_process_id,
101 params, output_device_id),
102 Deleter(mirroring_manager));
103 if (mirroring_manager)
104 mirroring_manager->AddDiverter(render_process_id, render_frame_id,
105 delegate->controller_.get());
106 return delegate;
107 }
108
109 void AudioOutputDelegate::OnPlayStream() {
110 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 controller_->Play();
112 audio_log_->OnStarted(stream_id_);
113 }
114
115 void AudioOutputDelegate::OnPauseStream() {
116 DCHECK_CURRENTLY_ON(BrowserThread::IO);
117 controller_->Pause();
118 audio_log_->OnStopped(stream_id_);
119 }
120
121 void AudioOutputDelegate::OnSetVolume(double volume) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO);
123 DCHECK(volume >= 0 && volume <= 1);
DaleCurtis 2016/11/29 20:31:23 Separate into DCHECK_GE() and DCHECK_LE() for easi
124 controller_->SetVolume(volume);
125 audio_log_->OnSetVolume(stream_id_, volume);
126 }
127
128 void AudioOutputDelegate::OnControllerCreated() {
129 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
130 BrowserThread::PostTask(
131 BrowserThread::IO, FROM_HERE,
132 base::Bind(&AudioOutputDelegate::OnControllerCreated,
133 weak_factory_.GetWeakPtr()));
DaleCurtis 2016/11/29 20:31:22 Precreate a weak_this_ during construction and use
134 return;
135 }
136 if (!handler_)
137 return;
138
139 handler_->OnStreamCreated(stream_id_, reader_->shared_memory(),
140 reader_->foreign_socket());
141 }
142
143 void AudioOutputDelegate::OnControllerPlaying() {
144 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
DaleCurtis 2016/11/29 20:31:23 This block (l.144-l.152) is repeated fairly regula
miu 2016/11/29 21:36:27 Or...Just unconditionally post the task, regardles
Max Morin 2016/12/01 16:08:37 I was not aware of the "no private inheritance" ru
145 BrowserThread::PostTask(
146 BrowserThread::IO, FROM_HERE,
147 base::Bind(&AudioOutputDelegate::OnControllerPlaying,
148 weak_factory_.GetWeakPtr()));
miu 2016/11/29 21:36:27 GetWeakPtr() is not thread-safe in this situation
149 return;
150 }
151 if (!handler_)
152 return;
153
154 UpdatePlayingState(true);
155 }
156
157 void AudioOutputDelegate::OnControllerPaused() {
158 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
159 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
160 base::Bind(&AudioOutputDelegate::OnControllerPaused,
161 weak_factory_.GetWeakPtr()));
162 return;
163 }
164 if (!handler_)
165 return;
166
167 UpdatePlayingState(false);
168 }
169
170 void AudioOutputDelegate::OnControllerError() {
171 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
172 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
173 base::Bind(&AudioOutputDelegate::OnControllerError,
174 weak_factory_.GetWeakPtr()));
175 return;
176 }
177 audio_log_->OnError(stream_id_);
DaleCurtis 2016/11/29 20:31:23 Why the exception for handler_ here?
DaleCurtis 2016/11/29 20:31:23 Why the exception for handler_ here?
178
179 if (!handler_)
180 return;
181
182 handler_->OnStreamError(stream_id_);
183 }
184
185 void AudioOutputDelegate::UpdatePlayingState(bool playing) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO);
187 DCHECK(handler_);
188 if (playing != playing_) {
DaleCurtis 2016/11/29 20:31:22 If playing == playing_ return.
189 playing_ = playing;
190 handler_->OnStreamStateChanged(playing_);
191 if (playing) {
192 // Note that this takes a reference to |controller_|, and
193 // (Start|Stop)MonitoringStream calls are async, so we don't have a
194 // guarantee for when the controller is destroyed.
195 AudioStreamMonitor::StartMonitoringStream(
196 render_process_id_, render_frame_id_, stream_id_,
197 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip,
198 controller_));
199 } else {
200 AudioStreamMonitor::StopMonitoringStream(render_process_id_,
201 render_frame_id_, stream_id_);
202 }
203 }
204 }
205
206 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698