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 |