1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sstream>
18 
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioRecordTest"
21 
22 #include <android-base/logging.h>
23 #include <binder/ProcessState.h>
24 #include <gtest/gtest.h>
25 
26 #include "audio_test_utils.h"
27 #include "test_execution_tracer.h"
28 
29 using namespace android;
30 
31 // Test that the basic constructor returns an object that doesn't crash
32 // on stop() or destruction.
33 
TEST(AudioRecordTestBasic,EmptyAudioRecord)34 TEST(AudioRecordTestBasic, EmptyAudioRecord) {
35     AttributionSourceState attributionSource;
36     attributionSource.packageName = "AudioRecordTest";
37     attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
38     attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
39     attributionSource.token = sp<BBinder>::make();
40     const auto ar = sp<AudioRecord>::make(attributionSource);
41 
42     // test key commands on an unset AudioRecord.
43     EXPECT_EQ(NO_INIT, ar->initCheck());
44     EXPECT_EQ(true, ar->stopped());
45 
46     // just don't crash.
47     ar->stop();
48 }
49 
50 class AudioRecordTest : public ::testing::Test {
51   public:
SetUp()52     void SetUp() override {
53         mAC = new AudioCapture(AUDIO_SOURCE_DEFAULT, 44100, AUDIO_FORMAT_PCM_16_BIT,
54                                AUDIO_CHANNEL_IN_FRONT);
55         ASSERT_NE(nullptr, mAC);
56         ASSERT_EQ(OK, mAC->create()) << "record creation failed";
57     }
58 
TearDown()59     void TearDown() override {
60         if (mAC) ASSERT_EQ(OK, mAC->stop());
61     }
62 
63     sp<AudioCapture> mAC;
64 };
65 
66 using RecordCreateTestParam = std::tuple<uint32_t, audio_format_t, audio_channel_mask_t,
67                                          audio_input_flags_t, audio_session_t, audio_source_t>;
68 enum {
69     RECORD_PARAM_SAMPLE_RATE,
70     RECORD_PARAM_FORMAT,
71     RECORD_PARAM_CHANNEL_MASK,
72     RECORD_PARAM_FLAGS,
73     RECORD_PARAM_SESSION_ID,
74     RECORD_PARAM_INPUT_SOURCE
75 };
76 
77 class AudioRecordCreateTest : public ::testing::TestWithParam<RecordCreateTestParam> {
78   public:
AudioRecordCreateTest()79     AudioRecordCreateTest()
80         : mSampleRate(std::get<RECORD_PARAM_SAMPLE_RATE>(GetParam())),
81           mFormat(std::get<RECORD_PARAM_FORMAT>(GetParam())),
82           mChannelMask(std::get<RECORD_PARAM_CHANNEL_MASK>(GetParam())),
83           mFlags(std::get<RECORD_PARAM_FLAGS>(GetParam())),
84           mSessionId(std::get<RECORD_PARAM_SESSION_ID>(GetParam())),
85           mInputSource(std::get<RECORD_PARAM_INPUT_SOURCE>(GetParam())){};
86 
87     const uint32_t mSampleRate;
88     const audio_format_t mFormat;
89     const audio_channel_mask_t mChannelMask;
90     const audio_input_flags_t mFlags;
91     const audio_session_t mSessionId;
92     const audio_source_t mInputSource;
93     const AudioRecord::transfer_type mTransferType = AudioRecord::TRANSFER_OBTAIN;
94 
95     sp<AudioCapture> mAC;
96 
SetUp()97     void SetUp() override {
98         mAC = new AudioCapture(mInputSource, mSampleRate, mFormat, mChannelMask, mFlags, mSessionId,
99                                mTransferType);
100         ASSERT_NE(nullptr, mAC);
101         ASSERT_EQ(OK, mAC->create()) << "record creation failed";
102     }
103 
TearDown()104     void TearDown() override {
105         if (mAC) ASSERT_EQ(OK, mAC->stop());
106     }
107 };
108 
TEST_F(AudioRecordTest,TestSimpleRecord)109 TEST_F(AudioRecordTest, TestSimpleRecord) {
110     EXPECT_EQ(OK, mAC->start()) << "start recording failed";
111     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
112 }
113 
TEST_F(AudioRecordTest,TestAudioCbNotifier)114 TEST_F(AudioRecordTest, TestAudioCbNotifier) {
115     EXPECT_EQ(BAD_VALUE, mAC->getAudioRecordHandle()->addAudioDeviceCallback(nullptr));
116     sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
117     sp<OnAudioDeviceUpdateNotifier> cbOld = sp<OnAudioDeviceUpdateNotifier>::make();
118     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cbOld));
119     EXPECT_EQ(INVALID_OPERATION, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cbOld));
120     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cb));
121     EXPECT_EQ(OK, mAC->start()) << "record creation failed";
122     EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
123     EXPECT_EQ(AUDIO_IO_HANDLE_NONE, cbOld->mAudioIo);
124     EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, cbOld->mDeviceId);
125     EXPECT_NE(AUDIO_IO_HANDLE_NONE, cb->mAudioIo);
126     EXPECT_NE(AUDIO_PORT_HANDLE_NONE, cb->mDeviceId);
127     EXPECT_EQ(BAD_VALUE, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(nullptr));
128     EXPECT_EQ(INVALID_OPERATION, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cbOld));
129     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cb));
130     mAC->stop();
131 }
132 
TEST_F(AudioRecordTest,TestEventRecordTrackPause)133 TEST_F(AudioRecordTest, TestEventRecordTrackPause) {
134     const auto playback = sp<AudioPlayback>::make(
135             8000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO);
136     ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"))
137             << "Unable to open Resource";
138     EXPECT_EQ(OK, playback->create()) << "AudioTrack Creation failed";
139     audio_session_t audioTrackSession = playback->getAudioTrackHandle()->getSessionId();
140     EXPECT_EQ(OK, mAC->start(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE, audioTrackSession))
141             << "record creation failed";
142     EXPECT_EQ(OK, playback->start());
143     RawBuffer buffer;
144     status_t status = mAC->obtainBufferCb(buffer);
145     EXPECT_EQ(status, TIMED_OUT) << "Not expecting any callbacks until track sends Sync event";
146     playback->getAudioTrackHandle()->pause();
147     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
148     playback->stop();
149 }
150 
TEST_F(AudioRecordTest,TestEventRecordTrackStop)151 TEST_F(AudioRecordTest, TestEventRecordTrackStop) {
152     const auto playback = sp<AudioPlayback>::make(
153             8000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO);
154     ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"))
155             << "Unable to open Resource";
156     EXPECT_EQ(OK, playback->create()) << "AudioTrack Creation failed";
157     audio_session_t audioTrackSession = playback->getAudioTrackHandle()->getSessionId();
158     EXPECT_EQ(OK, mAC->start(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE, audioTrackSession))
159             << "record creation failed";
160     EXPECT_EQ(OK, playback->start());
161     RawBuffer buffer;
162     status_t status = mAC->obtainBufferCb(buffer);
163     EXPECT_EQ(status, TIMED_OUT) << "Not expecting any callbacks until track sends Sync event";
164     playback->stop();
165     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
166 }
167 
TEST_F(AudioRecordTest,TestGetSetMarker)168 TEST_F(AudioRecordTest, TestGetSetMarker) {
169     mAC->mMarkerPosition = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
170     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->setMarkerPosition(mAC->mMarkerPosition))
171             << "setMarkerPosition() failed";
172     uint32_t marker;
173     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getMarkerPosition(&marker))
174             << "getMarkerPosition() failed";
175     EXPECT_EQ(OK, mAC->start()) << "start recording failed";
176     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
177     EXPECT_EQ(marker, mAC->mMarkerPosition)
178             << "configured marker and received marker are different";
179     EXPECT_EQ(mAC->mReceivedCbMarkerAtPosition, mAC->mMarkerPosition)
180             << "configured marker and received cb marker are different";
181 }
182 
TEST_F(AudioRecordTest,TestGetSetMarkerPeriodical)183 TEST_F(AudioRecordTest, TestGetSetMarkerPeriodical) {
184     mAC->mMarkerPeriod = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
185     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->setPositionUpdatePeriod(mAC->mMarkerPeriod))
186             << "setPositionUpdatePeriod() failed";
187     uint32_t marker;
188     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPositionUpdatePeriod(&marker))
189             << "getPositionUpdatePeriod() failed";
190     EXPECT_EQ(OK, mAC->start()) << "start recording failed";
191     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
192     EXPECT_EQ(marker, mAC->mMarkerPeriod) << "configured marker and received marker are different";
193     EXPECT_EQ(mAC->mReceivedCbMarkerCount, mAC->mNumFramesToRecord / mAC->mMarkerPeriod)
194             << "configured marker and received cb marker are different";
195 }
196 
TEST_F(AudioRecordTest,TestGetPosition)197 TEST_F(AudioRecordTest, TestGetPosition) {
198     uint32_t position;
199     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPosition(&position)) << "getPosition() failed";
200     EXPECT_EQ(0, position);
201     EXPECT_EQ(OK, mAC->start()) << "start recording failed";
202     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
203     EXPECT_EQ(OK, mAC->stop());
204     EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPosition(&position)) << "getPosition() failed";
205 }
206 
207 // TODO: Add checkPatchCapture(), verify the information of patch via dumpPort() and dumpPatch()
TEST_P(AudioRecordCreateTest,TestCreateRecord)208 TEST_P(AudioRecordCreateTest, TestCreateRecord) {
209     EXPECT_EQ(mFormat, mAC->getAudioRecordHandle()->format());
210     EXPECT_EQ(audio_channel_count_from_in_mask(mChannelMask),
211               mAC->getAudioRecordHandle()->channelCount());
212     if (mAC->mFrameCount != 0)
213         EXPECT_LE(mAC->mFrameCount, mAC->getAudioRecordHandle()->frameCount());
214     EXPECT_EQ(mInputSource, mAC->getAudioRecordHandle()->inputSource());
215     if (mSampleRate != 0) EXPECT_EQ(mSampleRate, mAC->getAudioRecordHandle()->getSampleRate());
216     if (mSessionId != AUDIO_SESSION_NONE)
217         EXPECT_EQ(mSessionId, mAC->getAudioRecordHandle()->getSessionId());
218     if (mTransferType != AudioRecord::TRANSFER_CALLBACK) {
219         uint32_t marker;
220         mAC->mMarkerPosition = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
221         EXPECT_EQ(INVALID_OPERATION,
222                   mAC->getAudioRecordHandle()->setMarkerPosition(mAC->mMarkerPosition));
223         EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getMarkerPosition(&marker));
224         EXPECT_EQ(INVALID_OPERATION,
225                   mAC->getAudioRecordHandle()->setPositionUpdatePeriod(mAC->mMarkerPosition));
226         EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPositionUpdatePeriod(&marker));
227     }
228     EXPECT_EQ(OK, mAC->start()) << "start recording failed";
229     EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
230 }
231 
GetRecordTestName(const testing::TestParamInfo<RecordCreateTestParam> & info)232 static std::string GetRecordTestName(const testing::TestParamInfo<RecordCreateTestParam>& info) {
233     const auto& p = info.param;
234     std::ostringstream s;
235     s << std::get<RECORD_PARAM_SAMPLE_RATE>(p) << "_"
236       << audio_format_to_string(std::get<RECORD_PARAM_FORMAT>(p)) << "__"
237       << audio_channel_mask_to_string(std::get<RECORD_PARAM_CHANNEL_MASK>(p)) << "__"
238       << "Flags_0x" << std::hex << std::get<RECORD_PARAM_FLAGS>(p) << std::dec << "__"
239       << "Session_" << std::get<RECORD_PARAM_SESSION_ID>(p) << "__"
240       << audio_source_to_string(std::get<RECORD_PARAM_INPUT_SOURCE>(p));
241     return s.str();
242 }
243 
244 // for port primary input
245 INSTANTIATE_TEST_SUITE_P(AudioRecordPrimaryInput, AudioRecordCreateTest,
246                          ::testing::Combine(::testing::Values(8000, 11025, 12000, 16000, 22050,
247                                                               24000, 32000, 44100, 48000),
248                                             ::testing::Values(AUDIO_FORMAT_PCM_8_24_BIT),
249                                             ::testing::Values(AUDIO_CHANNEL_IN_MONO,
250                                                               AUDIO_CHANNEL_IN_STEREO,
251                                                               AUDIO_CHANNEL_IN_FRONT_BACK),
252                                             ::testing::Values(AUDIO_INPUT_FLAG_NONE),
253                                             ::testing::Values(AUDIO_SESSION_NONE),
254                                             ::testing::Values(AUDIO_SOURCE_DEFAULT)),
255                          GetRecordTestName);
256 
257 // for port fast input
258 INSTANTIATE_TEST_SUITE_P(AudioRecordFastInput, AudioRecordCreateTest,
259                          ::testing::Combine(::testing::Values(8000, 11025, 12000, 16000, 22050,
260                                                               24000, 32000, 44100, 48000),
261                                             ::testing::Values(AUDIO_FORMAT_PCM_8_24_BIT),
262                                             ::testing::Values(AUDIO_CHANNEL_IN_MONO,
263                                                               AUDIO_CHANNEL_IN_STEREO,
264                                                               AUDIO_CHANNEL_IN_FRONT_BACK),
265                                             ::testing::Values(AUDIO_INPUT_FLAG_FAST),
266                                             ::testing::Values(AUDIO_SESSION_NONE),
267                                             ::testing::Values(AUDIO_SOURCE_DEFAULT)),
268                          GetRecordTestName);
269 
270 // misc
271 INSTANTIATE_TEST_SUITE_P(AudioRecordMiscInput, AudioRecordCreateTest,
272                          ::testing::Combine(::testing::Values(48000),
273                                             ::testing::Values(AUDIO_FORMAT_PCM_16_BIT),
274                                             ::testing::Values(AUDIO_CHANNEL_IN_MONO),
275                                             ::testing::Values(AUDIO_INPUT_FLAG_NONE),
276                                             ::testing::Values(AUDIO_SESSION_NONE),
277                                             ::testing::Values(AUDIO_SOURCE_MIC,
278                                                               AUDIO_SOURCE_CAMCORDER,
279                                                               AUDIO_SOURCE_VOICE_RECOGNITION,
280                                                               AUDIO_SOURCE_VOICE_COMMUNICATION,
281                                                               AUDIO_SOURCE_UNPROCESSED)),
282                          GetRecordTestName);
283 
main(int argc,char ** argv)284 int main(int argc, char** argv) {
285     ::testing::InitGoogleTest(&argc, argv);
286     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
287     android::base::SetMinimumLogSeverity(::android::base::DEBUG);
288     // This is for death handlers instantiated by the framework code.
289     android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
290     android::ProcessState::self()->startThreadPool();
291     return RUN_ALL_TESTS();
292 }
293