- add sources.
[platform/framework/web/crosswalk.git] / src / media / audio / mac / audio_device_listener_mac.cc
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.
4
5 #include "media/audio/mac/audio_device_listener_mac.h"
6
7 #include "base/bind.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"
15
16 namespace media {
17
18 // Property address to monitor for device changes.
19 const AudioObjectPropertyAddress
20 AudioDeviceListenerMac::kDeviceChangePropertyAddress = {
21   kAudioHardwarePropertyDefaultOutputDevice,
22   kAudioObjectPropertyScopeGlobal,
23   kAudioObjectPropertyElementMaster
24 };
25
26 // Callback from the system when the default device changes; this must be called
27 // on the MessageLoop that created the AudioManager.
28 // static
29 OSStatus AudioDeviceListenerMac::OnDefaultDeviceChanged(
30     AudioObjectID object, UInt32 num_addresses,
31     const AudioObjectPropertyAddress addresses[], void* context) {
32   if (object != kAudioObjectSystemObject)
33     return noErr;
34
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 &&
39         context) {
40       static_cast<AudioDeviceListenerMac*>(context)->listener_cb_.Run();
41       break;
42     }
43   }
44
45   return noErr;
46 }
47
48 AudioDeviceListenerMac::AudioDeviceListenerMac(
49     const base::Closure& listener_cb) {
50   OSStatus result = AudioObjectAddPropertyListener(
51       kAudioObjectSystemObject, &kDeviceChangePropertyAddress,
52       &AudioDeviceListenerMac::OnDefaultDeviceChanged, this);
53
54   if (result != noErr) {
55     OSSTATUS_DLOG(ERROR, result)
56         << "AudioObjectAddPropertyListener() failed!";
57     return;
58   }
59
60   listener_cb_ = listener_cb;
61 }
62
63 AudioDeviceListenerMac::~AudioDeviceListenerMac() {
64   DCHECK(thread_checker_.CalledOnValidThread());
65   if (listener_cb_.is_null())
66     return;
67
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!";
75 }
76
77 }  // namespace media