1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <mutex>
17#include <chrono>
18#include <thread>
19#include "ActsOhaudioNdkTest.h"
20
21using namespace std::chrono;
22using namespace testing::ext;
23
24namespace OHOS {
25namespace AudioStandard {
26
27static int32_t AudioRendererOnWriteData(OH_AudioRenderer* renderer,
28    void* userData,
29    void* buffer,
30    int32_t bufferLen)
31{
32    OHAudioRendererWriteCallbackMock *mockPtr = static_cast<OHAudioRendererWriteCallbackMock*>(userData);
33    mockPtr->OnWriteData(renderer, userData, buffer, bufferLen);
34
35    return 0;
36}
37
38void ActsOhAudioNdkTest::SetUpTestCase(void) { }
39
40void ActsOhAudioNdkTest::TearDownTestCase(void) { }
41
42void ActsOhAudioNdkTest::SetUp(void) { }
43
44void ActsOhAudioNdkTest::TearDown(void) { }
45
46OH_AudioStreamBuilder* ActsOhAudioNdkTest::CreateRenderBuilder()
47{
48    OH_AudioStreamBuilder* builder;
49    OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
50    OH_AudioStreamBuilder_Create(&builder, type);
51    return builder;
52}
53
54/**
55* @tc.name  : Test OH_AudioRenderer_GetUnderflowCount API.
56* @tc.number: SUM_MULTIMEDIA_AUDIO_OH_AudioRenderer_GetUnderflowCount_0100
57* @tc.desc  : Test OH_AudioRenderer_GetUnderflowCount interface.
58*/
59HWTEST(ActsOhAudioNdkTest, SUM_MULTIMEDIA_AUDIO_OH_AudioRenderer_GetUnderflowCount_0100, TestSize.Level0)
60{
61    OH_AudioStreamBuilder* builder = ActsOhAudioNdkTest::CreateRenderBuilder();
62
63    OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLE_RATE_48000);
64    OH_AudioStreamBuilder_SetChannelCount(builder, CHANNEL_2);
65    OH_AudioStream_Usage usage = AUDIOSTREAM_USAGE_VOICE_COMMUNICATION;
66    OH_AudioStreamBuilder_SetRendererInfo(builder, usage);
67
68    OHAudioRendererWriteCallbackMock writeCallbackMock;
69
70    OH_AudioRenderer_Callbacks callbacks;
71    callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
72    OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, &writeCallbackMock);
73
74    OH_AudioRenderer* audioRenderer;
75    OH_AudioStream_Result result = OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
76    EXPECT_EQ(result, AUDIOSTREAM_SUCCESS);
77
78    std::mutex mutex;
79    std::condition_variable cv;
80    int32_t count = 0;
81    writeCallbackMock.Install([&count, &mutex, &cv](OH_AudioRenderer* renderer, void* userData,
82        void* buffer,
83        int32_t bufferLen) {
84            std::lock_guard lock(mutex);
85            cv.notify_one();
86            // only execute twice
87            if (count > 1) {
88                return;
89            }
90            // sleep time trigger underflow
91            if (count == 1) {
92                std::this_thread::sleep_for(200ms);
93            }
94            count++;
95        });
96
97    result = OH_AudioRenderer_Start(audioRenderer);
98    EXPECT_EQ(result, AUDIOSTREAM_SUCCESS);
99
100    std::unique_lock lock(mutex);
101    cv.wait_for(lock, 1s, [&count] {
102        // count > 1 ensure sleeped
103        return count > 1;
104    });
105    lock.unlock();
106
107    uint32_t underFlowCount;
108    result = OH_AudioRenderer_GetUnderflowCount(audioRenderer, &underFlowCount);
109    EXPECT_EQ(result, AUDIOSTREAM_SUCCESS);
110    EXPECT_GE(underFlowCount, 0);
111
112    OH_AudioRenderer_Stop(audioRenderer);
113    OH_AudioRenderer_Release(audioRenderer);
114
115    OH_AudioStreamBuilder_Destroy(builder);
116}
117} // namespace AudioStandard
118} // namespace OHOS