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

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

Issue 12440027: Do not pass the string device_id via IPC message to create an audio input stream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed palmer's comments Created 7 years, 9 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 | Annotate | Revision Log
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_input_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/process.h" 9 #include "base/process.h"
10 #include "base/shared_memory.h" 10 #include "base/shared_memory.h"
11 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 11 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
12 #include "content/browser/renderer_host/media/audio_input_sync_writer.h" 12 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
13 #include "content/browser/renderer_host/media/media_stream_manager.h" 13 #include "content/browser/renderer_host/media/media_stream_manager.h"
14 #include "content/browser/renderer_host/media/web_contents_audio_input_stream.h" 14 #include "content/browser/renderer_host/media/web_contents_audio_input_stream.h"
15 #include "content/browser/renderer_host/media/web_contents_capture_util.h" 15 #include "content/browser/renderer_host/media/web_contents_capture_util.h"
16 #include "content/common/media/audio_messages.h" 16 #include "content/common/media/audio_messages.h"
17 #include "media/audio/audio_manager_base.h"
17 18
18 namespace content { 19 namespace content {
19 20
20 struct AudioInputRendererHost::AudioEntry { 21 struct AudioInputRendererHost::AudioEntry {
21 AudioEntry(); 22 AudioEntry();
22 ~AudioEntry(); 23 ~AudioEntry();
23 24
24 // The AudioInputController that manages the audio input stream. 25 // The AudioInputController that manages the audio input stream.
25 scoped_refptr<media::AudioInputController> controller; 26 scoped_refptr<media::AudioInputController> controller;
26 27
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 if (!entry) 181 if (!entry)
181 return; 182 return;
182 183
183 DeleteEntryOnError(entry); 184 DeleteEntryOnError(entry);
184 } 185 }
185 186
186 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message, 187 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message,
187 bool* message_was_ok) { 188 bool* message_was_ok) {
188 bool handled = true; 189 bool handled = true;
189 IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok) 190 IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok)
190 IPC_MESSAGE_HANDLER(AudioInputHostMsg_StartDevice, OnStartDevice)
191 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream) 191 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream)
192 IPC_MESSAGE_HANDLER(AudioInputHostMsg_AssociateStreamWithConsumer, 192 IPC_MESSAGE_HANDLER(AudioInputHostMsg_AssociateStreamWithConsumer,
193 OnAssociateStreamWithConsumer) 193 OnAssociateStreamWithConsumer)
194 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream) 194 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream)
195 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream) 195 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream)
196 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume) 196 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume)
197 IPC_MESSAGE_UNHANDLED(handled = false) 197 IPC_MESSAGE_UNHANDLED(handled = false)
198 IPC_END_MESSAGE_MAP_EX() 198 IPC_END_MESSAGE_MAP_EX()
199 199
200 return handled; 200 return handled;
201 } 201 }
202 202
203 void AudioInputRendererHost::OnStartDevice(int stream_id, int session_id) {
204 VLOG(1) << "AudioInputRendererHost::OnStartDevice(stream_id="
205 << stream_id << ", session_id = " << session_id << ")";
206
207 // Add the session entry to the map.
208 session_entries_[session_id] = stream_id;
209
210 // Start the device with the session_id. If the device is started
211 // successfully, OnDeviceStarted() callback will be triggered.
212 media_stream_manager_->audio_input_device_manager()->Start(session_id, this);
213 }
214
215 void AudioInputRendererHost::OnCreateStream( 203 void AudioInputRendererHost::OnCreateStream(
216 int stream_id, 204 int stream_id,
205 int session_id,
217 const media::AudioParameters& params, 206 const media::AudioParameters& params,
218 const std::string& device_id,
219 bool automatic_gain_control, 207 bool automatic_gain_control,
220 int shared_memory_count) { 208 int shared_memory_count) {
221 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id=" 209 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id="
222 << stream_id << ")"; 210 << stream_id << ", session_id=" << session_id << ")";
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
224 // media::AudioParameters is validated in the deserializer. 212 // media::AudioParameters is validated in the deserializer.
225 if (LookupById(stream_id) != NULL) { 213 if (LookupById(stream_id) != NULL) {
226 SendErrorMessage(stream_id); 214 SendErrorMessage(stream_id);
227 return; 215 return;
228 } 216 }
229 217
218 // Check if we have the permission to open the device and which device to use.
219 std::string device_id = media::AudioManagerBase::kDefaultDeviceId;
220 if (session_id != AudioInputDeviceManager::kFakeOpenSessionId) {
221 const StreamDeviceInfo& info = media_stream_manager_->
222 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id);
223 if (info.device.id.empty()) {
224 // An empty device info indicates that no permission has been granted.
225 SendErrorMessage(stream_id);
226 DLOG(WARNING) << "No permission has been granted to input stream with "
227 << "session_id=" << session_id;
228 return;
229 }
230
231 device_id = info.device.id;
232 }
233
230 media::AudioParameters audio_params(params); 234 media::AudioParameters audio_params(params);
231
232 if (media_stream_manager_->audio_input_device_manager()-> 235 if (media_stream_manager_->audio_input_device_manager()->
233 ShouldUseFakeDevice()) { 236 ShouldUseFakeDevice()) {
234 audio_params.Reset(media::AudioParameters::AUDIO_FAKE, 237 audio_params.Reset(media::AudioParameters::AUDIO_FAKE,
235 params.channel_layout(), 0, params.sample_rate(), 238 params.channel_layout(), 0, params.sample_rate(),
236 params.bits_per_sample(), params.frames_per_buffer()); 239 params.bits_per_sample(), params.frames_per_buffer());
237 } 240 }
238 241
239 uint32 buffer_size = audio_params.GetBytesPerBuffer(); 242 uint32 buffer_size = audio_params.GetBytesPerBuffer();
240 243
241 // Create a new AudioEntry structure. 244 // Create a new AudioEntry structure.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 entry->controller->Record(); 325 entry->controller->Record();
323 } 326 }
324 327
325 void AudioInputRendererHost::OnCloseStream(int stream_id) { 328 void AudioInputRendererHost::OnCloseStream(int stream_id) {
326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
327 330
328 AudioEntry* entry = LookupById(stream_id); 331 AudioEntry* entry = LookupById(stream_id);
329 332
330 if (entry) 333 if (entry)
331 CloseAndDeleteStream(entry); 334 CloseAndDeleteStream(entry);
332
333 int session_id = LookupSessionById(stream_id);
334
335 if (session_id)
336 StopAndDeleteDevice(session_id);
337 } 335 }
338 336
339 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { 337 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
341 339
342 AudioEntry* entry = LookupById(stream_id); 340 AudioEntry* entry = LookupById(stream_id);
343 if (!entry) { 341 if (!entry) {
344 SendErrorMessage(stream_id); 342 SendErrorMessage(stream_id);
345 return; 343 return;
346 } 344 }
347 345
348 entry->controller->SetVolume(volume); 346 entry->controller->SetVolume(volume);
349 } 347 }
350 348
351 void AudioInputRendererHost::SendErrorMessage(int stream_id) { 349 void AudioInputRendererHost::SendErrorMessage(int stream_id) {
352 Send(new AudioInputMsg_NotifyStreamStateChanged( 350 Send(new AudioInputMsg_NotifyStreamStateChanged(
353 stream_id, media::AudioInputIPCDelegate::kError)); 351 stream_id, media::AudioInputIPCDelegate::kError));
354 } 352 }
355 353
356 void AudioInputRendererHost::DeleteEntries() { 354 void AudioInputRendererHost::DeleteEntries() {
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
358 356
359 for (AudioEntryMap::iterator i = audio_entries_.begin(); 357 for (AudioEntryMap::iterator i = audio_entries_.begin();
360 i != audio_entries_.end(); ++i) { 358 i != audio_entries_.end(); ++i) {
361 CloseAndDeleteStream(i->second); 359 CloseAndDeleteStream(i->second);
362 } 360 }
363 } 361 }
364 362
365 void AudioInputRendererHost::OnDeviceStarted(
366 int session_id, const std::string& device_id) {
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
368 SessionEntryMap::iterator it = session_entries_.find(session_id);
369 if (it == session_entries_.end()) {
370 DLOG(WARNING) << "AudioInputRendererHost::OnDeviceStarted()"
371 " session does not exist.";
372 return;
373 }
374
375 // Notify the renderer with the id of the opened device.
376 Send(new AudioInputMsg_NotifyDeviceStarted(it->second, device_id));
377 }
378
379 void AudioInputRendererHost::OnDeviceStopped(int session_id) {
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
381
382 SessionEntryMap::iterator it = session_entries_.find(session_id);
383 // Return if the stream has been closed.
384 if (it == session_entries_.end())
385 return;
386
387 int stream_id = it->second;
388 AudioEntry* entry = LookupById(stream_id);
389
390 if (entry) {
391 // Device has been stopped, close the input stream.
392 CloseAndDeleteStream(entry);
393 // Notify the renderer that the state of the input stream has changed.
394 Send(new AudioInputMsg_NotifyStreamStateChanged(
395 stream_id, media::AudioInputIPCDelegate::kStopped));
396 }
397
398 // Delete the session entry.
399 session_entries_.erase(it);
400 }
401
402 void AudioInputRendererHost::StopAndDeleteDevice(int session_id) {
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
404
405 media_stream_manager_->audio_input_device_manager()->Stop(session_id);
406
407 // Delete the session entry.
408 session_entries_.erase(session_id);
409 }
410
411 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 363 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
413 365
414 if (!entry->pending_close) { 366 if (!entry->pending_close) {
415 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry, 367 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry,
416 this, entry)); 368 this, entry));
417 entry->pending_close = true; 369 entry->pending_close = true;
418 } 370 }
419 } 371 }
420 372
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 // Iterate the map of entries. 406 // Iterate the map of entries.
455 // TODO(hclam): Implement a faster look up method. 407 // TODO(hclam): Implement a faster look up method.
456 for (AudioEntryMap::iterator i = audio_entries_.begin(); 408 for (AudioEntryMap::iterator i = audio_entries_.begin();
457 i != audio_entries_.end(); ++i) { 409 i != audio_entries_.end(); ++i) {
458 if (controller == i->second->controller.get()) 410 if (controller == i->second->controller.get())
459 return i->second; 411 return i->second;
460 } 412 }
461 return NULL; 413 return NULL;
462 } 414 }
463 415
464 int AudioInputRendererHost::LookupSessionById(int stream_id) {
465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
466
467 for (SessionEntryMap::iterator it = session_entries_.begin();
468 it != session_entries_.end(); ++it) {
469 if (stream_id == it->second) {
470 return it->first;
471 }
472 }
473 return 0;
474 }
475
476 } // namespace content 416 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698