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

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/capture/audio_mirroring_manager.h"
12 #include "content/browser/media/media_internals.h"
13 #include "content/browser/renderer_host/media/audio_sync_reader.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/media_observer.h"
16
17 namespace content {
18
19 AudioOutputDelegate::AudioOutputDelegate(
20 EventHandler* handler,
21 media::AudioManager* audio_manager,
22 std::unique_ptr<media::AudioLog> audio_log,
23 int stream_id,
24 int render_frame_id,
25 int render_process_id,
26 const media::AudioParameters& params,
27 const std::string& output_device_id)
28 : handler_(handler),
29 audio_log_(std::move(audio_log)),
30 reader_(AudioSyncReader::Create(params)),
31 stream_id_(stream_id),
32 render_frame_id_(render_frame_id),
33 render_process_id_(render_process_id),
34 weak_factory_(this) {
35 DCHECK(handler_);
36 DCHECK(audio_manager);
37 DCHECK(audio_log_);
38 weak_this_ = weak_factory_.GetWeakPtr();
39 controller_ = media::AudioOutputController::Create(
DaleCurtis 2016/12/01 19:33:07 Has to be very last call to avoid any risks.
40 audio_manager, this, params, output_device_id, reader_.get());
41 DCHECK(controller_);
42 audio_log_->OnCreated(stream_id, params, output_device_id);
43 }
44
45 AudioOutputDelegate::~AudioOutputDelegate() {
46 DCHECK_CURRENTLY_ON(BrowserThread::IO);
47 DCHECK(!playing_);
48 DCHECK(!handler_);
49 }
50
51 void AudioOutputDelegate::Deleter::operator()(AudioOutputDelegate* delegate) {
52 DCHECK_CURRENTLY_ON(BrowserThread::IO);
53 delegate->UpdatePlayingState(false);
54 delegate->handler_ = nullptr;
55 delegate->audio_log_->OnClosed(delegate->stream_id_);
56
57 // |controller| will call the closure (on IO thread) when it's done closing,
58 // and it is only after that call that we can delete |delegate|. By giving the
59 // closure ownership of |delegate|, we keep delegate alive until |controller|
60 // is closed.
61 //
62 // The mirroring manager is a singleton, so Unretained is fine.
63 delegate->controller_->Close(base::Bind(
64 [](AudioOutputDelegate* delegate,
65 AudioMirroringManager* mirroring_manager) {
66 // De-register the controller from the AudioMirroringManager now that
67 // the controller has closed the AudioOutputStream and shut itself down.
68 // This ensures that calling RemoveDiverter() here won't trigger the
69 // controller to re-start the default AudioOutputStream and cause a
70 // brief audio blip to come out the user's speakers.
71 // http://crbug.com/474432
72 //
73 // It's fine if the task is canceled during shutdown, since the
74 // mirroring manager doesn't require that all diverters are
75 // removed.
76 if (mirroring_manager)
77 mirroring_manager->RemoveDiverter(delegate->controller_.get());
78 },
79 base::Owned(delegate), base::Unretained(mirroring_manager_)));
80 }
81
82 // static
83 AudioOutputDelegate::ScopedPtr AudioOutputDelegate::Create(
84 EventHandler* handler,
85 media::AudioManager* audio_manager,
86 std::unique_ptr<media::AudioLog> audio_log,
87 AudioMirroringManager* mirroring_manager,
88 MediaObserver* media_observer,
89 int stream_id,
90 int render_frame_id,
91 int render_process_id,
92 const media::AudioParameters& params,
93 const std::string& output_device_id) {
94 if (media_observer)
95 media_observer->OnCreatingAudioStream(render_process_id, render_frame_id);
96 ScopedPtr delegate = ScopedPtr(
DaleCurtis 2016/12/01 19:33:07 Should be able to just do ScopedPtr delegate(new .
97 new AudioOutputDelegate(handler, audio_manager, std::move(audio_log),
98 stream_id, render_frame_id, render_process_id,
99 params, output_device_id),
100 Deleter(mirroring_manager));
101 if (mirroring_manager)
102 mirroring_manager->AddDiverter(render_process_id, render_frame_id,
103 delegate->controller_.get());
104 return delegate;
105 }
106
107 void AudioOutputDelegate::OnPlayStream() {
108 DCHECK_CURRENTLY_ON(BrowserThread::IO);
109 controller_->Play();
110 audio_log_->OnStarted(stream_id_);
111 }
112
113 void AudioOutputDelegate::OnPauseStream() {
114 DCHECK_CURRENTLY_ON(BrowserThread::IO);
115 controller_->Pause();
116 audio_log_->OnStopped(stream_id_);
117 }
118
119 void AudioOutputDelegate::OnSetVolume(double volume) {
120 DCHECK_CURRENTLY_ON(BrowserThread::IO);
121 DCHECK_GE(volume, 0);
122 DCHECK_LE(volume, 1);
123 controller_->SetVolume(volume);
124 audio_log_->OnSetVolume(stream_id_, volume);
125 }
126
127 void AudioOutputDelegate::OnControllerCreated() {
128 BrowserThread::PostTask(
129 BrowserThread::IO, FROM_HERE,
130 base::Bind(&AudioOutputDelegate::SendCreatedNotification, weak_this_));
131 }
132
133 void AudioOutputDelegate::OnControllerPlaying() {
134 BrowserThread::PostTask(
135 BrowserThread::IO, FROM_HERE,
136 base::Bind(&AudioOutputDelegate::UpdatePlayingState, weak_this_, true));
137 }
138
139 void AudioOutputDelegate::OnControllerPaused() {
140 BrowserThread::PostTask(
141 BrowserThread::IO, FROM_HERE,
142 base::Bind(&AudioOutputDelegate::UpdatePlayingState, weak_this_, false));
143 }
144
145 void AudioOutputDelegate::OnControllerError() {
146 BrowserThread::PostTask(
147 BrowserThread::IO, FROM_HERE,
148 base::Bind(&AudioOutputDelegate::OnError, weak_this_));
149 }
150
151 void AudioOutputDelegate::SendCreatedNotification() {
152 DCHECK_CURRENTLY_ON(BrowserThread::IO);
153 if (handler_)
DaleCurtis 2016/12/01 19:33:06 Multiline if needs {} or just early return.
154 handler_->OnStreamCreated(stream_id_, reader_->shared_memory(),
155 reader_->foreign_socket());
156 }
157
158 void AudioOutputDelegate::UpdatePlayingState(bool playing) {
159 DCHECK_CURRENTLY_ON(BrowserThread::IO);
160 if (!handler_ || playing == playing_)
161 return;
162
163 playing_ = playing;
164 handler_->OnStreamStateChanged(playing);
165 if (playing) {
166 // Note that this takes a reference to |controller_|, and
167 // (Start|Stop)MonitoringStream calls are async, so we don't have a
168 // guarantee for when the controller is destroyed.
169 AudioStreamMonitor::StartMonitoringStream(
170 render_process_id_, render_frame_id_, stream_id_,
171 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip,
172 controller_));
173 } else {
174 AudioStreamMonitor::StopMonitoringStream(render_process_id_,
175 render_frame_id_, stream_id_);
176 }
177 }
178
179 void AudioOutputDelegate::OnError() {
180 DCHECK_CURRENTLY_ON(BrowserThread::IO);
181
182 if (!handler_)
183 return;
184
185 audio_log_->OnError(stream_id_);
186 handler_->OnStreamError(stream_id_);
187 }
188
189 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698