audio_device_listener_mac.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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#ifndef MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_ 6#define MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_ 7 8#include <CoreAudio/AudioHardware.h> 9 10#include "base/basictypes.h" 11#include "base/callback.h" 12#include "base/scoped_native_library.h" 13#include "base/threading/thread_checker.h" 14#include "media/base/media_export.h" 15 16namespace media { 17 18class ExclusiveDispatchQueueTaskObserver; 19 20// AudioDeviceListenerMac facilitates thread safe execution of device listener 21// callbacks issued via CoreAudio. On 10.6 this means correctly binding the 22// CFRunLoop driving callbacks to the CFRunLoop AudioDeviceListenerMac is 23// constructed on. On 10.7 this means creating a dispatch queue to drive 24// callbacks and modifying the message loop AudioDeviceListenerMac to ensure 25// message loop tasks and dispatch queue tasks are executed in a mutually 26// exclusive manner. See http://crbug.com/158170 for more discussion. 27class MEDIA_EXPORT AudioDeviceListenerMac { 28 public: 29 // |listener_cb| will be called when a device change occurs; it's a permanent 30 // callback and must outlive AudioDeviceListenerMac. 31 explicit AudioDeviceListenerMac(const base::Closure& listener_cb); 32 ~AudioDeviceListenerMac(); 33 34 private: 35 friend class AudioDeviceListenerMacTest; 36 static const AudioObjectPropertyAddress kDeviceChangePropertyAddress; 37 38 static OSStatus OnDefaultDeviceChanged( 39 AudioObjectID object, UInt32 num_addresses, 40 const AudioObjectPropertyAddress addresses[], void* context); 41 42 // Attempts to dynamically load the property listener block functions. Sets 43 // |core_audio_lib_|, |add_listener_block_func_|, and 44 // |remove_listener_block_func_|. Returns false on failure. If successful, 45 // the unload function must be called to avoid memory leaks. 46 bool LoadAudioObjectPropertyListenerBlockFunctions(); 47 48 base::Closure listener_cb_; 49 scoped_ptr<ExclusiveDispatchQueueTaskObserver> task_observer_; 50 base::ScopedNativeLibrary core_audio_lib_; 51 52 // TODO(dalecurtis): Use the standard AudioObjectPropertyListenerBlock when 53 // the deployment target is > 10.6. 54 typedef void (^CrAudioObjectPropertyListenerBlock)( 55 UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[]); 56 CrAudioObjectPropertyListenerBlock listener_block_; 57 58 // Variables for storing dynamically loaded block functions. 59 typedef OSStatus(*AudioObjectPropertyListenerBlockT)( 60 AudioObjectID inObjectID, 61 const AudioObjectPropertyAddress* inAddress, 62 dispatch_queue_t inDispatchQueue, 63 CrAudioObjectPropertyListenerBlock inListener); 64 AudioObjectPropertyListenerBlockT add_listener_block_func_; 65 AudioObjectPropertyListenerBlockT remove_listener_block_func_; 66 67 // AudioDeviceListenerMac must be constructed and destructed on the same 68 // thread. 69 base::ThreadChecker thread_checker_; 70 71 // If the sample rate hasn't changed, don't fire a device change. OSX will 72 // handle the routing under the hood. 73 int current_sample_rate_; 74 75 DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerMac); 76}; 77 78} // namespace media 79 80#endif // MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_ 81