| 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 |