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

Unified Diff: media/audio/audio_output_device.cc

Issue 2043883005: Implementing AudioOutputDevice authorization timeout (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: guidou@'s comments addressed Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: media/audio/audio_output_device.cc
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index a3effebfb43af118500197a6eed9a48093563f7d..7d5fa103dd3863c6dbdd7cb1a0c4c8e03edb9817 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -12,8 +12,10 @@
#include "base/callback_helpers.h"
#include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "media/audio/audio_device_description.h"
@@ -52,7 +54,8 @@ AudioOutputDevice::AudioOutputDevice(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
int session_id,
const std::string& device_id,
- const url::Origin& security_origin)
+ const url::Origin& security_origin,
+ base::TimeDelta authorization_timeout)
: ScopedTaskRunnerObserver(io_task_runner),
callback_(NULL),
ipc_(std::move(ipc)),
@@ -65,7 +68,8 @@ AudioOutputDevice::AudioOutputDevice(
stopping_hack_(false),
did_receive_auth_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
- device_status_(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL) {
+ device_status_(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL),
+ auth_timeout_(authorization_timeout) {
CHECK(ipc_);
// The correctness of the code depends on the relative values assigned in the
@@ -156,6 +160,16 @@ void AudioOutputDevice::RequestDeviceAuthorizationOnIOThread() {
state_ = AUTHORIZING;
ipc_->RequestDeviceAuthorization(this, session_id_, device_id_,
security_origin_);
+
+ // Create the timer on the thread it's used on. It's guaranteed to be
+ // deleted on the same thread since users must call Stop() before deleting
+ // AudioOutputDevice; see ShutDownOnIOThread().
+ auth_timeout_action_.reset(new base::OneShotTimer());
+ auth_timeout_action_->Start(
+ FROM_HERE, auth_timeout_,
+ base::Bind(&AudioOutputDevice::ProcessDeviceAuthorizationOnIOThread, this,
+ OUTPUT_DEVICE_STATUS_ERROR_INTERNAL, media::AudioParameters(),
DaleCurtis 2016/06/13 18:30:09 This is fine with me, but have you considered addi
o1ka 2016/06/14 10:33:05 Good idea! Done.
+ std::string(), true /* timed out */));
}
void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
@@ -229,6 +243,9 @@ void AudioOutputDevice::ShutDownOnIOThread() {
}
start_on_authorized_ = false;
+ // Destoy the timer on the thread it's used on.
+ auth_timeout_action_.reset(nullptr);
DaleCurtis 2016/06/13 18:30:09 reset(nullptr) is unnecessary. just .reset()
o1ka 2016/06/14 10:33:05 Done.
+
// We can run into an issue where ShutDownOnIOThread is called right after
// OnStreamCreated is called in cases where Start/Stop are called before we
// get the OnStreamCreated callback. To handle that corner case, we call
@@ -250,41 +267,26 @@ void AudioOutputDevice::SetVolumeOnIOThread(double volume) {
ipc_->SetVolume(volume);
}
-void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegateState state) {
+void AudioOutputDevice::ProcessDeviceAuthorizationOnIOThread(
+ OutputDeviceStatus device_status,
+ const media::AudioParameters& output_params,
+ const std::string& matched_device_id,
+ bool timed_out) {
DCHECK(task_runner()->BelongsToCurrentThread());
- // Do nothing if the stream has been closed.
- if (state_ < CREATING_STREAM)
+ if (auth_timeout_action_) {
DaleCurtis 2016/06/13 18:30:09 Just auth_timeout_action_.reset() is sufficient.
o1ka 2016/06/14 10:33:05 Done.
+ auth_timeout_action_->Stop();
+ auth_timeout_action_.reset(nullptr);
+ }
+
+ // Do nothing if late authorization is received after timeout.
+ if (state_ == IPC_CLOSED && !timed_out)
return;
- // TODO(miu): Clean-up inconsistent and incomplete handling here.
- // http://crbug.com/180640
- switch (state) {
- case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PLAYING:
- case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED:
- break;
- case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR:
- DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)";
- // Don't dereference the callback object if the audio thread
- // is stopped or stopping. That could mean that the callback
- // object has been deleted.
- // TODO(tommi): Add an explicit contract for clearing the callback
- // object. Possibly require calling Initialize again or provide
- // a callback object via Start() and clear it in Stop().
- if (!audio_thread_.IsStopped())
- callback_->OnRenderError();
- break;
- default:
- NOTREACHED();
- break;
- }
-}
+ UMA_HISTOGRAM_BOOLEAN("Media.Audio.Render.OutputDeviceAuthorizationTimedOut",
+ timed_out);
-void AudioOutputDevice::OnDeviceAuthorized(
- OutputDeviceStatus device_status,
- const media::AudioParameters& output_params,
- const std::string& matched_device_id) {
- DCHECK(task_runner()->BelongsToCurrentThread());
+ DCHECK(!timed_out || device_status == OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
DCHECK_EQ(state_, AUTHORIZING);
// It may happen that a second authorization is received as a result to a
@@ -329,6 +331,44 @@ void AudioOutputDevice::OnDeviceAuthorized(
}
}
+void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegateState state) {
+ DCHECK(task_runner()->BelongsToCurrentThread());
+
+ // Do nothing if the stream has been closed.
+ if (state_ < CREATING_STREAM)
+ return;
+
+ // TODO(miu): Clean-up inconsistent and incomplete handling here.
+ // http://crbug.com/180640
+ switch (state) {
+ case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PLAYING:
+ case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED:
+ break;
+ case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR:
+ DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)";
+ // Don't dereference the callback object if the audio thread
+ // is stopped or stopping. That could mean that the callback
+ // object has been deleted.
+ // TODO(tommi): Add an explicit contract for clearing the callback
+ // object. Possibly require calling Initialize again or provide
+ // a callback object via Start() and clear it in Stop().
+ if (!audio_thread_.IsStopped())
+ callback_->OnRenderError();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void AudioOutputDevice::OnDeviceAuthorized(
+ OutputDeviceStatus device_status,
+ const media::AudioParameters& output_params,
+ const std::string& matched_device_id) {
+ ProcessDeviceAuthorizationOnIOThread(device_status, output_params,
+ matched_device_id, false);
+}
+
void AudioOutputDevice::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,

Powered by Google App Engine
This is Rietveld 408576698