1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/audio/mac/audio_device_listener_mac.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/mac/mac_logging.h"
11 #include "base/mac/mac_util.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/pending_task.h"
14 #include "media/audio/mac/audio_low_latency_output_mac.h"
18 // Property address to monitor for device changes.
19 const AudioObjectPropertyAddress
20 AudioDeviceListenerMac::kDeviceChangePropertyAddress = {
21 kAudioHardwarePropertyDefaultOutputDevice,
22 kAudioObjectPropertyScopeGlobal,
23 kAudioObjectPropertyElementMaster
26 // Callback from the system when the default device changes; this must be called
27 // on the MessageLoop that created the AudioManager.
29 OSStatus AudioDeviceListenerMac::OnDefaultDeviceChanged(
30 AudioObjectID object, UInt32 num_addresses,
31 const AudioObjectPropertyAddress addresses[], void* context) {
32 if (object != kAudioObjectSystemObject)
35 for (UInt32 i = 0; i < num_addresses; ++i) {
36 if (addresses[i].mSelector == kDeviceChangePropertyAddress.mSelector &&
37 addresses[i].mScope == kDeviceChangePropertyAddress.mScope &&
38 addresses[i].mElement == kDeviceChangePropertyAddress.mElement &&
40 static_cast<AudioDeviceListenerMac*>(context)->listener_cb_.Run();
48 AudioDeviceListenerMac::AudioDeviceListenerMac(
49 const base::Closure& listener_cb) {
50 OSStatus result = AudioObjectAddPropertyListener(
51 kAudioObjectSystemObject, &kDeviceChangePropertyAddress,
52 &AudioDeviceListenerMac::OnDefaultDeviceChanged, this);
54 if (result != noErr) {
55 OSSTATUS_DLOG(ERROR, result)
56 << "AudioObjectAddPropertyListener() failed!";
60 listener_cb_ = listener_cb;
63 AudioDeviceListenerMac::~AudioDeviceListenerMac() {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 if (listener_cb_.is_null())
68 // Since we're running on the same CFRunLoop, there can be no outstanding
69 // callbacks in flight.
70 OSStatus result = AudioObjectRemovePropertyListener(
71 kAudioObjectSystemObject, &kDeviceChangePropertyAddress,
72 &AudioDeviceListenerMac::OnDefaultDeviceChanged, this);
73 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
74 << "AudioObjectRemovePropertyListener() failed!";