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

Unified Diff: media/audio/mac/audio_device_listener_mac.cc

Issue 11338024: Handle audio device changes on Mac (Take 2). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Pass callback directly. Created 8 years, 2 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/mac/audio_device_listener_mac.cc
diff --git a/media/audio/mac/audio_device_listener_mac.cc b/media/audio/mac/audio_device_listener_mac.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7f0e8f15decc51c9f3eed31ea0a53086f7fd5247
--- /dev/null
+++ b/media/audio/mac/audio_device_listener_mac.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/mac/audio_device_listener_mac.h"
+
+#include <CoreAudio/CoreAudio.h>
+
+#include "base/logging.h"
+#include "base/mac/mac_logging.h"
+
+namespace media {
+
+static const AudioObjectPropertyAddress kPropertyAddress = {
+ kAudioHardwarePropertyDefaultOutputDevice,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster
+};
+
+// Callback from the system when the default device changes. This can be called
+// either on the main thread or on an audio thread managed by the system
+// depending on what kAudioHardwarePropertyRunLoop is set to.
+static OSStatus OnDefaultDeviceChangedCallback(
+ AudioObjectID object,
+ UInt32 size,
+ const AudioObjectPropertyAddress addresses[],
+ void* context) {
+ static_cast<base::Closure*>(context)->Run();
Scott Hess - ex-Googler 2012/10/31 23:39:11 If you've arranged for the callback to live foreve
scherkus (not reviewing) 2012/11/01 00:15:40 I do like having register/unregister auto-scoped,
DaleCurtis 2012/11/01 00:16:33 Indeed it could, which is exactly what the method
+ return noErr;
+}
+
+AudioDeviceListenerMac::AudioDeviceListenerMac(base::Closure* listener_cb)
+ : listener_cb_(listener_cb) {
+ CHECK(listener_cb_);
+ DCHECK(!listener_cb_->is_null());
+
+ OSStatus result = AudioObjectAddPropertyListener(
+ kAudioObjectSystemObject,
+ &kPropertyAddress,
+ &OnDefaultDeviceChangedCallback,
+ listener_cb_);
+
+ // Clear |listener_cb_| so we don't try to remove the listener later.
+ if (result != noErr) {
+ OSSTATUS_DLOG(ERROR, result) << "AudioObjectAddPropertyListener() failed!";
+ listener_cb_ = NULL;
+ }
+}
+
+AudioDeviceListenerMac::~AudioDeviceListenerMac() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // If adding the listener failed, don't try and remove it.
+ if (!listener_cb_)
scherkus (not reviewing) 2012/10/31 23:17:22 you can use is_null() instead since you DCHECK it
DaleCurtis 2012/11/01 00:16:33 No, it's set to NULL if AddPropertyListener fails.
+ return;
+
+ OSStatus result = AudioObjectRemovePropertyListener(
+ kAudioObjectSystemObject,
+ &kPropertyAddress,
+ &OnDefaultDeviceChangedCallback,
+ listener_cb_);
+
+ OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
+ << "AudioObjectRemovePropertyListener() failed!";
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698