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

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

Issue 1930393002: Switch stream creation and closing in Chrome audio rendering from IPC to Mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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" 17 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
16 #include "base/process/process.h" 19 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 20 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 21 #include "content/browser/browser_main_loop.h"
19 #include "content/browser/child_process_security_policy_impl.h" 22 #include "content/browser/child_process_security_policy_impl.h"
23 #include "content/browser/media/audio_output_impl.h"
20 #include "content/browser/media/audio_stream_monitor.h" 24 #include "content/browser/media/audio_stream_monitor.h"
21 #include "content/browser/media/capture/audio_mirroring_manager.h" 25 #include "content/browser/media/capture/audio_mirroring_manager.h"
22 #include "content/browser/media/media_internals.h" 26 #include "content/browser/media/media_internals.h"
23 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 27 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
24 #include "content/browser/renderer_host/media/audio_sync_reader.h" 28 #include "content/browser/renderer_host/media/audio_sync_reader.h"
25 #include "content/browser/renderer_host/media/media_stream_manager.h" 29 #include "content/browser/renderer_host/media/media_stream_manager.h"
26 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 30 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
27 #include "content/browser/renderer_host/render_widget_host_impl.h" 31 #include "content/browser/renderer_host/render_widget_host_impl.h"
28 #include "content/common/media/audio_messages.h" 32 #include "content/common/media/audio_messages.h"
29 #include "content/public/browser/content_browser_client.h" 33 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/media_device_id.h" 34 #include "content/public/browser/media_device_id.h"
31 #include "content/public/browser/media_observer.h" 35 #include "content/public/browser/media_observer.h"
32 #include "content/public/browser/render_frame_host.h" 36 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/common/content_switches.h" 37 #include "content/public/common/content_switches.h"
34 #include "media/audio/audio_device_name.h" 38 #include "media/audio/audio_device_name.h"
35 #include "media/audio/audio_manager_base.h" 39 #include "media/audio/audio_manager_base.h"
36 #include "media/audio/audio_streams_tracker.h" 40 #include "media/audio/audio_streams_tracker.h"
37 #include "media/base/audio_bus.h" 41 #include "media/base/audio_bus.h"
38 #include "media/base/limits.h" 42 #include "media/base/limits.h"
43 #include "mojo/edk/embedder/embedder.h"
44 #include "mojo/public/cpp/system/handle.h"
39 45
40 using media::AudioBus; 46 using media::AudioBus;
41 using media::AudioManager; 47 using media::AudioManager;
42 48
43 namespace content { 49 namespace content {
44 50
45 namespace { 51 namespace {
46 52
47 // Tracks the maximum number of simultaneous output streams browser-wide. 53 // Tracks the maximum number of simultaneous output streams browser-wide.
48 // Accessed on IO thread. 54 // Accessed on IO thread.
49 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker = 55 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker =
50 LAZY_INSTANCE_INITIALIZER; 56 LAZY_INSTANCE_INITIALIZER;
51 57
52 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData( 58 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData(
53 int stream_id, 59 int stream_id,
54 bool authorized, 60 bool authorized,
55 const std::string& device_unique_id) { 61 const std::string& device_unique_id) {
56 return std::make_pair(stream_id, 62 return std::make_pair(stream_id,
57 std::make_pair(authorized, device_unique_id)); 63 std::make_pair(authorized, device_unique_id));
58 } 64 }
59 65
60 GURL ConvertToGURL(const url::Origin& origin) { 66 GURL ConvertToGURL(const url::Origin& origin) {
61 return origin.unique() ? GURL() : GURL(origin.Serialize()); 67 return origin.unique() ? GURL() : GURL(origin.Serialize());
62 } 68 }
63 69
70 base::SyncSocket::TransitDescriptor DuplicateSocket(
71 base::SyncSocket::TransitDescriptor socket_descriptor) {
72 base::SyncSocket::TransitDescriptor socket_descriptor_dup;
73
74 #if defined(OS_WIN)
75 socket_descriptor_dup = 0;
76 if (!::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle
77 socket_descriptor,
78 GetCurrentProcess(), // hTargetProcessHandle
79 &socket_descriptor_dup,
80 0, // dwDesiredAccess ignored due to SAME_ACCESS
Henrik Grunell 2016/05/02 12:12:23 Two spaces after "0," instead of aligning with the
rchtara 2016/05/23 16:38:17 Done.
81 FALSE, // !bInheritHandle
82 DUPLICATE_SAME_ACCESS)) {
83 LOG(ERROR) << "Unable to duplicate socket handle.";
84 }
85
86 #else
87 socket_descriptor_dup.fd = dup(socket_descriptor.fd);
88 #endif
89 return socket_descriptor_dup;
90 }
91
64 bool IsValidDeviceId(const std::string& device_id) { 92 bool IsValidDeviceId(const std::string& device_id) {
65 static const std::string::size_type kValidLength = 64; 93 static const std::string::size_type kValidLength = 64;
66 94
67 if (device_id.empty() || 95 if (device_id.empty() ||
68 device_id == media::AudioManagerBase::kDefaultDeviceId || 96 device_id == media::AudioManagerBase::kDefaultDeviceId ||
69 device_id == media::AudioManagerBase::kCommunicationsDeviceId) { 97 device_id == media::AudioManagerBase::kCommunicationsDeviceId) {
70 return true; 98 return true;
71 } 99 }
72 100
73 if (device_id.length() != kValidLength) 101 if (device_id.length() != kValidLength)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 // fake audio path and let the client handle the error. 141 // fake audio path and let the client handle the error.
114 if (!params->IsValid()) 142 if (!params->IsValid())
115 *params = media::AudioParameters::UnavailableDeviceParams(); 143 *params = media::AudioParameters::UnavailableDeviceParams();
116 } 144 }
117 145
118 } // namespace 146 } // namespace
119 147
120 class AudioRendererHost::AudioEntry 148 class AudioRendererHost::AudioEntry
121 : public media::AudioOutputController::EventHandler { 149 : public media::AudioOutputController::EventHandler {
122 public: 150 public:
123 AudioEntry(AudioRendererHost* host, 151 AudioEntry(
124 int stream_id, 152 AudioRendererHost* host,
125 int render_frame_id, 153 int stream_id,
126 const media::AudioParameters& params, 154 int render_frame_id,
127 const std::string& output_device_id, 155 const media::AudioParameters& params,
128 std::unique_ptr<base::SharedMemory> shared_memory, 156 const std::string& output_device_id,
129 std::unique_ptr<media::AudioOutputController::SyncReader> reader); 157 std::unique_ptr<base::SharedMemory> shared_memory,
158 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
159 const media::interfaces::AudioOutput::CreateStreamCallback& callback);
130 ~AudioEntry() override; 160 ~AudioEntry() override;
131 161
132 int stream_id() const { 162 int stream_id() const {
133 return stream_id_; 163 return stream_id_;
134 } 164 }
135 165
136 int render_frame_id() const { return render_frame_id_; } 166 int render_frame_id() const { return render_frame_id_; }
137 167
138 media::AudioOutputController* controller() const { return controller_.get(); } 168 media::AudioOutputController* controller() const { return controller_.get(); }
139 169
(...skipping 24 matching lines...) Expand all
164 // Shared memory for transmission of the audio data. Used by |reader_|. 194 // Shared memory for transmission of the audio data. Used by |reader_|.
165 const std::unique_ptr<base::SharedMemory> shared_memory_; 195 const std::unique_ptr<base::SharedMemory> shared_memory_;
166 196
167 // The synchronous reader to be used by |controller_|. 197 // The synchronous reader to be used by |controller_|.
168 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; 198 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_;
169 199
170 // The AudioOutputController that manages the audio stream. 200 // The AudioOutputController that manages the audio stream.
171 const scoped_refptr<media::AudioOutputController> controller_; 201 const scoped_refptr<media::AudioOutputController> controller_;
172 202
173 bool playing_; 203 bool playing_;
204
205 // Callback for media::interfaces::AudioOutput::CreateStream.
206 media::interfaces::AudioOutput::CreateStreamCallback create_stream_callback_;
174 }; 207 };
175 208
176 AudioRendererHost::AudioEntry::AudioEntry( 209 AudioRendererHost::AudioEntry::AudioEntry(
177 AudioRendererHost* host, 210 AudioRendererHost* host,
178 int stream_id, 211 int stream_id,
179 int render_frame_id, 212 int render_frame_id,
180 const media::AudioParameters& params, 213 const media::AudioParameters& params,
181 const std::string& output_device_id, 214 const std::string& output_device_id,
182 std::unique_ptr<base::SharedMemory> shared_memory, 215 std::unique_ptr<base::SharedMemory> shared_memory,
183 std::unique_ptr<media::AudioOutputController::SyncReader> reader) 216 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
217 const media::interfaces::AudioOutput::CreateStreamCallback& callback)
184 : host_(host), 218 : host_(host),
185 stream_id_(stream_id), 219 stream_id_(stream_id),
186 render_frame_id_(render_frame_id), 220 render_frame_id_(render_frame_id),
187 shared_memory_(std::move(shared_memory)), 221 shared_memory_(std::move(shared_memory)),
188 reader_(std::move(reader)), 222 reader_(std::move(reader)),
189 controller_(media::AudioOutputController::Create(host->audio_manager_, 223 controller_(media::AudioOutputController::Create(host->audio_manager_,
190 this, 224 this,
191 params, 225 params,
192 output_device_id, 226 output_device_id,
193 reader_.get())), 227 reader_.get())),
194 playing_(false) { 228 playing_(false) {
229 create_stream_callback_ = callback;
Henrik Grunell 2016/05/02 12:12:23 Put it in the initialization list?
rchtara 2016/05/23 16:38:17 Done.
195 DCHECK(controller_.get()); 230 DCHECK(controller_.get());
196 } 231 }
197 232
198 AudioRendererHost::AudioEntry::~AudioEntry() {} 233 AudioRendererHost::AudioEntry::~AudioEntry() {}
199 234
200 /////////////////////////////////////////////////////////////////////////////// 235 ///////////////////////////////////////////////////////////////////////////////
201 // AudioRendererHost implementations. 236 // AudioRendererHost implementations.
202 237
203 AudioRendererHost::AudioRendererHost( 238 AudioRendererHost::AudioRendererHost(
204 int render_process_id, 239 int render_process_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 // Remove any authorizations for streams that were not yet created 292 // Remove any authorizations for streams that were not yet created
258 authorizations_.clear(); 293 authorizations_.clear();
259 } 294 }
260 295
261 void AudioRendererHost::OnDestruct() const { 296 void AudioRendererHost::OnDestruct() const {
262 BrowserThread::DeleteOnIOThread::Destruct(this); 297 BrowserThread::DeleteOnIOThread::Destruct(this);
263 } 298 }
264 299
265 void AudioRendererHost::AudioEntry::OnCreated() { 300 void AudioRendererHost::AudioEntry::OnCreated() {
266 BrowserThread::PostTask( 301 BrowserThread::PostTask(
267 BrowserThread::IO, 302 BrowserThread::IO, FROM_HERE,
268 FROM_HERE, 303 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_,
Henrik Grunell 2016/05/02 12:12:23 Could |callback_| be used again? If not, what abou
rchtara 2016/05/23 16:38:17 Done.
269 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 304 create_stream_callback_));
270 } 305 }
271 306
272 void AudioRendererHost::AudioEntry::OnPlaying() { 307 void AudioRendererHost::AudioEntry::OnPlaying() {
273 BrowserThread::PostTask( 308 BrowserThread::PostTask(
274 BrowserThread::IO, 309 BrowserThread::IO,
275 FROM_HERE, 310 FROM_HERE,
276 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 311 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
277 host_, 312 host_,
278 stream_id_, 313 stream_id_,
279 true)); 314 true));
280 } 315 }
281 316
282 void AudioRendererHost::AudioEntry::OnPaused() { 317 void AudioRendererHost::AudioEntry::OnPaused() {
283 BrowserThread::PostTask( 318 BrowserThread::PostTask(
284 BrowserThread::IO, 319 BrowserThread::IO,
285 FROM_HERE, 320 FROM_HERE,
286 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 321 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
287 host_, 322 host_,
288 stream_id_, 323 stream_id_,
289 false)); 324 false));
290 } 325 }
291 326
292 void AudioRendererHost::AudioEntry::OnError() { 327 void AudioRendererHost::AudioEntry::OnError() {
293 BrowserThread::PostTask( 328 BrowserThread::PostTask(
294 BrowserThread::IO, 329 BrowserThread::IO,
295 FROM_HERE, 330 FROM_HERE,
296 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 331 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
297 } 332 }
298 333
299 void AudioRendererHost::DoCompleteCreation(int stream_id) { 334 void AudioRendererHost::DoCompleteCreation(
335 int stream_id,
336 const media::interfaces::AudioOutput::CreateStreamCallback& callback) {
300 DCHECK_CURRENTLY_ON(BrowserThread::IO); 337 DCHECK_CURRENTLY_ON(BrowserThread::IO);
301 338
302 if (!PeerHandle()) { 339 if (!PeerHandle()) {
303 DLOG(WARNING) << "Renderer process handle is invalid."; 340 DLOG(WARNING) << "Renderer process handle is invalid.";
304 ReportErrorAndClose(stream_id); 341 ReportErrorAndCloseStream(stream_id, callback);
305 return; 342 return;
306 } 343 }
307 344
308 AudioEntry* const entry = LookupById(stream_id); 345 AudioEntry* const entry = LookupById(stream_id);
309 if (!entry) { 346 if (!entry) {
310 ReportErrorAndClose(stream_id); 347 ReportErrorAndCloseStream(stream_id, callback);
311 return; 348 return;
312 } 349 }
313 350
314 // Once the audio stream is created then complete the creation process by 351 media::interfaces::AudioOutputStreamPtr stream_ptr =
315 // mapping shared memory and sharing with the renderer process. 352 (audio_output_impl_->StreamFactory(stream_id, this));
316 base::SharedMemoryHandle foreign_memory_handle; 353
317 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 354 base::SharedMemoryHandle shared_memory_handle =
318 &foreign_memory_handle)) { 355 base::SharedMemory::DuplicateHandle(entry->shared_memory()->handle());
319 // If we failed to map and share the shared memory then close the audio 356
320 // stream and send an error message. 357 MojoHandle mojo_foreign_memory_handle;
321 ReportErrorAndClose(entry->stream_id()); 358
359 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
360 shared_memory_handle, entry->shared_memory()->requested_size(), false,
361 &mojo_foreign_memory_handle);
362
363 if (shared_buffer_result != MOJO_RESULT_OK) {
364 DLOG(WARNING) << "Failed to wrap transit descriptor. Closing: "
365 << shared_buffer_result;
366 ReportErrorAndCloseStream(entry->stream_id(), callback);
322 return; 367 return;
323 } 368 }
324 369
325 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 370 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
326 371
327 base::SyncSocket::TransitDescriptor socket_descriptor; 372 base::SyncSocket::TransitDescriptor socket_descriptor;
328 373
329 // If we failed to prepare the sync socket for the renderer then we fail 374 // If we failed to prepare the sync socket for the renderer then we fail
330 // the construction of audio stream. 375 // the construction of audio stream.
331 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 376 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
332 ReportErrorAndClose(entry->stream_id()); 377 ReportErrorAndCloseStream(entry->stream_id(), callback);
378 return;
379 }
380 mojo::ScopedSharedBufferHandle shared_buffer_handle =
381 mojo::ScopedSharedBufferHandle(
382 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
383
384 MojoHandle socket_descriptor_handle;
385 MojoResult platform_handle_result;
386
387 // The socket handle is going to be closed when |mojo_application_host_| is
388 // reset. AudioOutputIPCDelegate is going to need to close the socket handle
Henrik Grunell 2016/05/02 12:12:23 AudioOutputIPCDelegate is an implementation detail
rchtara 2016/05/23 16:38:17 Mojo close it automatically, but not sure if it's
389 // too when the steam it controls is closed. This is going to cause an issue
390 // because both of them are going to close the same socket handle.
391 // This is why a duplicate of the socket handler is going to be created,
392 // stored in |socket_descriptor_dup| and sent through Mojo to the renderer so
393 // it can be used by AudioOutputIPCDelegate.
394
395 base::SyncSocket::TransitDescriptor socket_descriptor_dup =
396 DuplicateSocket(socket_descriptor);
397 #if defined(OS_WIN)
398 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
399 mojo::edk::ScopedPlatformHandle(
400 mojo::edk::PlatformHandle(socket_descriptor_dup),
401 &socket_descriptor_handle);
402 #else
403 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
404 mojo::edk::ScopedPlatformHandle(
405 mojo::edk::PlatformHandle(socket_descriptor_dup.fd)),
406 &socket_descriptor_handle);
407 #endif
408
409 if (platform_handle_result != MOJO_RESULT_OK) {
410 DLOG(WARNING) << "Failed to wrap platform handle. Closing: "
411 << platform_handle_result;
412 ReportErrorAndCloseStream(stream_id, callback);
333 return; 413 return;
334 } 414 }
335 415
336 Send(new AudioMsg_NotifyStreamCreated( 416 mojo::ScopedHandle socket_handle =
337 entry->stream_id(), foreign_memory_handle, socket_descriptor, 417 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
338 entry->shared_memory()->requested_size())); 418 callback.Run(stream_id, std::move(stream_ptr),
419 std::move(shared_buffer_handle), std::move(socket_handle));
339 } 420 }
340 421
341 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 422 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
342 bool is_playing) { 423 bool is_playing) {
343 DCHECK_CURRENTLY_ON(BrowserThread::IO); 424 DCHECK_CURRENTLY_ON(BrowserThread::IO);
344 425
345 AudioEntry* const entry = LookupById(stream_id); 426 AudioEntry* const entry = LookupById(stream_id);
346 if (!entry) 427 if (!entry)
347 return; 428 return;
348 429
(...skipping 30 matching lines...) Expand all
379 return controllers; 460 return controllers;
380 } 461 }
381 462
382 /////////////////////////////////////////////////////////////////////////////// 463 ///////////////////////////////////////////////////////////////////////////////
383 // IPC Messages handler 464 // IPC Messages handler
384 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) { 465 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) {
385 bool handled = true; 466 bool handled = true;
386 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message) 467 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message)
387 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization, 468 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization,
388 OnRequestDeviceAuthorization) 469 OnRequestDeviceAuthorization)
389 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
390 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) 470 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
391 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) 471 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
392 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) 472 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
393 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) 473 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
394 IPC_MESSAGE_UNHANDLED(handled = false) 474 IPC_MESSAGE_UNHANDLED(handled = false)
395 IPC_END_MESSAGE_MAP() 475 IPC_END_MESSAGE_MAP()
396 476
397 return handled; 477 return handled;
398 } 478 }
399 479
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 598
519 auth_data->second.first = true; 599 auth_data->second.first = true;
520 auth_data->second.second = device_info.unique_id; 600 auth_data->second.second = device_info.unique_id;
521 601
522 media::AudioParameters output_params = device_info.output_params; 602 media::AudioParameters output_params = device_info.output_params;
523 MaybeFixAudioParameters(&output_params); 603 MaybeFixAudioParameters(&output_params);
524 Send(new AudioMsg_NotifyDeviceAuthorized( 604 Send(new AudioMsg_NotifyDeviceAuthorized(
525 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); 605 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
526 } 606 }
527 607
528 void AudioRendererHost::OnCreateStream(int stream_id, 608 void AudioRendererHost::CreateStream(
529 int render_frame_id, 609 int stream_id,
530 const media::AudioParameters& params) { 610 int render_frame_id,
611 const media::AudioParameters& params,
612 const media::interfaces::AudioOutput::CreateStreamCallback& callback) {
531 DCHECK_CURRENTLY_ON(BrowserThread::IO); 613 DCHECK_CURRENTLY_ON(BrowserThread::IO);
532 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 614 DVLOG(1) << "AudioRendererHost@" << this << "::CreateStream"
533 << "(stream_id=" << stream_id << ")"; 615 << "(stream_id=" << stream_id << ")";
534 616
535 const auto& auth_data = authorizations_.find(stream_id); 617 const auto& auth_data = authorizations_.find(stream_id);
536 618
537 // If no previous authorization requested, assume default device 619 // If no previous authorization requested, assume default device
538 if (auth_data == authorizations_.end()) { 620 if (auth_data == authorizations_.end()) {
539 DoCreateStream(stream_id, render_frame_id, params, std::string()); 621 DoCreateStream(stream_id, render_frame_id, params, std::string(), callback);
540 return; 622 return;
541 } 623 }
542 624
543 CHECK(auth_data->second.first); 625 CHECK(auth_data->second.first);
544 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 626 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second,
627 callback);
545 authorizations_.erase(auth_data); 628 authorizations_.erase(auth_data);
546 } 629 }
547 630
548 void AudioRendererHost::DoCreateStream(int stream_id, 631 void AudioRendererHost::DoCreateStream(
549 int render_frame_id, 632 int stream_id,
550 const media::AudioParameters& params, 633 int render_frame_id,
551 const std::string& device_unique_id) { 634 const media::AudioParameters& params,
635 const std::string& device_unique_id,
636 const media::interfaces::AudioOutput::CreateStreamCallback& callback) {
552 DCHECK_CURRENTLY_ON(BrowserThread::IO); 637 DCHECK_CURRENTLY_ON(BrowserThread::IO);
553 638
554 // media::AudioParameters is validated in the deserializer. 639 // media::AudioParameters is validated in the deserializer.
555 if (LookupById(stream_id) != NULL) { 640 if (LookupById(stream_id) != NULL) {
556 SendErrorMessage(stream_id); 641 SendErrorMessage(stream_id);
557 return; 642 return;
558 } 643 }
559 644
560 // Create the shared memory and share with the renderer process. 645 // Create the shared memory and share with the renderer process.
561 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 646 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
(...skipping 11 matching lines...) Expand all
573 return; 658 return;
574 } 659 }
575 660
576 MediaObserver* const media_observer = 661 MediaObserver* const media_observer =
577 GetContentClient()->browser()->GetMediaObserver(); 662 GetContentClient()->browser()->GetMediaObserver();
578 if (media_observer) 663 if (media_observer)
579 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 664 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
580 665
581 std::unique_ptr<AudioEntry> entry( 666 std::unique_ptr<AudioEntry> entry(
582 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, 667 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
583 std::move(shared_memory), std::move(reader))); 668 std::move(shared_memory), std::move(reader), callback));
584 if (mirroring_manager_) { 669 if (mirroring_manager_) {
585 mirroring_manager_->AddDiverter( 670 mirroring_manager_->AddDiverter(
586 render_process_id_, entry->render_frame_id(), entry->controller()); 671 render_process_id_, entry->render_frame_id(), entry->controller());
587 } 672 }
588 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 673 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
589 g_audio_streams_tracker.Get().IncreaseStreamCount(); 674 g_audio_streams_tracker.Get().IncreaseStreamCount();
590 675
591 audio_log_->OnCreated(stream_id, params, device_unique_id); 676 audio_log_->OnCreated(stream_id, params, device_unique_id);
592 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 677 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
593 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 678 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. 771 // is closed.
687 if (!LookupById(stream_id)) 772 if (!LookupById(stream_id))
688 return; 773 return;
689 774
690 SendErrorMessage(stream_id); 775 SendErrorMessage(stream_id);
691 776
692 audio_log_->OnError(stream_id); 777 audio_log_->OnError(stream_id);
693 OnCloseStream(stream_id); 778 OnCloseStream(stream_id);
694 } 779 }
695 780
781 void AudioRendererHost::ReportErrorAndCloseStream(
782 int stream_id,
783 const media::interfaces::AudioOutput::CreateStreamCallback& callback) {
784 DCHECK_CURRENTLY_ON(BrowserThread::IO);
785
786 // Make sure this isn't a stray callback executing after the stream has been
787 // closed, so error notifications aren't sent after clients believe the stream
788 // is closed.
789 if (!LookupById(stream_id))
790 return;
791 mojo::ScopedSharedBufferHandle shared_buffer_handle =
Henrik Grunell 2016/05/02 12:12:22 Nit: add empty line before this.
rchtara 2016/05/23 16:38:17 Done.
792 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
793
794 mojo::ScopedHandle socket_handle = mojo::ScopedHandle(mojo::Handle());
795
796 callback.Run(stream_id, media::interfaces::AudioOutputStreamPtr(),
797 std::move(shared_buffer_handle), std::move(socket_handle));
798
799 audio_log_->OnError(stream_id);
800 OnCloseStream(stream_id);
801 }
802
696 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 803 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
697 DCHECK_CURRENTLY_ON(BrowserThread::IO); 804 DCHECK_CURRENTLY_ON(BrowserThread::IO);
698 805
699 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 806 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
700 return i != audio_entries_.end() ? i->second : NULL; 807 return i != audio_entries_.end() ? i->second : NULL;
701 } 808 }
702 809
703 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry, 810 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
704 bool is_playing) { 811 bool is_playing) {
705 DCHECK_CURRENTLY_ON(BrowserThread::IO); 812 DCHECK_CURRENTLY_ON(BrowserThread::IO);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 callback.Run(false, device_info); 922 callback.Run(false, device_info);
816 } 923 }
817 924
818 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 925 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
819 DCHECK_CURRENTLY_ON(BrowserThread::IO); 926 DCHECK_CURRENTLY_ON(BrowserThread::IO);
820 const auto& i = authorizations_.find(stream_id); 927 const auto& i = authorizations_.find(stream_id);
821 return i != authorizations_.end(); 928 return i != authorizations_.end();
822 } 929 }
823 930
824 } // namespace content 931 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698