- add sources.
[platform/framework/web/crosswalk.git] / src / media / audio / mac / audio_device_listener_mac_unittest.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 <CoreAudio/AudioHardware.h>
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/audio/mac/audio_device_listener_mac.h"
12 #include "media/base/bind_to_loop.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace media {
17
18 class AudioDeviceListenerMacTest : public testing::Test {
19  public:
20   AudioDeviceListenerMacTest() {
21     // It's important to create the device listener from the message loop in
22     // order to ensure we don't end up with unbalanced TaskObserver calls.
23     message_loop_.PostTask(FROM_HERE, base::Bind(
24         &AudioDeviceListenerMacTest::CreateDeviceListener,
25         base::Unretained(this)));
26     message_loop_.RunUntilIdle();
27   }
28
29   virtual ~AudioDeviceListenerMacTest() {
30     // It's important to destroy the device listener from the message loop in
31     // order to ensure we don't end up with unbalanced TaskObserver calls.
32     message_loop_.PostTask(FROM_HERE, base::Bind(
33         &AudioDeviceListenerMacTest::DestroyDeviceListener,
34         base::Unretained(this)));
35     message_loop_.RunUntilIdle();
36   }
37
38   void CreateDeviceListener() {
39     // Force a post task using BindToLoop to ensure device listener internals
40     // are working correctly.
41     output_device_listener_.reset(new AudioDeviceListenerMac(BindToLoop(
42         message_loop_.message_loop_proxy(), base::Bind(
43             &AudioDeviceListenerMacTest::OnDeviceChange,
44             base::Unretained(this)))));
45   }
46
47   void DestroyDeviceListener() {
48     output_device_listener_.reset();
49   }
50
51   bool ListenerIsValid() {
52     return !output_device_listener_->listener_cb_.is_null();
53   }
54
55   // Simulate a device change where no output devices are available.
56   bool SimulateDefaultOutputDeviceChange() {
57     // Include multiple addresses to ensure only a single device change event
58     // occurs.
59     const AudioObjectPropertyAddress addresses[] = {
60       AudioDeviceListenerMac::kDeviceChangePropertyAddress,
61       { kAudioHardwarePropertyDevices,
62         kAudioObjectPropertyScopeGlobal,
63         kAudioObjectPropertyElementMaster }
64     };
65
66     return noErr == output_device_listener_->OnDefaultDeviceChanged(
67         kAudioObjectSystemObject, 1, addresses, output_device_listener_.get());
68   }
69
70   MOCK_METHOD0(OnDeviceChange, void());
71
72  protected:
73   base::MessageLoop message_loop_;
74   scoped_ptr<AudioDeviceListenerMac> output_device_listener_;
75
76   DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerMacTest);
77 };
78
79 // Simulate a device change events and ensure we get the right callbacks.
80 TEST_F(AudioDeviceListenerMacTest, OutputDeviceChange) {
81   ASSERT_TRUE(ListenerIsValid());
82   EXPECT_CALL(*this, OnDeviceChange()).Times(1);
83   ASSERT_TRUE(SimulateDefaultOutputDeviceChange());
84   message_loop_.RunUntilIdle();
85 }
86
87 }  // namespace media