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

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: rebase + tests in progress 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"
22 #include "content/browser/media/audio_output_impl.h"
19 #include "content/browser/media/audio_stream_monitor.h" 23 #include "content/browser/media/audio_stream_monitor.h"
20 #include "content/browser/media/capture/audio_mirroring_manager.h" 24 #include "content/browser/media/capture/audio_mirroring_manager.h"
21 #include "content/browser/media/media_internals.h" 25 #include "content/browser/media/media_internals.h"
22 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 26 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
23 #include "content/browser/renderer_host/media/audio_sync_reader.h" 27 #include "content/browser/renderer_host/media/audio_sync_reader.h"
24 #include "content/browser/renderer_host/media/media_stream_manager.h" 28 #include "content/browser/renderer_host/media/media_stream_manager.h"
25 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 29 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
26 #include "content/browser/renderer_host/render_widget_host_impl.h" 30 #include "content/browser/renderer_host/render_widget_host_impl.h"
27 #include "content/common/media/audio_messages.h" 31 #include "content/common/media/audio_messages.h"
28 #include "content/public/browser/content_browser_client.h" 32 #include "content/public/browser/content_browser_client.h"
29 #include "content/public/browser/media_device_id.h" 33 #include "content/public/browser/media_device_id.h"
30 #include "content/public/browser/media_observer.h" 34 #include "content/public/browser/media_observer.h"
31 #include "content/public/browser/render_frame_host.h" 35 #include "content/public/browser/render_frame_host.h"
32 #include "content/public/common/content_switches.h" 36 #include "content/public/common/content_switches.h"
33 #include "media/audio/audio_device_description.h" 37 #include "media/audio/audio_device_description.h"
34 #include "media/audio/audio_streams_tracker.h" 38 #include "media/audio/audio_streams_tracker.h"
35 #include "media/base/audio_bus.h" 39 #include "media/base/audio_bus.h"
36 #include "media/base/limits.h" 40 #include "media/base/limits.h"
41 #include "mojo/edk/embedder/embedder.h"
42 #include "mojo/public/cpp/system/handle.h"
37 43
38 using media::AudioBus; 44 using media::AudioBus;
39 using media::AudioManager; 45 using media::AudioManager;
40 46
41 namespace content { 47 namespace content {
42 48
43 namespace { 49 namespace {
44 50
45 // Tracks the maximum number of simultaneous output streams browser-wide. 51 // Tracks the maximum number of simultaneous output streams browser-wide.
46 // Accessed on IO thread. 52 // Accessed on IO thread.
47 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker = 53 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker =
48 LAZY_INSTANCE_INITIALIZER; 54 LAZY_INSTANCE_INITIALIZER;
49 55
50 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData( 56 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData(
51 int stream_id, 57 int stream_id,
52 bool authorized, 58 bool authorized,
53 const std::string& device_unique_id) { 59 const std::string& device_unique_id) {
54 return std::make_pair(stream_id, 60 return std::make_pair(stream_id,
55 std::make_pair(authorized, device_unique_id)); 61 std::make_pair(authorized, device_unique_id));
56 } 62 }
57 63
64 base::SyncSocket::TransitDescriptor DuplicateSocket(
65 base::SyncSocket::TransitDescriptor socket_descriptor) {
66 base::SyncSocket::TransitDescriptor socket_descriptor_dup;
67
68 #if defined(OS_WIN)
69 socket_descriptor_dup = 0;
70 if (!::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle
71 socket_descriptor,
72 GetCurrentProcess(), // hTargetProcessHandle
73 &socket_descriptor_dup,
74 0, // dwDesiredAccess ignored due to SAME_ACCESS
75 FALSE, // !bInheritHandle
76 DUPLICATE_SAME_ACCESS)) {
77 LOG(ERROR) << "Unable to duplicate socket handle.";
78 }
79
80 #else
81 socket_descriptor_dup.fd = dup(socket_descriptor.fd);
82 #endif
83 return socket_descriptor_dup;
84 }
85
58 bool IsValidDeviceId(const std::string& device_id) { 86 bool IsValidDeviceId(const std::string& device_id) {
59 static const std::string::size_type kValidLength = 64; 87 static const std::string::size_type kValidLength = 64;
60 88
61 if (device_id.empty() || 89 if (device_id.empty() ||
62 device_id == media::AudioDeviceDescription::kDefaultDeviceId || 90 device_id == media::AudioDeviceDescription::kDefaultDeviceId ||
63 device_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { 91 device_id == media::AudioDeviceDescription::kCommunicationsDeviceId) {
64 return true; 92 return true;
65 } 93 }
66 94
67 if (device_id.length() != kValidLength) 95 if (device_id.length() != kValidLength)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 141
114 class AudioRendererHost::AudioEntry 142 class AudioRendererHost::AudioEntry
115 : public media::AudioOutputController::EventHandler { 143 : public media::AudioOutputController::EventHandler {
116 public: 144 public:
117 AudioEntry(AudioRendererHost* host, 145 AudioEntry(AudioRendererHost* host,
118 int stream_id, 146 int stream_id,
119 int render_frame_id, 147 int render_frame_id,
120 const media::AudioParameters& params, 148 const media::AudioParameters& params,
121 const std::string& output_device_id, 149 const std::string& output_device_id,
122 std::unique_ptr<base::SharedMemory> shared_memory, 150 std::unique_ptr<base::SharedMemory> shared_memory,
123 std::unique_ptr<media::AudioOutputController::SyncReader> reader); 151 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
152 const media::mojom::AudioOutput::CreateStreamCallback&
153 create_stream_callback);
124 ~AudioEntry() override; 154 ~AudioEntry() override;
125 155
126 int stream_id() const { 156 int stream_id() const {
127 return stream_id_; 157 return stream_id_;
128 } 158 }
129 159
130 int render_frame_id() const { return render_frame_id_; } 160 int render_frame_id() const { return render_frame_id_; }
131 161
132 media::AudioOutputController* controller() const { return controller_.get(); } 162 media::AudioOutputController* controller() const { return controller_.get(); }
133 163
134 base::SharedMemory* shared_memory() { 164 base::SharedMemory* shared_memory() {
135 return shared_memory_.get(); 165 return shared_memory_.get();
136 } 166 }
137 167
138 media::AudioOutputController::SyncReader* reader() const { 168 media::AudioOutputController::SyncReader* reader() const {
139 return reader_.get(); 169 return reader_.get();
140 } 170 }
141 171
142 bool playing() const { return playing_; } 172 bool playing() const { return playing_; }
143 void set_playing(bool playing) { playing_ = playing; } 173 void set_playing(bool playing) { playing_ = playing; }
144 174
175 media::mojom::AudioOutput::CreateStreamCallback*
176 get_create_stream_callback() {
177 return &create_stream_callback_;
178 }
179
145 private: 180 private:
146 // media::AudioOutputController::EventHandler implementation. 181 // media::AudioOutputController::EventHandler implementation.
147 void OnCreated() override; 182 void OnCreated() override;
148 void OnPlaying() override; 183 void OnPlaying() override;
149 void OnPaused() override; 184 void OnPaused() override;
150 void OnError() override; 185 void OnError() override;
151 186
152 AudioRendererHost* const host_; 187 AudioRendererHost* const host_;
153 const int stream_id_; 188 const int stream_id_;
154 189
155 // The routing ID of the source RenderFrame. 190 // The routing ID of the source RenderFrame.
156 const int render_frame_id_; 191 const int render_frame_id_;
157 192
158 // Shared memory for transmission of the audio data. Used by |reader_|. 193 // Shared memory for transmission of the audio data. Used by |reader_|.
159 const std::unique_ptr<base::SharedMemory> shared_memory_; 194 const std::unique_ptr<base::SharedMemory> shared_memory_;
160 195
161 // The synchronous reader to be used by |controller_|. 196 // The synchronous reader to be used by |controller_|.
162 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; 197 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_;
163 198
164 // The AudioOutputController that manages the audio stream. 199 // The AudioOutputController that manages the audio stream.
165 const scoped_refptr<media::AudioOutputController> controller_; 200 const scoped_refptr<media::AudioOutputController> controller_;
166 201
167 bool playing_; 202 bool playing_;
203
204 // Callback for media::mojom::AudioOutput::CreateStream.
205 media::mojom::AudioOutput::CreateStreamCallback create_stream_callback_;
168 }; 206 };
169 207
170 AudioRendererHost::AudioEntry::AudioEntry( 208 AudioRendererHost::AudioEntry::AudioEntry(
171 AudioRendererHost* host, 209 AudioRendererHost* host,
172 int stream_id, 210 int stream_id,
173 int render_frame_id, 211 int render_frame_id,
174 const media::AudioParameters& params, 212 const media::AudioParameters& params,
175 const std::string& output_device_id, 213 const std::string& output_device_id,
176 std::unique_ptr<base::SharedMemory> shared_memory, 214 std::unique_ptr<base::SharedMemory> shared_memory,
177 std::unique_ptr<media::AudioOutputController::SyncReader> reader) 215 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
216 const media::mojom::AudioOutput::CreateStreamCallback&
217 create_stream_callback)
178 : host_(host), 218 : host_(host),
179 stream_id_(stream_id), 219 stream_id_(stream_id),
180 render_frame_id_(render_frame_id), 220 render_frame_id_(render_frame_id),
181 shared_memory_(std::move(shared_memory)), 221 shared_memory_(std::move(shared_memory)),
182 reader_(std::move(reader)), 222 reader_(std::move(reader)),
183 controller_(media::AudioOutputController::Create(host->audio_manager_, 223 controller_(media::AudioOutputController::Create(host->audio_manager_,
184 this, 224 this,
185 params, 225 params,
186 output_device_id, 226 output_device_id,
187 reader_.get())), 227 reader_.get())),
188 playing_(false) { 228 playing_(false),
229 create_stream_callback_(create_stream_callback) {
189 DCHECK(controller_.get()); 230 DCHECK(controller_.get());
190 } 231 }
191 232
192 AudioRendererHost::AudioEntry::~AudioEntry() {} 233 AudioRendererHost::AudioEntry::~AudioEntry() {}
193 234
194 /////////////////////////////////////////////////////////////////////////////// 235 ///////////////////////////////////////////////////////////////////////////////
195 // AudioRendererHost implementations. 236 // AudioRendererHost implementations.
196 237
197 AudioRendererHost::AudioRendererHost( 238 AudioRendererHost::AudioRendererHost(
198 int render_process_id, 239 int render_process_id,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 const RenderProcessHost::GetAudioOutputControllersCallback& 278 const RenderProcessHost::GetAudioOutputControllersCallback&
238 callback) const { 279 callback) const {
239 BrowserThread::PostTaskAndReplyWithResult( 280 BrowserThread::PostTaskAndReplyWithResult(
240 BrowserThread::IO, FROM_HERE, 281 BrowserThread::IO, FROM_HERE,
241 base::Bind(&AudioRendererHost::DoGetOutputControllers, this), callback); 282 base::Bind(&AudioRendererHost::DoGetOutputControllers, this), callback);
242 } 283 }
243 284
244 void AudioRendererHost::OnChannelClosing() { 285 void AudioRendererHost::OnChannelClosing() {
245 // Since the IPC sender is gone, close all requested audio streams. 286 // Since the IPC sender is gone, close all requested audio streams.
246 while (!audio_entries_.empty()) { 287 while (!audio_entries_.empty()) {
247 // Note: OnCloseStream() removes the entries from audio_entries_. 288 // Note: CloseStream() removes the entries from audio_entries_.
248 OnCloseStream(audio_entries_.begin()->first); 289 CloseStream(audio_entries_.begin()->first);
249 } 290 }
250 291
251 // Remove any authorizations for streams that were not yet created 292 // Remove any authorizations for streams that were not yet created
252 authorizations_.clear(); 293 authorizations_.clear();
253 } 294 }
254 295
255 void AudioRendererHost::OnDestruct() const { 296 void AudioRendererHost::OnDestruct() const {
256 BrowserThread::DeleteOnIOThread::Destruct(this); 297 BrowserThread::DeleteOnIOThread::Destruct(this);
257 } 298 }
258 299
259 void AudioRendererHost::AudioEntry::OnCreated() { 300 void AudioRendererHost::AudioEntry::OnCreated() {
260 BrowserThread::PostTask( 301 BrowserThread::PostTask(
261 BrowserThread::IO, 302 BrowserThread::IO, FROM_HERE,
262 FROM_HERE, 303 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_,
263 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 304 create_stream_callback_));
264 } 305 }
265 306
266 void AudioRendererHost::AudioEntry::OnPlaying() { 307 void AudioRendererHost::AudioEntry::OnPlaying() {
267 BrowserThread::PostTask( 308 BrowserThread::PostTask(
268 BrowserThread::IO, 309 BrowserThread::IO,
269 FROM_HERE, 310 FROM_HERE,
270 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 311 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
271 host_, 312 host_,
272 stream_id_, 313 stream_id_,
273 true)); 314 true));
274 } 315 }
275 316
276 void AudioRendererHost::AudioEntry::OnPaused() { 317 void AudioRendererHost::AudioEntry::OnPaused() {
277 BrowserThread::PostTask( 318 BrowserThread::PostTask(
278 BrowserThread::IO, 319 BrowserThread::IO,
279 FROM_HERE, 320 FROM_HERE,
280 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 321 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
281 host_, 322 host_,
282 stream_id_, 323 stream_id_,
283 false)); 324 false));
284 } 325 }
285 326
286 void AudioRendererHost::AudioEntry::OnError() { 327 void AudioRendererHost::AudioEntry::OnError() {
287 BrowserThread::PostTask( 328 BrowserThread::PostTask(
288 BrowserThread::IO, 329 BrowserThread::IO,
289 FROM_HERE, 330 FROM_HERE,
290 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 331 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
291 } 332 }
292 333
293 void AudioRendererHost::DoCompleteCreation(int stream_id) { 334 void AudioRendererHost::DoCompleteCreation(
335 int stream_id,
336 const media::mojom::AudioOutput::CreateStreamCallback&
337 create_stream_callback) {
294 DCHECK_CURRENTLY_ON(BrowserThread::IO); 338 DCHECK_CURRENTLY_ON(BrowserThread::IO);
295 339
296 if (!PeerHandle()) { 340 if (!PeerHandle()) {
297 DLOG(WARNING) << "Renderer process handle is invalid."; 341 DLOG(WARNING) << "Renderer process handle is invalid.";
298 ReportErrorAndClose(stream_id); 342 ReportErrorAndCloseStream(stream_id, create_stream_callback);
299 return; 343 return;
300 } 344 }
301 345
302 AudioEntry* const entry = LookupById(stream_id); 346 AudioEntry* entry = LookupById(stream_id);
303 if (!entry) { 347 if (!entry) {
304 ReportErrorAndClose(stream_id); 348 ReportErrorAndCloseStream(stream_id, create_stream_callback);
305 return; 349 return;
306 } 350 }
307 351
308 // Once the audio stream is created then complete the creation process by 352 media::mojom::AudioOutputStreamPtr stream_ptr =
309 // mapping shared memory and sharing with the renderer process. 353 (audio_output_impls_[entry->render_frame_id()]->StreamFactory(
310 base::SharedMemoryHandle foreign_memory_handle; 354 stream_id, entry->render_frame_id(), this));
311 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 355
312 &foreign_memory_handle)) { 356 base::SharedMemoryHandle shared_memory_handle =
313 // If we failed to map and share the shared memory then close the audio 357 base::SharedMemory::DuplicateHandle(entry->shared_memory()->handle());
314 // stream and send an error message. 358
315 ReportErrorAndClose(entry->stream_id()); 359 MojoHandle mojo_foreign_memory_handle;
360
361 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
362 shared_memory_handle, entry->shared_memory()->requested_size(), false,
363 &mojo_foreign_memory_handle);
364
365 if (shared_buffer_result != MOJO_RESULT_OK) {
366 DLOG(WARNING) << "Failed to wrap transit descriptor. Closing: "
367 << shared_buffer_result;
368 ReportErrorAndCloseStream(entry->stream_id(), create_stream_callback);
316 return; 369 return;
317 } 370 }
318 371
319 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 372 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
320 373
321 base::SyncSocket::TransitDescriptor socket_descriptor; 374 base::SyncSocket::TransitDescriptor socket_descriptor;
322 375
323 // If we failed to prepare the sync socket for the renderer then we fail 376 // If we failed to prepare the sync socket for the renderer then we fail
324 // the construction of audio stream. 377 // the construction of audio stream.
325 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 378 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
326 ReportErrorAndClose(entry->stream_id()); 379 ReportErrorAndCloseStream(entry->stream_id(), create_stream_callback);
380 return;
381 }
382 mojo::ScopedSharedBufferHandle shared_buffer_handle =
383 mojo::ScopedSharedBufferHandle(
384 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
385
386 MojoHandle socket_descriptor_handle;
387 MojoResult platform_handle_result;
388
389 // The socket handle is going to be closed when |mojo_application_host_| is
390 // reset. The renderer is going to need to close the socket handle
391 // too when the output steam is closed. This is going to cause an issue
392 // because both of them are going to close the same socket handle.
393 // This is why a duplicate of the socket handler is going to be created,
394 // stored in |socket_descriptor_dup| and sent through Mojo to the renderer so
395 // it can be used by AudioOutputIPCDelegate.
396
397 base::SyncSocket::TransitDescriptor socket_descriptor_dup =
398 DuplicateSocket(socket_descriptor);
399 #if defined(OS_WIN)
400 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
401 mojo::edk::ScopedPlatformHandle(
402 mojo::edk::PlatformHandle(socket_descriptor_dup),
403 &socket_descriptor_handle);
404 #else
405 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
406 mojo::edk::ScopedPlatformHandle(
407 mojo::edk::PlatformHandle(socket_descriptor_dup.fd)),
408 &socket_descriptor_handle);
409 #endif
410
411 if (platform_handle_result != MOJO_RESULT_OK) {
412 DLOG(WARNING) << "Failed to wrap platform handle. Closing: "
413 << platform_handle_result;
414 ReportErrorAndCloseStream(stream_id, create_stream_callback);
327 return; 415 return;
328 } 416 }
329 417
330 Send(new AudioMsg_NotifyStreamCreated( 418 mojo::ScopedHandle socket_handle =
331 entry->stream_id(), foreign_memory_handle, socket_descriptor, 419 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
332 entry->shared_memory()->requested_size())); 420 create_stream_callback.Run(
421 stream_id, std::move(stream_ptr),
422 std::move(shared_buffer_handle), std::move(socket_handle));
423
424 entry->get_create_stream_callback()->reset();
333 } 425 }
334 426
335 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 427 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
336 bool is_playing) { 428 bool is_playing) {
337 DCHECK_CURRENTLY_ON(BrowserThread::IO); 429 DCHECK_CURRENTLY_ON(BrowserThread::IO);
338 430
339 AudioEntry* const entry = LookupById(stream_id); 431 AudioEntry* const entry = LookupById(stream_id);
340 if (!entry) 432 if (!entry)
341 return; 433 return;
342 434
(...skipping 30 matching lines...) Expand all
373 return controllers; 465 return controllers;
374 } 466 }
375 467
376 /////////////////////////////////////////////////////////////////////////////// 468 ///////////////////////////////////////////////////////////////////////////////
377 // IPC Messages handler 469 // IPC Messages handler
378 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) { 470 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) {
379 bool handled = true; 471 bool handled = true;
380 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message) 472 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message)
381 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization, 473 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization,
382 OnRequestDeviceAuthorization) 474 OnRequestDeviceAuthorization)
383 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
384 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) 475 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
385 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) 476 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
386 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) 477 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, CloseStream)
387 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) 478 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
388 IPC_MESSAGE_UNHANDLED(handled = false) 479 IPC_MESSAGE_UNHANDLED(handled = false)
389 IPC_END_MESSAGE_MAP() 480 IPC_END_MESSAGE_MAP()
390 481
391 return handled; 482 return handled;
392 } 483 }
393 484
394 void AudioRendererHost::OnRequestDeviceAuthorization( 485 void AudioRendererHost::OnRequestDeviceAuthorization(
395 int stream_id, 486 int stream_id,
396 int render_frame_id, 487 int render_frame_id,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 601
511 auth_data->second.first = true; 602 auth_data->second.first = true;
512 auth_data->second.second = device_info.unique_id; 603 auth_data->second.second = device_info.unique_id;
513 604
514 media::AudioParameters output_params = device_info.output_params; 605 media::AudioParameters output_params = device_info.output_params;
515 MaybeFixAudioParameters(&output_params); 606 MaybeFixAudioParameters(&output_params);
516 Send(new AudioMsg_NotifyDeviceAuthorized( 607 Send(new AudioMsg_NotifyDeviceAuthorized(
517 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); 608 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
518 } 609 }
519 610
520 void AudioRendererHost::OnCreateStream(int stream_id, 611 void AudioRendererHost::CreateStream(
521 int render_frame_id, 612 int stream_id,
522 const media::AudioParameters& params) { 613 int render_frame_id,
614 const media::AudioParameters& params,
615 const media::mojom::AudioOutput::CreateStreamCallback&
616 create_stream_callback) {
523 DCHECK_CURRENTLY_ON(BrowserThread::IO); 617 DCHECK_CURRENTLY_ON(BrowserThread::IO);
524 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 618 DVLOG(1) << "AudioRendererHost@" << this << "::CreateStream"
525 << "(stream_id=" << stream_id << ")"; 619 << "(stream_id=" << stream_id << ")";
526 620
527 const auto& auth_data = authorizations_.find(stream_id); 621 const auto& auth_data = authorizations_.find(stream_id);
528 622
529 // If no previous authorization requested, assume default device 623 // If no previous authorization requested, assume default device
530 if (auth_data == authorizations_.end()) { 624 if (auth_data == authorizations_.end()) {
531 DoCreateStream(stream_id, render_frame_id, params, std::string()); 625 DoCreateStream(stream_id, render_frame_id, params, std::string(),
626 create_stream_callback);
532 return; 627 return;
533 } 628 }
534 629
535 CHECK(auth_data->second.first); 630 CHECK(auth_data->second.first);
536 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 631 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second,
632 create_stream_callback);
537 authorizations_.erase(auth_data); 633 authorizations_.erase(auth_data);
538 } 634 }
539 635
540 void AudioRendererHost::DoCreateStream(int stream_id, 636 void AudioRendererHost::DoCreateStream(
541 int render_frame_id, 637 int stream_id,
542 const media::AudioParameters& params, 638 int render_frame_id,
543 const std::string& device_unique_id) { 639 const media::AudioParameters& params,
640 const std::string& device_unique_id,
641 const media::mojom::AudioOutput::CreateStreamCallback&
642 create_stream_callback) {
544 DCHECK_CURRENTLY_ON(BrowserThread::IO); 643 DCHECK_CURRENTLY_ON(BrowserThread::IO);
545 644
546 // media::AudioParameters is validated in the deserializer. 645 // media::AudioParameters is validated in the deserializer.
547 if (LookupById(stream_id) != NULL) { 646 if (LookupById(stream_id) != NULL) {
548 SendErrorMessage(stream_id); 647 SendErrorMessage(stream_id);
549 return; 648 return;
550 } 649 }
551 650
552 // Create the shared memory and share with the renderer process. 651 // Create the shared memory and share with the renderer process.
553 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 652 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
554 AudioBus::CalculateMemorySize(params); 653 AudioBus::CalculateMemorySize(params);
555 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 654 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
556 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { 655 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
557 SendErrorMessage(stream_id); 656 SendErrorMessage(stream_id);
558 return; 657 return;
559 } 658 }
560 659
561 std::unique_ptr<AudioSyncReader> reader( 660 std::unique_ptr<AudioSyncReader> reader(
562 new AudioSyncReader(shared_memory.get(), params)); 661 new AudioSyncReader(shared_memory.get(), params));
563 if (!reader->Init()) { 662 if (!reader->Init()) {
564 SendErrorMessage(stream_id); 663 SendErrorMessage(stream_id);
565 return; 664 return;
566 } 665 }
567 666
568 MediaObserver* const media_observer = 667 MediaObserver* const media_observer =
569 GetContentClient()->browser()->GetMediaObserver(); 668 GetContentClient()->browser()->GetMediaObserver();
570 if (media_observer) 669 if (media_observer)
571 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 670 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
572 671
573 std::unique_ptr<AudioEntry> entry( 672 std::unique_ptr<AudioEntry> entry(new AudioEntry(
574 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, 673 this, stream_id, render_frame_id, params, device_unique_id,
575 std::move(shared_memory), std::move(reader))); 674 std::move(shared_memory), std::move(reader), create_stream_callback));
576 if (mirroring_manager_) { 675 if (mirroring_manager_) {
577 mirroring_manager_->AddDiverter( 676 mirroring_manager_->AddDiverter(
578 render_process_id_, entry->render_frame_id(), entry->controller()); 677 render_process_id_, entry->render_frame_id(), entry->controller());
579 } 678 }
580 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 679 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
581 g_audio_streams_tracker.Get().IncreaseStreamCount(); 680 g_audio_streams_tracker.Get().IncreaseStreamCount();
582 681
583 audio_log_->OnCreated(stream_id, params, device_unique_id); 682 audio_log_->OnCreated(stream_id, params, device_unique_id);
584 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 683 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
585 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 684 stream_id, render_process_id_, render_frame_id, audio_log_.get());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 return; 727 return;
629 entry->controller()->SetVolume(volume); 728 entry->controller()->SetVolume(volume);
630 audio_log_->OnSetVolume(stream_id, volume); 729 audio_log_->OnSetVolume(stream_id, volume);
631 } 730 }
632 731
633 void AudioRendererHost::SendErrorMessage(int stream_id) { 732 void AudioRendererHost::SendErrorMessage(int stream_id) {
634 Send(new AudioMsg_NotifyStreamStateChanged( 733 Send(new AudioMsg_NotifyStreamStateChanged(
635 stream_id, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR)); 734 stream_id, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR));
636 } 735 }
637 736
638 void AudioRendererHost::OnCloseStream(int stream_id) { 737 void AudioRendererHost::CloseStream(int stream_id) {
639 DCHECK_CURRENTLY_ON(BrowserThread::IO); 738 DCHECK_CURRENTLY_ON(BrowserThread::IO);
640 authorizations_.erase(stream_id); 739 authorizations_.erase(stream_id);
641 740
642 // Prevent oustanding callbacks from attempting to close/delete the same 741 // Prevent oustanding callbacks from attempting to close/delete the same
643 // AudioEntry twice. 742 // AudioEntry twice.
644 AudioEntryMap::iterator i = audio_entries_.find(stream_id); 743 AudioEntryMap::iterator i = audio_entries_.find(stream_id);
645 if (i == audio_entries_.end()) 744 if (i == audio_entries_.end())
646 return; 745 return;
647 std::unique_ptr<AudioEntry> entry(i->second); 746 std::unique_ptr<AudioEntry> entry(i->second);
648 audio_entries_.erase(i); 747 audio_entries_.erase(i);
(...skipping 26 matching lines...) Expand all
675 774
676 // Make sure this isn't a stray callback executing after the stream has been 775 // Make sure this isn't a stray callback executing after the stream has been
677 // closed, so error notifications aren't sent after clients believe the stream 776 // closed, so error notifications aren't sent after clients believe the stream
678 // is closed. 777 // is closed.
679 if (!LookupById(stream_id)) 778 if (!LookupById(stream_id))
680 return; 779 return;
681 780
682 SendErrorMessage(stream_id); 781 SendErrorMessage(stream_id);
683 782
684 audio_log_->OnError(stream_id); 783 audio_log_->OnError(stream_id);
685 OnCloseStream(stream_id); 784 CloseStream(stream_id);
785 }
786
787 void AudioRendererHost::ReportErrorAndCloseStream(
788 int stream_id,
789 const media::mojom::AudioOutput::CreateStreamCallback& callback) {
790 DCHECK_CURRENTLY_ON(BrowserThread::IO);
791
792 // Make sure this isn't a stray callback executing after the stream has been
793 // closed, so error notifications aren't sent after clients believe the stream
794 // is closed.
795 if (!LookupById(stream_id))
796 return;
797
798 mojo::ScopedSharedBufferHandle shared_buffer_handle =
799 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
800
801 mojo::ScopedHandle socket_handle = mojo::ScopedHandle(mojo::Handle());
802
803 callback.Run(stream_id, media::mojom::AudioOutputStreamPtr(),
804 std::move(shared_buffer_handle), std::move(socket_handle));
805
806 audio_log_->OnError(stream_id);
807 CloseStream(stream_id);
686 } 808 }
687 809
688 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 810 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
689 DCHECK_CURRENTLY_ON(BrowserThread::IO); 811 DCHECK_CURRENTLY_ON(BrowserThread::IO);
690 812
691 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 813 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
692 return i != audio_entries_.end() ? i->second : NULL; 814 return i != audio_entries_.end() ? i->second : NULL;
693 } 815 }
694 816
695 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry, 817 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 for (AudioEntryMap::const_iterator it = audio_entries_.begin(); 852 for (AudioEntryMap::const_iterator it = audio_entries_.begin();
731 it != audio_entries_.end(); 853 it != audio_entries_.end();
732 ++it) { 854 ++it) {
733 AudioEntry* entry = it->second; 855 AudioEntry* entry = it->second;
734 if (entry->render_frame_id() == render_frame_id && entry->playing()) 856 if (entry->render_frame_id() == render_frame_id && entry->playing())
735 return true; 857 return true;
736 } 858 }
737 return false; 859 return false;
738 } 860 }
739 861
862 AudioOutputImpl* AudioRendererHost::get_audio_output_impl(
863 int render_frame_id) const {
864 auto result = audio_output_impls_.find(render_frame_id);
865 if (result != audio_output_impls_.end())
866 return result->second;
867 else
868 return NULL;
869 }
870
871 void AudioRendererHost::set_audio_output_impl(
872 int render_frame_id,
873 AudioOutputImpl* audio_output_impl) {
874 audio_output_impls_.insert(
875 std::make_pair(render_frame_id, audio_output_impl));
876 }
877
740 void AudioRendererHost::CheckOutputDeviceAccess( 878 void AudioRendererHost::CheckOutputDeviceAccess(
741 int render_frame_id, 879 int render_frame_id,
742 const std::string& device_id, 880 const std::string& device_id,
743 const url::Origin& security_origin, 881 const url::Origin& security_origin,
744 const OutputDeviceAccessCB& callback) { 882 const OutputDeviceAccessCB& callback) {
745 DCHECK_CURRENTLY_ON(BrowserThread::IO); 883 DCHECK_CURRENTLY_ON(BrowserThread::IO);
746 884
747 // Check security origin if nondefault device is requested. 885 // Check security origin if nondefault device is requested.
748 // Ignore check for default device, which is always authorized. 886 // Ignore check for default device, which is always authorized.
749 if (!media::AudioDeviceDescription::IsDefaultDevice(device_id) && 887 if (!media::AudioDeviceDescription::IsDefaultDevice(device_id) &&
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 callback.Run(false, device_info); 946 callback.Run(false, device_info);
809 } 947 }
810 948
811 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 949 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
812 DCHECK_CURRENTLY_ON(BrowserThread::IO); 950 DCHECK_CURRENTLY_ON(BrowserThread::IO);
813 const auto& i = authorizations_.find(stream_id); 951 const auto& i = authorizations_.find(stream_id);
814 return i != authorizations_.end(); 952 return i != authorizations_.end();
815 } 953 }
816 954
817 } // namespace content 955 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698