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

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: ready for review 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 if (!entry) 177 if (!entry)
177 return; 178 return;
178 179
179 DeleteEntryOnError(entry); 180 DeleteEntryOnError(entry);
180 } 181 }
181 182
182 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message, 183 bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message,
183 bool* message_was_ok) { 184 bool* message_was_ok) {
184 bool handled = true; 185 bool handled = true;
185 IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok) 186 IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok)
186 IPC_MESSAGE_HANDLER(AudioInputHostMsg_StartDevice, OnStartDevice)
187 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream) 187 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream)
188 IPC_MESSAGE_HANDLER(AudioInputHostMsg_AssociateStreamWithConsumer, 188 IPC_MESSAGE_HANDLER(AudioInputHostMsg_AssociateStreamWithConsumer,
189 OnAssociateStreamWithConsumer) 189 OnAssociateStreamWithConsumer)
190 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream) 190 IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream)
191 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream) 191 IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream)
192 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume) 192 IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume)
193 IPC_MESSAGE_UNHANDLED(handled = false) 193 IPC_MESSAGE_UNHANDLED(handled = false)
194 IPC_END_MESSAGE_MAP_EX() 194 IPC_END_MESSAGE_MAP_EX()
195 195
196 return handled; 196 return handled;
197 } 197 }
198 198
199 void AudioInputRendererHost::OnStartDevice(int stream_id, int session_id) {
200 VLOG(1) << "AudioInputRendererHost::OnStartDevice(stream_id="
201 << stream_id << ", session_id = " << session_id << ")";
202
203 // Add the session entry to the map.
204 session_entries_[session_id] = stream_id;
205
206 // Start the device with the session_id. If the device is started
207 // successfully, OnDeviceStarted() callback will be triggered.
208 media_stream_manager_->audio_input_device_manager()->Start(session_id, this);
209 }
210
211 void AudioInputRendererHost::OnCreateStream( 199 void AudioInputRendererHost::OnCreateStream(
212 int stream_id, const media::AudioParameters& params, 200 int stream_id, int session_id, const media::AudioParameters& params,
213 const std::string& device_id, bool automatic_gain_control) { 201 bool automatic_gain_control) {
214 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id=" 202 VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id="
215 << stream_id << ")"; 203 << stream_id << ", session_id=" << session_id << ")";
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
217 // media::AudioParameters is validated in the deserializer. 205 // media::AudioParameters is validated in the deserializer.
218 if (LookupById(stream_id) != NULL) { 206 if (LookupById(stream_id) != NULL) {
219 SendErrorMessage(stream_id); 207 SendErrorMessage(stream_id);
220 return; 208 return;
221 } 209 }
222 210
211 // Check if we have the permission to open the device and which device to use.
212 std::string device_id = media::AudioManagerBase::kDefaultDeviceId;
213 if (session_id != AudioInputDeviceManager::kFakeOpenSessionId) {
palmer 2013/03/12 17:45:11 NIT: Two spaces after the "!=". Just use one.
no longer working on chromium 2013/03/14 10:47:32 Done.
214 const StreamDeviceInfo& info = media_stream_manager_->
215 audio_input_device_manager()->GetOpenedDeviceInfoById(session_id);
216 if (info.device.id.empty()) {
217 // An empty device info indicates that no permission has been granted .
palmer 2013/03/12 17:45:11 NIT: Space before period.
no longer working on chromium 2013/03/14 10:47:32 Done.
218 SendErrorMessage(stream_id);
219 DLOG(WARNING) << "No permission has been granted to input stream with "
220 << "session_id=" << session_id;
221 return;
222 }
223
224 device_id = info.device.id;
225 }
226
223 media::AudioParameters audio_params(params); 227 media::AudioParameters audio_params(params);
224
225 if (media_stream_manager_->audio_input_device_manager()-> 228 if (media_stream_manager_->audio_input_device_manager()->
226 ShouldUseFakeDevice()) { 229 ShouldUseFakeDevice()) {
227 audio_params.Reset(media::AudioParameters::AUDIO_FAKE, 230 audio_params.Reset(media::AudioParameters::AUDIO_FAKE,
228 params.channel_layout(), 0, params.sample_rate(), 231 params.channel_layout(), 0, params.sample_rate(),
229 params.bits_per_sample(), params.frames_per_buffer()); 232 params.bits_per_sample(), params.frames_per_buffer());
230 } 233 }
231 234
232 uint32 buffer_size = audio_params.GetBytesPerBuffer(); 235 uint32 buffer_size = audio_params.GetBytesPerBuffer();
233 236
234 // Create a new AudioEntry structure. 237 // Create a new AudioEntry structure.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 entry->controller->Record(); 314 entry->controller->Record();
312 } 315 }
313 316
314 void AudioInputRendererHost::OnCloseStream(int stream_id) { 317 void AudioInputRendererHost::OnCloseStream(int stream_id) {
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
316 319
317 AudioEntry* entry = LookupById(stream_id); 320 AudioEntry* entry = LookupById(stream_id);
318 321
319 if (entry) 322 if (entry)
320 CloseAndDeleteStream(entry); 323 CloseAndDeleteStream(entry);
321
322 int session_id = LookupSessionById(stream_id);
323
324 if (session_id)
325 StopAndDeleteDevice(session_id);
326 } 324 }
327 325
328 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { 326 void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
330 328
331 AudioEntry* entry = LookupById(stream_id); 329 AudioEntry* entry = LookupById(stream_id);
332 if (!entry) { 330 if (!entry) {
333 SendErrorMessage(stream_id); 331 SendErrorMessage(stream_id);
334 return; 332 return;
335 } 333 }
336 334
337 entry->controller->SetVolume(volume); 335 entry->controller->SetVolume(volume);
338 } 336 }
339 337
340 void AudioInputRendererHost::SendErrorMessage(int stream_id) { 338 void AudioInputRendererHost::SendErrorMessage(int stream_id) {
341 Send(new AudioInputMsg_NotifyStreamStateChanged( 339 Send(new AudioInputMsg_NotifyStreamStateChanged(
342 stream_id, media::AudioInputIPCDelegate::kError)); 340 stream_id, media::AudioInputIPCDelegate::kError));
343 } 341 }
344 342
345 void AudioInputRendererHost::DeleteEntries() { 343 void AudioInputRendererHost::DeleteEntries() {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
347 345
348 for (AudioEntryMap::iterator i = audio_entries_.begin(); 346 for (AudioEntryMap::iterator i = audio_entries_.begin();
349 i != audio_entries_.end(); ++i) { 347 i != audio_entries_.end(); ++i) {
350 CloseAndDeleteStream(i->second); 348 CloseAndDeleteStream(i->second);
351 } 349 }
352 } 350 }
353 351
354 void AudioInputRendererHost::OnDeviceStarted(
355 int session_id, const std::string& device_id) {
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
357 SessionEntryMap::iterator it = session_entries_.find(session_id);
358 if (it == session_entries_.end()) {
359 DLOG(WARNING) << "AudioInputRendererHost::OnDeviceStarted()"
360 " session does not exist.";
361 return;
362 }
363
364 // Notify the renderer with the id of the opened device.
365 Send(new AudioInputMsg_NotifyDeviceStarted(it->second, device_id));
366 }
367
368 void AudioInputRendererHost::OnDeviceStopped(int session_id) {
369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
370
371 SessionEntryMap::iterator it = session_entries_.find(session_id);
372 // Return if the stream has been closed.
373 if (it == session_entries_.end())
374 return;
375
376 int stream_id = it->second;
377 AudioEntry* entry = LookupById(stream_id);
378
379 if (entry) {
380 // Device has been stopped, close the input stream.
381 CloseAndDeleteStream(entry);
382 // Notify the renderer that the state of the input stream has changed.
383 Send(new AudioInputMsg_NotifyStreamStateChanged(
384 stream_id, media::AudioInputIPCDelegate::kStopped));
385 }
386
387 // Delete the session entry.
388 session_entries_.erase(it);
389 }
390
391 void AudioInputRendererHost::StopAndDeleteDevice(int session_id) {
392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
393
394 media_stream_manager_->audio_input_device_manager()->Stop(session_id);
395
396 // Delete the session entry.
397 session_entries_.erase(session_id);
398 }
399
400 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 352 void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
402 354
403 if (!entry->pending_close) { 355 if (!entry->pending_close) {
404 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry, 356 entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry,
405 this, entry)); 357 this, entry));
406 entry->pending_close = true; 358 entry->pending_close = true;
407 } 359 }
408 } 360 }
409 361
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Iterate the map of entries. 395 // Iterate the map of entries.
444 // TODO(hclam): Implement a faster look up method. 396 // TODO(hclam): Implement a faster look up method.
445 for (AudioEntryMap::iterator i = audio_entries_.begin(); 397 for (AudioEntryMap::iterator i = audio_entries_.begin();
446 i != audio_entries_.end(); ++i) { 398 i != audio_entries_.end(); ++i) {
447 if (controller == i->second->controller.get()) 399 if (controller == i->second->controller.get())
448 return i->second; 400 return i->second;
449 } 401 }
450 return NULL; 402 return NULL;
451 } 403 }
452 404
453 int AudioInputRendererHost::LookupSessionById(int stream_id) {
454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
455
456 for (SessionEntryMap::iterator it = session_entries_.begin();
457 it != session_entries_.end(); ++it) {
458 if (stream_id == it->second) {
459 return it->first;
460 }
461 }
462 return 0;
463 }
464
465 } // namespace content 405 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698