1 // Copyright 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 "base/bind.h"
6 #include "base/macros.h"
7 #include "base/message_loop/message_pump_type.h"
8 #include "base/run_loop.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/test/test_message_loop.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "media/audio/audio_device_info_accessor_for_tests.h"
13 #include "media/audio/audio_io.h"
14 #include "media/audio/audio_manager.h"
15 #include "media/audio/audio_unittest_util.h"
16 #include "media/audio/mock_audio_source_callback.h"
17 #include "media/audio/test_audio_thread.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using testing::_;
22 using testing::DoAll;
23 using testing::Return;
24
25 // TODO(crogers): Most of these tests can be made platform agnostic.
26 // http://crbug.com/223242
27
28 namespace media {
29
ACTION(ZeroBuffer)30 ACTION(ZeroBuffer) {
31 arg3->Zero();
32 }
33
ACTION_P3(MaybeSignalEvent,counter,signal_at_count,event)34 ACTION_P3(MaybeSignalEvent, counter, signal_at_count, event) {
35 if (++(*counter) == signal_at_count)
36 event->Signal();
37 }
38
39 class AUHALStreamTest : public testing::Test {
40 public:
AUHALStreamTest()41 AUHALStreamTest()
42 : message_loop_(base::MessagePumpType::UI),
43 manager_(AudioManager::CreateForTesting(
44 std::make_unique<TestAudioThread>())),
45 manager_device_info_(manager_.get()) {
46 // Wait for the AudioManager to finish any initialization on the audio loop.
47 base::RunLoop().RunUntilIdle();
48 }
49
~AUHALStreamTest()50 ~AUHALStreamTest() override { manager_->Shutdown(); }
51
Create()52 AudioOutputStream* Create() {
53 return manager_->MakeAudioOutputStream(
54 manager_device_info_.GetDefaultOutputStreamParameters(), "",
55 base::BindRepeating(&AUHALStreamTest::OnLogMessage,
56 base::Unretained(this)));
57 }
58
OutputDevicesAvailable()59 bool OutputDevicesAvailable() {
60 return manager_device_info_.HasAudioOutputDevices();
61 }
62
OnLogMessage(const std::string & message)63 void OnLogMessage(const std::string& message) { log_message_ = message; }
64
65 protected:
66 base::TestMessageLoop message_loop_;
67 std::unique_ptr<AudioManager> manager_;
68 AudioDeviceInfoAccessorForTests manager_device_info_;
69 MockAudioSourceCallback source_;
70 std::string log_message_;
71
72 private:
73 DISALLOW_COPY_AND_ASSIGN(AUHALStreamTest);
74 };
75
TEST_F(AUHALStreamTest,HardwareSampleRate)76 TEST_F(AUHALStreamTest, HardwareSampleRate) {
77 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
78 const AudioParameters preferred_params =
79 manager_device_info_.GetDefaultOutputStreamParameters();
80 EXPECT_GE(preferred_params.sample_rate(), 16000);
81 EXPECT_LE(preferred_params.sample_rate(), 192000);
82 }
83
TEST_F(AUHALStreamTest,CreateClose)84 TEST_F(AUHALStreamTest, CreateClose) {
85 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
86 Create()->Close();
87 }
88
TEST_F(AUHALStreamTest,CreateOpenClose)89 TEST_F(AUHALStreamTest, CreateOpenClose) {
90 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
91 AudioOutputStream* stream = Create();
92 EXPECT_TRUE(stream->Open());
93 stream->Close();
94 }
95
TEST_F(AUHALStreamTest,CreateOpenStartStopClose)96 TEST_F(AUHALStreamTest, CreateOpenStartStopClose) {
97 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
98
99 AudioOutputStream* stream = Create();
100 EXPECT_TRUE(stream->Open());
101
102 // Wait for the first two data callback from the OS.
103 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
104 base::WaitableEvent::InitialState::NOT_SIGNALED);
105 int callback_counter = 0;
106 const int number_of_callbacks = 2;
107 EXPECT_CALL(source_, OnMoreData(_, _, _, _))
108 .Times(number_of_callbacks)
109 .WillRepeatedly(DoAll(
110 ZeroBuffer(),
111 MaybeSignalEvent(&callback_counter, number_of_callbacks, &event),
112 Return(0)));
113 EXPECT_CALL(source_, OnError(_)).Times(0);
114 stream->Start(&source_);
115 event.Wait();
116
117 stream->Stop();
118 stream->Close();
119
120 EXPECT_FALSE(log_message_.empty());
121 }
122
123 } // namespace media
124