Chromium Code Reviews| Index: media/audio/audio_output_device.cc |
| diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc |
| index d55d10077ed47870fb34521fce57bc24ae4d71c8..3e43c06c9b5d4982808e1daf9fc043585d0668d6 100644 |
| --- a/media/audio/audio_output_device.cc |
| +++ b/media/audio/audio_output_device.cc |
| @@ -4,6 +4,8 @@ |
| #include "media/audio/audio_output_device.h" |
| +#include <string> |
| + |
| #include "base/threading/thread_restrictions.h" |
| #include "base/time/time.h" |
| #include "base/trace_event/trace_event.h" |
| @@ -45,7 +47,8 @@ AudioOutputDevice::AudioOutputDevice( |
| state_(IDLE), |
| play_on_start_(true), |
| session_id_(-1), |
| - stopping_hack_(false) { |
| + stopping_hack_(false), |
| + current_switch_request_id_(0) { |
| CHECK(ipc_); |
| // The correctness of the code depends on the relative values assigned in the |
| @@ -75,6 +78,14 @@ AudioOutputDevice::~AudioOutputDevice() { |
| // The current design requires that the user calls Stop() before deleting |
| // this class. |
| DCHECK(audio_thread_.IsStopped()); |
| + |
| + // The following makes it possible for |current_switch_callback_| to release |
| + // its bound parameters in the correct thread instead of implicitly releasing |
| + // them in the thread where this destructor runs. |
| + if (current_switch_callback_) { |
| + current_switch_callback_->Run(SWITCH_OUTPUT_DEVICE_RESULT_ERROR_OBSOLETE); |
|
DaleCurtis
2015/06/15 16:58:30
you can use base::ResetAndReturn() to achieve this
|
| + current_switch_callback_ = NULL; |
| + } |
| } |
| void AudioOutputDevice::Start() { |
| @@ -117,6 +128,16 @@ bool AudioOutputDevice::SetVolume(double volume) { |
| return true; |
| } |
| +void AudioOutputDevice::SwitchOutputDevice( |
| + const std::string& device_id, |
| + const GURL& security_origin, |
| + const SwitchOutputDeviceCB& callback) { |
| + DVLOG(1) << __FUNCTION__ << "(" << device_id << ")"; |
| + task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&AudioOutputDevice::SwitchOutputDeviceOnIOThread, |
| + this, device_id, security_origin, callback)); |
| +} |
| + |
| void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) { |
| DCHECK(task_runner()->BelongsToCurrentThread()); |
| if (state_ == IDLE) { |
| @@ -179,6 +200,21 @@ void AudioOutputDevice::SetVolumeOnIOThread(double volume) { |
| ipc_->SetVolume(volume); |
| } |
| +void AudioOutputDevice::SwitchOutputDeviceOnIOThread( |
| + const std::string& device_id, |
| + const GURL& security_origin, |
| + const SwitchOutputDeviceCB& callback) { |
| + DCHECK(task_runner()->BelongsToCurrentThread()); |
| + DVLOG(1) << __FUNCTION__ << "(" << device_id << "," << security_origin << ")"; |
| + if (state_ >= CREATING_STREAM) { |
| + SetCurrentSwitchRequest(callback); |
| + ipc_->SwitchOutputDevice(device_id, security_origin, |
| + current_switch_request_id_); |
| + } else { |
| + callback.Run(SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_SUPPORTED); |
| + } |
| +} |
| + |
| void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegateState state) { |
| DCHECK(task_runner()->BelongsToCurrentThread()); |
| @@ -254,6 +290,32 @@ void AudioOutputDevice::OnStreamCreated( |
| PlayOnIOThread(); |
| } |
| +void AudioOutputDevice::SetCurrentSwitchRequest( |
| + const SwitchOutputDeviceCB& callback) { |
| + DCHECK(task_runner()->BelongsToCurrentThread()); |
| + DVLOG(1) << __FUNCTION__; |
| + // If there is a previous unresolved request, resolve it as obsolete |
| + if (current_switch_callback_) { |
| + current_switch_callback_->Run(SWITCH_OUTPUT_DEVICE_RESULT_ERROR_OBSOLETE); |
| + } |
| + current_switch_callback_.reset(new SwitchOutputDeviceCB(callback)); |
| + current_switch_request_id_++; |
| +} |
| + |
| +void AudioOutputDevice::OnOutputDeviceSwitched( |
| + int request_id, |
| + SwitchOutputDeviceResult result) { |
| + DCHECK(task_runner()->BelongsToCurrentThread()); |
| + DCHECK(request_id <= current_switch_request_id_); |
| + DVLOG(1) << __FUNCTION__ |
| + << "(" << request_id << ", " << result << ")"; |
| + if (request_id != current_switch_request_id_) { |
| + return; |
| + } |
| + current_switch_callback_->Run(result); |
| + current_switch_callback_ = NULL; |
| +} |
| + |
| void AudioOutputDevice::OnIPCClosed() { |
| DCHECK(task_runner()->BelongsToCurrentThread()); |
| state_ = IPC_CLOSED; |