OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <memory> | 6 #include <memory> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "media/base/audio_renderer_mixer.h" | 12 #include "media/base/audio_renderer_mixer.h" |
13 #include "media/base/audio_renderer_mixer_input.h" | 13 #include "media/base/audio_renderer_mixer_input.h" |
14 #include "media/base/fake_audio_render_callback.h" | 14 #include "media/base/fake_audio_render_callback.h" |
15 #include "media/base/mock_audio_renderer_sink.h" | 15 #include "media/base/mock_audio_renderer_sink.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 namespace media { | 19 namespace media { |
20 | 20 |
21 static const int kBitsPerChannel = 16; | 21 static const int kBitsPerChannel = 16; |
22 static const int kSampleRate = 48000; | 22 static const int kSampleRate = 48000; |
23 static const int kBufferSize = 8192; | 23 static const int kBufferSize = 8192; |
24 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; | 24 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; |
25 static const char kDefaultDeviceId[] = ""; | 25 static const char kDefaultDeviceId[] = "default"; |
26 static const char kUnauthorizedDeviceId[] = "unauthorized"; | 26 static const char kUnauthorizedDeviceId[] = "unauthorized"; |
27 static const char kNonexistentDeviceId[] = "nonexistent"; | 27 static const char kNonexistentDeviceId[] = "nonexistent"; |
28 | 28 |
29 class AudioRendererMixerInputTest : public testing::Test { | 29 class AudioRendererMixerInputTest : public testing::Test { |
30 public: | 30 public: |
31 AudioRendererMixerInputTest() { | 31 AudioRendererMixerInputTest() { |
32 audio_parameters_ = AudioParameters( | 32 audio_parameters_ = AudioParameters( |
33 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 33 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
34 kBitsPerChannel, kBufferSize); | 34 kBitsPerChannel, kBufferSize); |
35 | 35 |
36 CreateMixerInput(kDefaultDeviceId); | 36 CreateMixerInput(kDefaultDeviceId); |
37 fake_callback_.reset(new FakeAudioRenderCallback(0)); | 37 fake_callback_.reset(new FakeAudioRenderCallback(0)); |
38 mixer_input_->Initialize(audio_parameters_, fake_callback_.get()); | 38 mixer_input_->Initialize(audio_parameters_, fake_callback_.get()); |
39 audio_bus_ = AudioBus::Create(audio_parameters_); | 39 audio_bus_ = AudioBus::Create(audio_parameters_); |
40 } | 40 } |
41 | 41 |
42 void CreateMixerInput(const std::string& device_id) { | 42 void CreateMixerInput(const std::string& device_id) { |
43 mixer_input_ = new AudioRendererMixerInput( | 43 mixer_input_ = new AudioRendererMixerInput( |
44 base::Bind(&AudioRendererMixerInputTest::GetMixer, | 44 base::Bind(&AudioRendererMixerInputTest::GetMixer, |
45 base::Unretained(this)), | 45 base::Unretained(this)), |
46 base::Bind(&AudioRendererMixerInputTest::RemoveMixer, | 46 base::Bind(&AudioRendererMixerInputTest::RemoveMixer, |
47 base::Unretained(this)), | 47 base::Unretained(this)), |
| 48 base::Bind(&AudioRendererMixerInputTest::GetOutputDeviceInfo, |
| 49 base::Unretained(this)), |
48 device_id, url::Origin()); | 50 device_id, url::Origin()); |
49 } | 51 } |
50 | 52 |
51 AudioRendererMixer* GetMixer(const AudioParameters& params, | 53 AudioRendererMixer* GetMixer(const AudioParameters& params, |
52 const std::string& device_id, | 54 const std::string& device_id, |
53 const url::Origin& security_origin, | 55 const url::Origin& security_origin, |
54 OutputDeviceStatus* device_status) { | 56 OutputDeviceStatus* device_status) { |
55 if (device_id == kNonexistentDeviceId) { | 57 if (device_id == kNonexistentDeviceId) { |
56 if (device_status) | 58 if (device_status) |
57 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; | 59 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; |
58 return nullptr; | 60 return nullptr; |
59 } | 61 } |
60 | 62 |
61 if (device_id == kUnauthorizedDeviceId) { | 63 if (device_id == kUnauthorizedDeviceId) { |
62 if (device_status) | 64 if (device_status) |
63 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED; | 65 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED; |
64 return nullptr; | 66 return nullptr; |
65 } | 67 } |
66 | 68 |
67 size_t idx = device_id.empty() ? 0 : 1; | 69 size_t idx = (device_id == kDefaultDeviceId) ? 0 : 1; |
68 if (!mixers_[idx]) { | 70 if (!mixers_[idx]) { |
69 scoped_refptr<MockAudioRendererSink> sink = new MockAudioRendererSink(); | 71 sinks_[idx] = |
70 EXPECT_CALL(*sink.get(), Start()); | 72 new MockAudioRendererSink(device_id, OUTPUT_DEVICE_STATUS_OK); |
71 EXPECT_CALL(*sink.get(), Stop()); | 73 EXPECT_CALL(*(sinks_[idx].get()), Start()); |
| 74 EXPECT_CALL(*(sinks_[idx].get()), Stop()); |
72 | 75 |
73 mixers_[idx].reset(new AudioRendererMixer(audio_parameters_, sink)); | 76 mixers_[idx].reset(new AudioRendererMixer( |
| 77 audio_parameters_, sinks_[idx].get(), |
| 78 base::Bind(&AudioRendererMixerInputTest::ReleaseSink, |
| 79 base::Unretained(this)))); |
74 } | 80 } |
75 EXPECT_CALL(*this, RemoveMixer(testing::_, device_id, testing::_)); | 81 EXPECT_CALL(*this, RemoveMixer(testing::_, device_id, testing::_)); |
| 82 EXPECT_CALL(*this, ReleaseSink(sinks_[idx].get())); |
76 | 83 |
77 if (device_status) | 84 if (device_status) |
78 *device_status = OUTPUT_DEVICE_STATUS_OK; | 85 *device_status = OUTPUT_DEVICE_STATUS_OK; |
79 return mixers_[idx].get(); | 86 return mixers_[idx].get(); |
80 } | 87 } |
81 | 88 |
82 double ProvideInput() { | 89 double ProvideInput() { |
83 return mixer_input_->ProvideInput(audio_bus_.get(), base::TimeDelta()); | 90 return mixer_input_->ProvideInput(audio_bus_.get(), base::TimeDelta()); |
84 } | 91 } |
85 | 92 |
86 MOCK_METHOD3(RemoveMixer, | 93 MOCK_METHOD3(RemoveMixer, |
87 void(const AudioParameters&, | 94 void(const AudioParameters&, |
88 const std::string&, | 95 const std::string&, |
89 const url::Origin&)); | 96 const url::Origin&)); |
90 | 97 |
| 98 MOCK_METHOD2(GetOutputDeviceInfo, |
| 99 OutputDeviceInfo(const std::string&, const url::Origin&)); |
| 100 |
| 101 MOCK_METHOD1(ReleaseSink, void(AudioRendererSink*)); |
| 102 |
91 MOCK_METHOD1(SwitchCallbackCalled, void(OutputDeviceStatus)); | 103 MOCK_METHOD1(SwitchCallbackCalled, void(OutputDeviceStatus)); |
| 104 |
92 void SwitchCallback(base::RunLoop* loop, OutputDeviceStatus result) { | 105 void SwitchCallback(base::RunLoop* loop, OutputDeviceStatus result) { |
93 SwitchCallbackCalled(result); | 106 SwitchCallbackCalled(result); |
94 loop->Quit(); | 107 loop->Quit(); |
95 } | 108 } |
96 | 109 |
97 AudioRendererMixer* GetInputMixer() { return mixer_input_->mixer_; } | 110 AudioRendererMixer* GetInputMixer() { return mixer_input_->mixer_; } |
98 | 111 |
99 protected: | 112 protected: |
100 virtual ~AudioRendererMixerInputTest() {} | 113 virtual ~AudioRendererMixerInputTest() {} |
101 | 114 |
102 AudioParameters audio_parameters_; | 115 AudioParameters audio_parameters_; |
| 116 scoped_refptr<MockAudioRendererSink> sinks_[2]; // Must outlive mixers. |
103 std::unique_ptr<AudioRendererMixer> mixers_[2]; | 117 std::unique_ptr<AudioRendererMixer> mixers_[2]; |
104 scoped_refptr<AudioRendererMixerInput> mixer_input_; | 118 scoped_refptr<AudioRendererMixerInput> mixer_input_; |
105 std::unique_ptr<FakeAudioRenderCallback> fake_callback_; | 119 std::unique_ptr<FakeAudioRenderCallback> fake_callback_; |
106 std::unique_ptr<AudioBus> audio_bus_; | 120 std::unique_ptr<AudioBus> audio_bus_; |
107 | 121 |
108 private: | 122 private: |
109 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerInputTest); | 123 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerInputTest); |
110 }; | 124 }; |
111 | 125 |
| 126 TEST_F(AudioRendererMixerInputTest, GetDeviceInfo) { |
| 127 ON_CALL(*this, GetOutputDeviceInfo(testing::_, testing::_)) |
| 128 .WillByDefault(testing::Return(OutputDeviceInfo())); |
| 129 EXPECT_CALL(*this, GetOutputDeviceInfo(kDefaultDeviceId, testing::_)) |
| 130 .Times(testing::Exactly(1)); |
| 131 |
| 132 // Calling GetOutputDeviceInfo() should result in the mock call, since there |
| 133 // is no mixer created yet for mixer input. |
| 134 mixer_input_->GetOutputDeviceInfo(); |
| 135 mixer_input_->Start(); |
| 136 |
| 137 // This call should be directed to the mixer and should not result in the mock |
| 138 // call. |
| 139 EXPECT_STREQ(kDefaultDeviceId, |
| 140 mixer_input_->GetOutputDeviceInfo().device_id().c_str()); |
| 141 |
| 142 mixer_input_->Stop(); |
| 143 } |
| 144 |
112 // Test that getting and setting the volume work as expected. The volume is | 145 // Test that getting and setting the volume work as expected. The volume is |
113 // returned from ProvideInput() only when playing. | 146 // returned from ProvideInput() only when playing. |
114 TEST_F(AudioRendererMixerInputTest, GetSetVolume) { | 147 TEST_F(AudioRendererMixerInputTest, GetSetVolume) { |
115 mixer_input_->Start(); | 148 mixer_input_->Start(); |
116 mixer_input_->Play(); | 149 mixer_input_->Play(); |
117 | 150 |
118 // Starting volume should be 1.0. | 151 // Starting volume should be 1.0. |
119 EXPECT_DOUBLE_EQ(ProvideInput(), 1); | 152 EXPECT_DOUBLE_EQ(ProvideInput(), 1); |
120 | 153 |
121 const double kVolume = 0.5; | 154 const double kVolume = 0.5; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 EXPECT_CALL(*this, SwitchCallbackCalled(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); | 304 EXPECT_CALL(*this, SwitchCallbackCalled(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); |
272 mixer_input_->SwitchOutputDevice( | 305 mixer_input_->SwitchOutputDevice( |
273 kDefaultDeviceId, url::Origin(), | 306 kDefaultDeviceId, url::Origin(), |
274 base::Bind(&AudioRendererMixerInputTest::SwitchCallback, | 307 base::Bind(&AudioRendererMixerInputTest::SwitchCallback, |
275 base::Unretained(this), &run_loop)); | 308 base::Unretained(this), &run_loop)); |
276 mixer_input_->Stop(); | 309 mixer_input_->Stop(); |
277 run_loop.Run(); | 310 run_loop.Run(); |
278 } | 311 } |
279 | 312 |
280 } // namespace media | 313 } // namespace media |
OLD | NEW |