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

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

Issue 1896883002: Mojo interfaces needed for switching audio rendering stream creation and closing from IPC to Mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 months 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 #if defined(OS_WIN)
10 #include <windows.h>
11 #endif
9 12
10 #include "base/bind.h" 13 #include "base/bind.h"
11 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
12 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
13 #include "base/logging.h" 16 #include "base/logging.h"
14 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
16 #include "base/process/process.h" 18 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 19 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 20 #include "content/browser/browser_main_loop.h"
19 #include "content/browser/child_process_security_policy_impl.h" 21 #include "content/browser/child_process_security_policy_impl.h"
22 #include "content/browser/media/audio_output_impl.h"
20 #include "content/browser/media/audio_stream_monitor.h" 23 #include "content/browser/media/audio_stream_monitor.h"
21 #include "content/browser/media/capture/audio_mirroring_manager.h" 24 #include "content/browser/media/capture/audio_mirroring_manager.h"
22 #include "content/browser/media/media_internals.h" 25 #include "content/browser/media/media_internals.h"
23 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 26 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
24 #include "content/browser/renderer_host/media/audio_sync_reader.h" 27 #include "content/browser/renderer_host/media/audio_sync_reader.h"
25 #include "content/browser/renderer_host/media/media_stream_manager.h" 28 #include "content/browser/renderer_host/media/media_stream_manager.h"
26 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 29 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
27 #include "content/browser/renderer_host/render_widget_host_impl.h" 30 #include "content/browser/renderer_host/render_widget_host_impl.h"
28 #include "content/common/media/audio_messages.h" 31 #include "content/common/media/audio_messages.h"
29 #include "content/public/browser/content_browser_client.h" 32 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/media_device_id.h" 33 #include "content/public/browser/media_device_id.h"
31 #include "content/public/browser/media_observer.h" 34 #include "content/public/browser/media_observer.h"
32 #include "content/public/browser/render_frame_host.h" 35 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/common/content_switches.h" 36 #include "content/public/common/content_switches.h"
34 #include "media/audio/audio_device_name.h" 37 #include "media/audio/audio_device_name.h"
35 #include "media/audio/audio_manager_base.h" 38 #include "media/audio/audio_manager_base.h"
36 #include "media/audio/audio_streams_tracker.h" 39 #include "media/audio/audio_streams_tracker.h"
37 #include "media/base/audio_bus.h" 40 #include "media/base/audio_bus.h"
38 #include "media/base/limits.h" 41 #include "media/base/limits.h"
42 #include "mojo/edk/embedder/embedder.h"
43 #include "mojo/public/cpp/system/handle.h"
39 44
40 using media::AudioBus; 45 using media::AudioBus;
41 using media::AudioManager; 46 using media::AudioManager;
42 47
43 namespace content { 48 namespace content {
44 49
45 namespace { 50 namespace {
46 51
47 // Tracks the maximum number of simultaneous output streams browser-wide. 52 // Tracks the maximum number of simultaneous output streams browser-wide.
48 // Accessed on IO thread. 53 // Accessed on IO thread.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 params->set_channels_for_discrete(media::limits::kMaxChannels); 115 params->set_channels_for_discrete(media::limits::kMaxChannels);
111 116
112 // If hardware parameters are still invalid, use dummy parameters with 117 // If hardware parameters are still invalid, use dummy parameters with
113 // fake audio path and let the client handle the error. 118 // fake audio path and let the client handle the error.
114 if (!params->IsValid()) 119 if (!params->IsValid())
115 *params = media::AudioParameters::UnavailableDeviceParams(); 120 *params = media::AudioParameters::UnavailableDeviceParams();
116 } 121 }
117 122
118 } // namespace 123 } // namespace
119 124
120 class AudioRendererHost::AudioEntry
121 : public media::AudioOutputController::EventHandler {
122 public:
123 AudioEntry(AudioRendererHost* host,
124 int stream_id,
125 int render_frame_id,
126 const media::AudioParameters& params,
127 const std::string& output_device_id,
128 std::unique_ptr<base::SharedMemory> shared_memory,
129 std::unique_ptr<media::AudioOutputController::SyncReader> reader);
130 ~AudioEntry() override;
131
132 int stream_id() const {
133 return stream_id_;
134 }
135
136 int render_frame_id() const { return render_frame_id_; }
137
138 media::AudioOutputController* controller() const { return controller_.get(); }
139
140 base::SharedMemory* shared_memory() {
141 return shared_memory_.get();
142 }
143
144 media::AudioOutputController::SyncReader* reader() const {
145 return reader_.get();
146 }
147
148 bool playing() const { return playing_; }
149 void set_playing(bool playing) { playing_ = playing; }
150
151 private:
152 // media::AudioOutputController::EventHandler implementation.
153 void OnCreated() override;
154 void OnPlaying() override;
155 void OnPaused() override;
156 void OnError() override;
157
158 AudioRendererHost* const host_;
159 const int stream_id_;
160
161 // The routing ID of the source RenderFrame.
162 const int render_frame_id_;
163
164 // Shared memory for transmission of the audio data. Used by |reader_|.
165 const std::unique_ptr<base::SharedMemory> shared_memory_;
166
167 // The synchronous reader to be used by |controller_|.
168 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_;
169
170 // The AudioOutputController that manages the audio stream.
171 const scoped_refptr<media::AudioOutputController> controller_;
172
173 bool playing_;
174 };
175
176 AudioRendererHost::AudioEntry::AudioEntry( 125 AudioRendererHost::AudioEntry::AudioEntry(
177 AudioRendererHost* host, 126 AudioRendererHost* host,
178 int stream_id, 127 int stream_id,
179 int render_frame_id, 128 int render_frame_id,
180 const media::AudioParameters& params, 129 const media::AudioParameters& params,
181 const std::string& output_device_id, 130 const std::string& output_device_id,
182 std::unique_ptr<base::SharedMemory> shared_memory, 131 std::unique_ptr<base::SharedMemory> shared_memory,
183 std::unique_ptr<media::AudioOutputController::SyncReader> reader) 132 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
133 const mojom::AudioOutput::CreateStreamCallback& callback)
184 : host_(host), 134 : host_(host),
185 stream_id_(stream_id), 135 stream_id_(stream_id),
186 render_frame_id_(render_frame_id), 136 render_frame_id_(render_frame_id),
187 shared_memory_(std::move(shared_memory)), 137 shared_memory_(std::move(shared_memory)),
188 reader_(std::move(reader)), 138 reader_(std::move(reader)),
189 controller_(media::AudioOutputController::Create(host->audio_manager_, 139 controller_(media::AudioOutputController::Create(host->audio_manager_,
190 this, 140 this,
191 params, 141 params,
192 output_device_id, 142 output_device_id,
193 reader_.get())), 143 reader_.get(),
144 callback)),
194 playing_(false) { 145 playing_(false) {
195 DCHECK(controller_.get()); 146 DCHECK(controller_.get());
196 } 147 }
197 148
198 AudioRendererHost::AudioEntry::~AudioEntry() {} 149 AudioRendererHost::AudioEntry::~AudioEntry() {}
199 150
200 /////////////////////////////////////////////////////////////////////////////// 151 ///////////////////////////////////////////////////////////////////////////////
201 // AudioRendererHost implementations. 152 // AudioRendererHost implementations.
202 153
203 AudioRendererHost::AudioRendererHost( 154 AudioRendererHost::AudioRendererHost(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 } 206 }
256 207
257 // Remove any authorizations for streams that were not yet created 208 // Remove any authorizations for streams that were not yet created
258 authorizations_.clear(); 209 authorizations_.clear();
259 } 210 }
260 211
261 void AudioRendererHost::OnDestruct() const { 212 void AudioRendererHost::OnDestruct() const {
262 BrowserThread::DeleteOnIOThread::Destruct(this); 213 BrowserThread::DeleteOnIOThread::Destruct(this);
263 } 214 }
264 215
265 void AudioRendererHost::AudioEntry::OnCreated() { 216 void AudioRendererHost::AudioEntry::OnCreated(
266 BrowserThread::PostTask( 217 const mojom::AudioOutput::CreateStreamCallback& callback) {
Henrik Grunell 2016/04/19 15:36:09 Can the callback be stored in the AudioEntry inste
rchtara 2016/04/21 09:10:18 it's possible to do that, but we are going to have
Henrik Grunell 2016/04/22 08:23:03 Acknowledged.
267 BrowserThread::IO, 218 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
268 FROM_HERE, 219 base::Bind(&AudioRendererHost::DoCompleteCreation,
269 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 220 host_, stream_id_, callback));
270 } 221 }
271 222
272 void AudioRendererHost::AudioEntry::OnPlaying() { 223 void AudioRendererHost::AudioEntry::OnPlaying() {
273 BrowserThread::PostTask( 224 BrowserThread::PostTask(
274 BrowserThread::IO, 225 BrowserThread::IO,
275 FROM_HERE, 226 FROM_HERE,
276 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 227 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
277 host_, 228 host_,
278 stream_id_, 229 stream_id_,
279 true)); 230 true));
280 } 231 }
281 232
282 void AudioRendererHost::AudioEntry::OnPaused() { 233 void AudioRendererHost::AudioEntry::OnPaused() {
283 BrowserThread::PostTask( 234 BrowserThread::PostTask(
284 BrowserThread::IO, 235 BrowserThread::IO,
285 FROM_HERE, 236 FROM_HERE,
286 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 237 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
287 host_, 238 host_,
288 stream_id_, 239 stream_id_,
289 false)); 240 false));
290 } 241 }
291 242
292 void AudioRendererHost::AudioEntry::OnError() { 243 void AudioRendererHost::AudioEntry::OnError() {
293 BrowserThread::PostTask( 244 BrowserThread::PostTask(
294 BrowserThread::IO, 245 BrowserThread::IO,
295 FROM_HERE, 246 FROM_HERE,
296 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 247 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
297 } 248 }
298 249
299 void AudioRendererHost::DoCompleteCreation(int stream_id) { 250 void AudioRendererHost::DoCompleteCreation(
251 int stream_id,
252 const mojom::AudioOutput::CreateStreamCallback& callback) {
300 DCHECK_CURRENTLY_ON(BrowserThread::IO); 253 DCHECK_CURRENTLY_ON(BrowserThread::IO);
301 254
302 if (!PeerHandle()) { 255 if (!PeerHandle()) {
303 DLOG(WARNING) << "Renderer process handle is invalid."; 256 DLOG(WARNING) << "Renderer process handle is invalid.";
304 ReportErrorAndClose(stream_id); 257 ReportErrorAndCloseMojo(stream_id, callback);
305 return; 258 return;
306 } 259 }
307 260
308 AudioEntry* const entry = LookupById(stream_id); 261 AudioEntry* const entry = LookupById(stream_id);
309 if (!entry) { 262 if (!entry) {
310 ReportErrorAndClose(stream_id); 263 ReportErrorAndCloseMojo(stream_id, callback);
311 return; 264 return;
312 } 265 }
313 266
314 // Once the audio stream is created then complete the creation process by 267 scoped_ptr<mojom::AudioOutputStreamPtr> stream_ptr(
Henrik Grunell 2016/04/19 15:36:09 std::unique_ptr. Here and elsewhere.
rchtara 2016/04/21 09:10:17 Done.
315 // mapping shared memory and sharing with the renderer process. 268 audio_output_impl_->StreamFactory(stream_id, entry, this));
316 base::SharedMemoryHandle foreign_memory_handle; 269
317 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 270 base::SharedMemoryHandle shared_memory_handle =
318 &foreign_memory_handle)) { 271 base::SharedMemory::DuplicateHandle(entry->shared_memory()->handle());
319 // If we failed to map and share the shared memory then close the audio 272
320 // stream and send an error message. 273 MojoHandle mojo_foreign_memory_handle;
321 ReportErrorAndClose(entry->stream_id()); 274
275 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
276 shared_memory_handle, entry->shared_memory()->requested_size(), false,
277 &mojo_foreign_memory_handle);
278
279 if (shared_buffer_result != MOJO_RESULT_OK) {
280 DLOG(WARNING) << "Failed to wrap transit descriptor. Closing: "
281 << shared_buffer_result;
282 ReportErrorAndCloseMojo(entry->stream_id(), callback);
322 return; 283 return;
323 } 284 }
324 285
325 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 286 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
326 287
327 base::SyncSocket::TransitDescriptor socket_descriptor; 288 base::SyncSocket::TransitDescriptor socket_descriptor;
328 289
329 // If we failed to prepare the sync socket for the renderer then we fail 290 // If we failed to prepare the sync socket for the renderer then we fail
330 // the construction of audio stream. 291 // the construction of audio stream.
331 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 292 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
332 ReportErrorAndClose(entry->stream_id()); 293 ReportErrorAndCloseMojo(entry->stream_id(), callback);
294 return;
295 }
296 mojo::ScopedSharedBufferHandle shared_buffer_handle =
297 mojo::ScopedSharedBufferHandle(
298 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
299
300 MojoHandle socket_descriptor_handle;
301 MojoResult platform_handle_result;
302
303 // Mojo is going to close the socket handle when Mojo shutdowns.
Henrik Grunell 2016/04/19 15:36:08 I'm not sure what Mojo means here. And what "when
rchtara 2016/04/21 09:10:17 Done.
304 // This could create a conflict between Mojo and AudioOutputIPCDelegate where
305 // the socket is going to need to be closed too.
Henrik Grunell 2016/04/19 15:36:09 This line is hard to parse.
rchtara 2016/04/21 09:10:18 Done.
306 // This is why a duplicate of socket handler is going to be created, stored in
307 // |socket_descriptor_dup| and sent through Mojo to the renderer.
308
309 #if defined(OS_WIN)
Henrik Grunell 2016/04/19 15:36:09 This duplication looks like a good candidate for a
rchtara 2016/04/21 09:10:17 Done.
310 base::SyncSocket::TransitDescriptor socket_descriptor_dup = nullptr;
311 if (::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle
312 socket_descriptor,
313 GetCurrentProcess(), // hTargetProcessHandle
314 &socket_descriptor_dup,
315 0, // dwDesiredAccess ignored due to SAME_ACCESS
316 FALSE, // !bInheritHandle
317 DUPLICATE_SAME_ACCESS)) {
318 DLOG(WARNING) << "Failed to duplicate socket";
319 return;
320 }
321 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
322 mojo::edk::ScopedPlatformHandle(
323 mojo::edk::PlatformHandle(socket_descriptor_dup)),
324 &socket_descriptor_handle);
325
326 #else
327 int socket_descriptor_dup = dup(socket_descriptor.fd);
328 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
329 mojo::edk::ScopedPlatformHandle(
330 mojo::edk::PlatformHandle(socket_descriptor_dup)),
331 &socket_descriptor_handle);
332 #endif
333
334 if (platform_handle_result != MOJO_RESULT_OK) {
335 DLOG(WARNING) << "Failed to wrap platform handle. Closing: "
336 << platform_handle_result;
337 ReportErrorAndCloseMojo(stream_id, callback);
333 return; 338 return;
334 } 339 }
335 340
336 Send(new AudioMsg_NotifyStreamCreated( 341 mojo::ScopedHandle socket_handle =
337 entry->stream_id(), foreign_memory_handle, socket_descriptor, 342 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
338 entry->shared_memory()->requested_size())); 343 callback.Run(std::move(*stream_ptr), stream_id,
344 std::move(shared_buffer_handle), std::move(socket_handle));
345
339 } 346 }
340 347
341 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 348 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
342 bool is_playing) { 349 bool is_playing) {
343 DCHECK_CURRENTLY_ON(BrowserThread::IO); 350 DCHECK_CURRENTLY_ON(BrowserThread::IO);
344 351
345 AudioEntry* const entry = LookupById(stream_id); 352 AudioEntry* const entry = LookupById(stream_id);
346 if (!entry) 353 if (!entry)
347 return; 354 return;
348 355
(...skipping 30 matching lines...) Expand all
379 return controllers; 386 return controllers;
380 } 387 }
381 388
382 /////////////////////////////////////////////////////////////////////////////// 389 ///////////////////////////////////////////////////////////////////////////////
383 // IPC Messages handler 390 // IPC Messages handler
384 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) { 391 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) {
385 bool handled = true; 392 bool handled = true;
386 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message) 393 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message)
387 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization, 394 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization,
388 OnRequestDeviceAuthorization) 395 OnRequestDeviceAuthorization)
389 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
390 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) 396 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
391 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) 397 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
392 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) 398 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
393 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) 399 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
394 IPC_MESSAGE_UNHANDLED(handled = false) 400 IPC_MESSAGE_UNHANDLED(handled = false)
395 IPC_END_MESSAGE_MAP() 401 IPC_END_MESSAGE_MAP()
396 402
397 return handled; 403 return handled;
398 } 404 }
399 405
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 524
519 auth_data->second.first = true; 525 auth_data->second.first = true;
520 auth_data->second.second = device_info.unique_id; 526 auth_data->second.second = device_info.unique_id;
521 527
522 media::AudioParameters output_params = device_info.output_params; 528 media::AudioParameters output_params = device_info.output_params;
523 MaybeFixAudioParameters(&output_params); 529 MaybeFixAudioParameters(&output_params);
524 Send(new AudioMsg_NotifyDeviceAuthorized( 530 Send(new AudioMsg_NotifyDeviceAuthorized(
525 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); 531 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
526 } 532 }
527 533
528 void AudioRendererHost::OnCreateStream(int stream_id, 534 void AudioRendererHost::OnCreateStream(
529 int render_frame_id, 535 int stream_id,
530 const media::AudioParameters& params) { 536 int render_frame_id,
537 const media::AudioParameters& params,
538 const mojom::AudioOutput::CreateStreamCallback& callback) {
531 DCHECK_CURRENTLY_ON(BrowserThread::IO); 539 DCHECK_CURRENTLY_ON(BrowserThread::IO);
532 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 540 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream"
533 << "(stream_id=" << stream_id << ")"; 541 << "(stream_id=" << stream_id << ")";
534 542
535 const auto& auth_data = authorizations_.find(stream_id); 543 const auto& auth_data = authorizations_.find(stream_id);
536 544
537 // If no previous authorization requested, assume default device 545 // If no previous authorization requested, assume default device
538 if (auth_data == authorizations_.end()) { 546 if (auth_data == authorizations_.end()) {
539 DoCreateStream(stream_id, render_frame_id, params, std::string()); 547 DoCreateStream(stream_id, render_frame_id, params, std::string(), callback);
540 return; 548 return;
541 } 549 }
542 550
543 CHECK(auth_data->second.first); 551 CHECK(auth_data->second.first);
544 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 552 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second,
553 callback);
545 authorizations_.erase(auth_data); 554 authorizations_.erase(auth_data);
546 } 555 }
547 556
548 void AudioRendererHost::DoCreateStream(int stream_id, 557 void AudioRendererHost::DoCreateStream(
549 int render_frame_id, 558 int stream_id,
550 const media::AudioParameters& params, 559 int render_frame_id,
551 const std::string& device_unique_id) { 560 const media::AudioParameters& params,
561 const std::string& device_unique_id,
562 const mojom::AudioOutput::CreateStreamCallback& callback) {
552 DCHECK_CURRENTLY_ON(BrowserThread::IO); 563 DCHECK_CURRENTLY_ON(BrowserThread::IO);
553 564
554 // media::AudioParameters is validated in the deserializer. 565 // media::AudioParameters is validated in the deserializer.
555 if (LookupById(stream_id) != NULL) { 566 if (LookupById(stream_id) != NULL) {
556 SendErrorMessage(stream_id); 567 SendErrorMessage(stream_id);
557 return; 568 return;
558 } 569 }
559 570
560 // Create the shared memory and share with the renderer process. 571 // Create the shared memory and share with the renderer process.
561 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 572 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
562 AudioBus::CalculateMemorySize(params); 573 AudioBus::CalculateMemorySize(params);
563 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 574 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
Henrik Grunell 2016/04/19 15:36:09 scoped_ptr is deprecated. Keep std::unique_ptr. (N
rchtara 2016/04/21 09:10:18 Done.
564 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { 575 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
565 SendErrorMessage(stream_id); 576 SendErrorMessage(stream_id);
566 return; 577 return;
567 } 578 }
568 579
569 std::unique_ptr<AudioSyncReader> reader( 580 scoped_ptr<AudioSyncReader> reader(
570 new AudioSyncReader(shared_memory.get(), params)); 581 new AudioSyncReader(shared_memory.get(), params));
571 if (!reader->Init()) { 582 if (!reader->Init()) {
572 SendErrorMessage(stream_id); 583 SendErrorMessage(stream_id);
573 return; 584 return;
574 } 585 }
575 586
576 MediaObserver* const media_observer = 587 MediaObserver* const media_observer =
577 GetContentClient()->browser()->GetMediaObserver(); 588 GetContentClient()->browser()->GetMediaObserver();
578 if (media_observer) 589 if (media_observer)
579 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 590 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
580 591
581 std::unique_ptr<AudioEntry> entry( 592 scoped_ptr<AudioEntry> entry(
582 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, 593 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
583 std::move(shared_memory), std::move(reader))); 594 std::move(shared_memory), std::move(reader), callback));
584 if (mirroring_manager_) { 595 if (mirroring_manager_) {
585 mirroring_manager_->AddDiverter( 596 mirroring_manager_->AddDiverter(
586 render_process_id_, entry->render_frame_id(), entry->controller()); 597 render_process_id_, entry->render_frame_id(), entry->controller());
587 } 598 }
588 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 599 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
589 g_audio_streams_tracker.Get().IncreaseStreamCount(); 600 g_audio_streams_tracker.Get().IncreaseStreamCount();
590 601
591 audio_log_->OnCreated(stream_id, params, device_unique_id); 602 audio_log_->OnCreated(stream_id, params, device_unique_id);
592 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 603 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
593 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 604 stream_id, render_process_id_, render_frame_id, audio_log_.get());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 // is closed. 697 // is closed.
687 if (!LookupById(stream_id)) 698 if (!LookupById(stream_id))
688 return; 699 return;
689 700
690 SendErrorMessage(stream_id); 701 SendErrorMessage(stream_id);
691 702
692 audio_log_->OnError(stream_id); 703 audio_log_->OnError(stream_id);
693 OnCloseStream(stream_id); 704 OnCloseStream(stream_id);
694 } 705 }
695 706
707 void AudioRendererHost::ReportErrorAndCloseMojo(
Henrik Grunell 2016/04/19 15:36:09 "CloseMojo" sounds like the whole mojo infrastruct
rchtara 2016/04/21 09:10:17 :) yes exactly. Done.
708 int stream_id,
709 const mojom::AudioOutput::CreateStreamCallback& callback) {
710 DCHECK_CURRENTLY_ON(BrowserThread::IO);
711
712 // Make sure this isn't a stray callback executing after the stream has been
713 // closed, so error notifications aren't sent after clients believe the stream
714 // is closed.
715 if (!LookupById(stream_id))
716 return;
717 mojo::ScopedSharedBufferHandle shared_buffer_handle =
718 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
719
720 mojo::ScopedHandle socket_handle = mojo::ScopedHandle(mojo::Handle());
721
722 callback.Run(mojom::AudioOutputStreamPtr(), stream_id,
723 std::move(shared_buffer_handle), std::move(socket_handle));
724
725 audio_log_->OnError(stream_id);
726 OnCloseStream(stream_id);
727 }
728
696 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 729 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
697 DCHECK_CURRENTLY_ON(BrowserThread::IO); 730 DCHECK_CURRENTLY_ON(BrowserThread::IO);
698 731
699 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 732 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
700 return i != audio_entries_.end() ? i->second : NULL; 733 return i != audio_entries_.end() ? i->second : NULL;
701 } 734 }
702 735
703 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry, 736 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
704 bool is_playing) { 737 bool is_playing) {
705 DCHECK_CURRENTLY_ON(BrowserThread::IO); 738 DCHECK_CURRENTLY_ON(BrowserThread::IO);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 callback.Run(false, device_info); 848 callback.Run(false, device_info);
816 } 849 }
817 850
818 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 851 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
819 DCHECK_CURRENTLY_ON(BrowserThread::IO); 852 DCHECK_CURRENTLY_ON(BrowserThread::IO);
820 const auto& i = authorizations_.find(stream_id); 853 const auto& i = authorizations_.find(stream_id);
821 return i != authorizations_.end(); 854 return i != authorizations_.end();
822 } 855 }
823 856
824 } // namespace content 857 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698