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

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 Per'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) {
224 SendErrorMessage(stream_id);
225 DLOG(WARNING) << "No permission has been granted to input stream with "
226 << "session_id=" << session_id;
227 return;
228 }
229
230 device_id = info->device.id;
231 }
232
230 media::AudioParameters audio_params(params); 233 media::AudioParameters audio_params(params);
231
232 if (media_stream_manager_->audio_input_device_manager()-> 234 if (media_stream_manager_->audio_input_device_manager()->
233 ShouldUseFakeDevice()) { 235 ShouldUseFakeDevice()) {
234 audio_params.Reset(media::AudioParameters::AUDIO_FAKE, 236 audio_params.Reset(media::AudioParameters::AUDIO_FAKE,
235 params.channel_layout(), params.channels(), 0, 237 params.channel_layout(), params.channels(), 0,
236 params.sample_rate(), 238 params.sample_rate(),
237 params.bits_per_sample(), params.frames_per_buffer()); 239 params.bits_per_sample(), params.frames_per_buffer());
238 } 240 }
239 241
240 uint32 buffer_size = audio_params.GetBytesPerBuffer(); 242 uint32 buffer_size = audio_params.GetBytesPerBuffer();
241 243
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 entry->controller->Record(); 325 entry->controller->Record();
324 } 326 }
325 327
326 void AudioInputRendererHost::OnCloseStream(int stream_id) { 328 void AudioInputRendererHost::OnCloseStream(int stream_id) {
327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
328 330
329 AudioEntry* entry = LookupById(stream_id); 331 AudioEntry* entry = LookupById(stream_id);
330 332
331 if (entry) 333 if (entry)
332 CloseAndDeleteStream(entry); 334 CloseAndDeleteStream(entry);
333
334 int session_id = LookupSessionById(stream_id);
335
336 if (session_id)
337 StopAndDeleteDevice(session_id);
338 } 335 }
339 336
340 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { 337 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
342 339
343 AudioEntry* entry = LookupById(stream_id); 340 AudioEntry* entry = LookupById(stream_id);
344 if (!entry) { 341 if (!entry) {
345 SendErrorMessage(stream_id); 342 SendErrorMessage(stream_id);
346 return; 343 return;
347 } 344 }
348 345
349 entry->controller->SetVolume(volume); 346 entry->controller->SetVolume(volume);
350 } 347 }
351 348
352 void AudioInputRendererHost::SendErrorMessage(int stream_id) { 349 void AudioInputRendererHost::SendErrorMessage(int stream_id) {
353 Send(new AudioInputMsg_NotifyStreamStateChanged( 350 Send(new AudioInputMsg_NotifyStreamStateChanged(
354 stream_id, media::AudioInputIPCDelegate::kError)); 351 stream_id, media::AudioInputIPCDelegate::kError));
355 } 352 }
356 353
357 void AudioInputRendererHost::DeleteEntries() { 354 void AudioInputRendererHost::DeleteEntries() {
358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
359 356
360 for (AudioEntryMap::iterator i = audio_entries_.begin(); 357 for (AudioEntryMap::iterator i = audio_entries_.begin();
361 i != audio_entries_.end(); ++i) { 358 i != audio_entries_.end(); ++i) {
362 CloseAndDeleteStream(i->second); 359 CloseAndDeleteStream(i->second);
363 } 360 }
364 } 361 }
365 362
366 void AudioInputRendererHost::OnDeviceStarted(
367 int session_id, const std::string& device_id) {
368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
369 SessionEntryMap::iterator it = session_entries_.find(session_id);
370 if (it == session_entries_.end()) {
371 DLOG(WARNING) << "AudioInputRendererHost::OnDeviceStarted()"
372 " session does not exist.";
373 return;
374 }
375
376 // Notify the renderer with the id of the opened device.
377 Send(new AudioInputMsg_NotifyDeviceStarted(it->second, device_id));
378 }
379
380 void AudioInputRendererHost::OnDeviceStopped(int session_id) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
382
383 SessionEntryMap::iterator it = session_entries_.find(session_id);
384 // Return if the stream has been closed.
385 if (it == session_entries_.end())
386 return;
387
388 int stream_id = it->second;
389 AudioEntry* entry = LookupById(stream_id);
390
391 if (entry) {
392 // Device has been stopped, close the input stream.
393 CloseAndDeleteStream(entry);
394 // Notify the renderer that the state of the input stream has changed.
395 Send(new AudioInputMsg_NotifyStreamStateChanged(
396 stream_id, media::AudioInputIPCDelegate::kStopped));
397 }
398
399 // Delete the session entry.
400 session_entries_.erase(it);
401 }
402
403 void AudioInputRendererHost::StopAndDeleteDevice(int session_id) {
404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
405
406 media_stream_manager_->audio_input_device_manager()->Stop(session_id);
407
408 // Delete the session entry.
409 session_entries_.erase(session_id);
410 }
411
412 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 363 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
414 365
415 if (!entry->pending_close) { 366 if (!entry->pending_close) {
416 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry, 367 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry,
417 this, entry)); 368 this, entry));
418 entry->pending_close = true; 369 entry->pending_close = true;
419 } 370 }
420 } 371 }
421 372
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 // Iterate the map of entries. 406 // Iterate the map of entries.
456 // TODO(hclam): Implement a faster look up method. 407 // TODO(hclam): Implement a faster look up method.
457 for (AudioEntryMap::iterator i = audio_entries_.begin(); 408 for (AudioEntryMap::iterator i = audio_entries_.begin();
458 i != audio_entries_.end(); ++i) { 409 i != audio_entries_.end(); ++i) {
459 if (controller == i->second->controller.get()) 410 if (controller == i->second->controller.get())
460 return i->second; 411 return i->second;
461 } 412 }
462 return NULL; 413 return NULL;
463 } 414 }
464 415
465 int AudioInputRendererHost::LookupSessionById(int stream_id) {
466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
467
468 for (SessionEntryMap::iterator it = session_entries_.begin();
469 it != session_entries_.end(); ++it) {
470 if (stream_id == it->second) {
471 return it->first;
472 }
473 }
474 return 0;
475 }
476
477 } // namespace content 416 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698