| OLD | NEW |
| 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 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 return false; | 74 return false; |
| 75 | 75 |
| 76 for (const char& c : device_id) { | 76 for (const char& c : device_id) { |
| 77 if ((c < 'a' || c > 'f') && (c < '0' || c > '9')) | 77 if ((c < 'a' || c > 'f') && (c < '0' || c > '9')) |
| 78 return false; | 78 return false; |
| 79 } | 79 } |
| 80 | 80 |
| 81 return true; | 81 return true; |
| 82 } | 82 } |
| 83 | 83 |
| 84 bool IsDefaultDeviceId(const std::string& device_id) { | |
| 85 return device_id.empty() || | |
| 86 device_id == media::AudioManagerBase::kDefaultDeviceId; | |
| 87 } | |
| 88 | |
| 89 AudioOutputDeviceInfo GetDefaultDeviceInfoOnDeviceThread( | 84 AudioOutputDeviceInfo GetDefaultDeviceInfoOnDeviceThread( |
| 90 media::AudioManager* audio_manager) { | 85 media::AudioManager* audio_manager) { |
| 91 DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread()); | 86 DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread()); |
| 92 AudioOutputDeviceInfo default_device_info = { | 87 AudioOutputDeviceInfo default_device_info = { |
| 93 media::AudioManagerBase::kDefaultDeviceId, | 88 media::AudioManagerBase::kDefaultDeviceId, |
| 94 audio_manager->GetDefaultDeviceName(), | 89 audio_manager->GetDefaultDeviceName(), |
| 95 audio_manager->GetDefaultOutputStreamParameters()}; | 90 audio_manager->GetDefaultOutputStreamParameters()}; |
| 96 | 91 |
| 97 return default_device_info; | 92 return default_device_info; |
| 98 } | 93 } |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 << ", render_frame_id=" << render_frame_id | 409 << ", render_frame_id=" << render_frame_id |
| 415 << ", session_id=" << session_id << ", device_id=" << device_id | 410 << ", session_id=" << session_id << ", device_id=" << device_id |
| 416 << ", security_origin=" << security_origin << ")"; | 411 << ", security_origin=" << security_origin << ")"; |
| 417 | 412 |
| 418 if (LookupById(stream_id) || IsAuthorizationStarted(stream_id)) | 413 if (LookupById(stream_id) || IsAuthorizationStarted(stream_id)) |
| 419 return; | 414 return; |
| 420 | 415 |
| 421 if (!IsValidDeviceId(device_id)) { | 416 if (!IsValidDeviceId(device_id)) { |
| 422 Send(new AudioMsg_NotifyDeviceAuthorized( | 417 Send(new AudioMsg_NotifyDeviceAuthorized( |
| 423 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, | 418 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, |
| 424 media::AudioParameters::UnavailableDeviceParams())); | 419 media::AudioParameters::UnavailableDeviceParams(), std::string())); |
| 425 return; | 420 return; |
| 426 } | 421 } |
| 427 | 422 |
| 428 // If |device_id| is not empty, ignore |session_id| and select the device | 423 // If |session_id should be used for output device selection and such output |
| 429 // indicated by |device_id|. | 424 // device is found, reuse the input device permissions. |
| 430 // If |device_id| is empty and |session_id| is nonzero, try to use the | 425 if (media::AudioManagerBase::UseSessionIdToSelectDevice(session_id, |
| 431 // output device associated with the opened input device designated by | 426 device_id)) { |
| 432 // |session_id| and, if such output device is found, reuse the input device | |
| 433 // permissions. | |
| 434 if (session_id != 0 && device_id.empty()) { | |
| 435 const StreamDeviceInfo* info = | 427 const StreamDeviceInfo* info = |
| 436 media_stream_manager_->audio_input_device_manager() | 428 media_stream_manager_->audio_input_device_manager() |
| 437 ->GetOpenedDeviceInfoById(session_id); | 429 ->GetOpenedDeviceInfoById(session_id); |
| 438 if (info) { | 430 if (info) { |
| 439 media::AudioParameters output_params( | 431 media::AudioParameters output_params( |
| 440 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | 432 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 441 static_cast<media::ChannelLayout>( | 433 static_cast<media::ChannelLayout>( |
| 442 info->device.matched_output.channel_layout), | 434 info->device.matched_output.channel_layout), |
| 443 info->device.matched_output.sample_rate, 16, | 435 info->device.matched_output.sample_rate, 16, |
| 444 info->device.matched_output.frames_per_buffer); | 436 info->device.matched_output.frames_per_buffer); |
| 445 output_params.set_effects(info->device.matched_output.effects); | 437 output_params.set_effects(info->device.matched_output.effects); |
| 446 authorizations_.insert(MakeAuthorizationData( | 438 authorizations_.insert(MakeAuthorizationData( |
| 447 stream_id, true, info->device.matched_output_device_id)); | 439 stream_id, true, info->device.matched_output_device_id)); |
| 448 MaybeFixAudioParameters(&output_params); | 440 MaybeFixAudioParameters(&output_params); |
| 441 // Hash matched device id and pass it to the renderer |
| 442 GURL gurl_security_origin = ConvertToGURL(security_origin); |
| 449 Send(new AudioMsg_NotifyDeviceAuthorized( | 443 Send(new AudioMsg_NotifyDeviceAuthorized( |
| 450 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params)); | 444 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, |
| 445 GetHMACForMediaDeviceID(salt_callback_, gurl_security_origin, |
| 446 info->device.matched_output_device_id))); |
| 451 return; | 447 return; |
| 452 } | 448 } |
| 453 } | 449 } |
| 454 | 450 |
| 455 authorizations_.insert( | 451 authorizations_.insert( |
| 456 MakeAuthorizationData(stream_id, false, std::string())); | 452 MakeAuthorizationData(stream_id, false, std::string())); |
| 457 GURL gurl_security_origin = ConvertToGURL(security_origin); | 453 GURL gurl_security_origin = ConvertToGURL(security_origin); |
| 458 CheckOutputDeviceAccess( | 454 CheckOutputDeviceAccess( |
| 459 render_frame_id, device_id, gurl_security_origin, | 455 render_frame_id, device_id, gurl_security_origin, |
| 460 base::Bind(&AudioRendererHost::OnDeviceAuthorized, this, stream_id, | 456 base::Bind(&AudioRendererHost::OnDeviceAuthorized, this, stream_id, |
| 461 device_id, gurl_security_origin)); | 457 device_id, gurl_security_origin)); |
| 462 } | 458 } |
| 463 | 459 |
| 464 void AudioRendererHost::OnDeviceAuthorized(int stream_id, | 460 void AudioRendererHost::OnDeviceAuthorized(int stream_id, |
| 465 const std::string& device_id, | 461 const std::string& device_id, |
| 466 const GURL& gurl_security_origin, | 462 const GURL& gurl_security_origin, |
| 467 bool have_access) { | 463 bool have_access) { |
| 468 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 464 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 469 const auto& auth_data = authorizations_.find(stream_id); | 465 const auto& auth_data = authorizations_.find(stream_id); |
| 470 | 466 |
| 471 // A close request was received while access check was in progress. | 467 // A close request was received while access check was in progress. |
| 472 if (auth_data == authorizations_.end()) | 468 if (auth_data == authorizations_.end()) |
| 473 return; | 469 return; |
| 474 | 470 |
| 475 if (!have_access) { | 471 if (!have_access) { |
| 476 authorizations_.erase(auth_data); | 472 authorizations_.erase(auth_data); |
| 477 Send(new AudioMsg_NotifyDeviceAuthorized( | 473 Send(new AudioMsg_NotifyDeviceAuthorized( |
| 478 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, | 474 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, |
| 479 media::AudioParameters::UnavailableDeviceParams())); | 475 media::AudioParameters::UnavailableDeviceParams(), std::string())); |
| 480 return; | 476 return; |
| 481 } | 477 } |
| 482 | 478 |
| 483 // If enumerator caching is disabled, avoid the enumeration if the default | 479 // If enumerator caching is disabled, avoid the enumeration if the default |
| 484 // device is requested, since no device ID translation is needed. | 480 // device is requested, since no device ID translation is needed. |
| 485 // If enumerator caching is enabled, it is better to use its cache, even | 481 // If enumerator caching is enabled, it is better to use its cache, even |
| 486 // for the default device. | 482 // for the default device. |
| 487 if (IsDefaultDeviceId(device_id) && | 483 if (media::AudioManagerBase::IsDefaultDeviceId(device_id) && |
| 488 !media_stream_manager_->audio_output_device_enumerator() | 484 !media_stream_manager_->audio_output_device_enumerator() |
| 489 ->IsCacheEnabled()) { | 485 ->IsCacheEnabled()) { |
| 490 base::PostTaskAndReplyWithResult( | 486 base::PostTaskAndReplyWithResult( |
| 491 audio_manager_->GetTaskRunner().get(), FROM_HERE, | 487 audio_manager_->GetTaskRunner().get(), FROM_HERE, |
| 492 base::Bind(&GetDefaultDeviceInfoOnDeviceThread, audio_manager_), | 488 base::Bind(&GetDefaultDeviceInfoOnDeviceThread, audio_manager_), |
| 493 base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id, | 489 base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id, |
| 494 true)); | 490 true)); |
| 495 } else { | 491 } else { |
| 496 media_stream_manager_->audio_output_device_enumerator()->Enumerate( | 492 media_stream_manager_->audio_output_device_enumerator()->Enumerate( |
| 497 base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id, | 493 base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 509 const auto& auth_data = authorizations_.find(stream_id); | 505 const auto& auth_data = authorizations_.find(stream_id); |
| 510 | 506 |
| 511 // A close request was received while translation was in progress | 507 // A close request was received while translation was in progress |
| 512 if (auth_data == authorizations_.end()) | 508 if (auth_data == authorizations_.end()) |
| 513 return; | 509 return; |
| 514 | 510 |
| 515 if (!device_found) { | 511 if (!device_found) { |
| 516 authorizations_.erase(auth_data); | 512 authorizations_.erase(auth_data); |
| 517 Send(new AudioMsg_NotifyDeviceAuthorized( | 513 Send(new AudioMsg_NotifyDeviceAuthorized( |
| 518 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, | 514 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, |
| 519 media::AudioParameters::UnavailableDeviceParams())); | 515 media::AudioParameters::UnavailableDeviceParams(), std::string())); |
| 520 return; | 516 return; |
| 521 } | 517 } |
| 522 | 518 |
| 523 auth_data->second.first = true; | 519 auth_data->second.first = true; |
| 524 auth_data->second.second = device_info.unique_id; | 520 auth_data->second.second = device_info.unique_id; |
| 525 | 521 |
| 526 media::AudioParameters output_params = device_info.output_params; | 522 media::AudioParameters output_params = device_info.output_params; |
| 527 MaybeFixAudioParameters(&output_params); | 523 MaybeFixAudioParameters(&output_params); |
| 528 Send(new AudioMsg_NotifyDeviceAuthorized( | 524 Send(new AudioMsg_NotifyDeviceAuthorized( |
| 529 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params)); | 525 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); |
| 530 } | 526 } |
| 531 | 527 |
| 532 void AudioRendererHost::OnCreateStream(int stream_id, | 528 void AudioRendererHost::OnCreateStream(int stream_id, |
| 533 int render_frame_id, | 529 int render_frame_id, |
| 534 const media::AudioParameters& params) { | 530 const media::AudioParameters& params) { |
| 535 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 531 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 536 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" | 532 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" |
| 537 << "(stream_id=" << stream_id << ")"; | 533 << "(stream_id=" << stream_id << ")"; |
| 538 | 534 |
| 539 const auto& auth_data = authorizations_.find(stream_id); | 535 const auto& auth_data = authorizations_.find(stream_id); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 | 747 |
| 752 void AudioRendererHost::CheckOutputDeviceAccess( | 748 void AudioRendererHost::CheckOutputDeviceAccess( |
| 753 int render_frame_id, | 749 int render_frame_id, |
| 754 const std::string& device_id, | 750 const std::string& device_id, |
| 755 const GURL& gurl_security_origin, | 751 const GURL& gurl_security_origin, |
| 756 const OutputDeviceAccessCB& callback) { | 752 const OutputDeviceAccessCB& callback) { |
| 757 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 753 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 758 | 754 |
| 759 // Check security origin if nondefault device is requested. | 755 // Check security origin if nondefault device is requested. |
| 760 // Ignore check for default device, which is always authorized. | 756 // Ignore check for default device, which is always authorized. |
| 761 if (!IsDefaultDeviceId(device_id) && | 757 if (!media::AudioManagerBase::IsDefaultDeviceId(device_id) && |
| 762 !ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | 758 !ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( |
| 763 render_process_id_, gurl_security_origin)) { | 759 render_process_id_, gurl_security_origin)) { |
| 764 content::bad_message::ReceivedBadMessage(this, | 760 content::bad_message::ReceivedBadMessage(this, |
| 765 bad_message::ARH_UNAUTHORIZED_URL); | 761 bad_message::ARH_UNAUTHORIZED_URL); |
| 766 return; | 762 return; |
| 767 } | 763 } |
| 768 | 764 |
| 769 if (device_id.empty()) { | 765 if (device_id.empty()) { |
| 770 callback.Run(true); | 766 callback.Run(true); |
| 771 } else { | 767 } else { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 callback.Run(false, device_info); | 815 callback.Run(false, device_info); |
| 820 } | 816 } |
| 821 | 817 |
| 822 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { | 818 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { |
| 823 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 819 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 824 const auto& i = authorizations_.find(stream_id); | 820 const auto& i = authorizations_.find(stream_id); |
| 825 return i != authorizations_.end(); | 821 return i != authorizations_.end(); |
| 826 } | 822 } |
| 827 | 823 |
| 828 } // namespace content | 824 } // namespace content |
| OLD | NEW |