1 /*
2  * Copyright (c) 2022 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 <gtest/gtest.h>
17 #include "hdi_service_common.h"
18 #include "osal_mem.h"
19 
20 using namespace std;
21 using namespace testing::ext;
22 using namespace OHOS::Audio;
23 
24 namespace {
25 const float COUNT = 1000;             // number of interface calls
26 const int32_t LOWLATENCY = 10000;     // low interface delay:10ms
27 const int32_t HIGHLATENCY = 60000;    // high interface delay:60ms
28 
29 class AudioIdlHdiAdapterPerformaceTest : public testing::Test {
30 public:
31     static void SetUpTestCase(void);
32     static void TearDownTestCase(void);
33     void SetUp();
34     void TearDown();
35     static struct IAudioAdapter *adapter;
36     static struct AudioPort audioPort;
37     static TestAudioManager *manager;
38     uint32_t captureId_ = 0;
39     uint32_t renderId_ = 0;
40 };
41 using THREAD_FUNC = void *(*)(void *);
42 TestAudioManager *AudioIdlHdiAdapterPerformaceTest::manager = nullptr;
43 struct IAudioAdapter *AudioIdlHdiAdapterPerformaceTest::adapter = nullptr;
44 struct AudioPort AudioIdlHdiAdapterPerformaceTest::audioPort = {};
45 
SetUpTestCase(void)46 void AudioIdlHdiAdapterPerformaceTest::SetUpTestCase(void)
47 {
48     manager = IAudioManagerGet(IS_STUB);
49     ASSERT_NE(nullptr, manager);
50     int32_t ret = GetLoadAdapter(manager, PORT_OUT, ADAPTER_NAME, &adapter, audioPort);
51     ASSERT_EQ(HDF_SUCCESS, ret);
52 }
53 
TearDownTestCase(void)54 void AudioIdlHdiAdapterPerformaceTest::TearDownTestCase(void)
55 {
56     if (manager != nullptr && manager->UnloadAdapter != nullptr && adapter != nullptr) {
57         int32_t ret = manager->UnloadAdapter(manager, ADAPTER_NAME.c_str());
58         EXPECT_EQ(HDF_SUCCESS, ret);
59         IAudioAdapterRelease(adapter, IS_STUB);
60         free(audioPort.portName);
61         (void)IAudioManagerRelease(manager, IS_STUB);
62     }
63 }
64 
SetUp(void)65 void AudioIdlHdiAdapterPerformaceTest::SetUp(void) {}
66 
TearDown(void)67 void AudioIdlHdiAdapterPerformaceTest::TearDown(void) {}
68 /**
69 * @tc.name  AudioManagerInitAllPortsPerformance_001
70 * @tc.desc  tests the performace of InitAllPorts interface by executing 1000 times,
71 *           and calculates the delay time and average of Delay Time.
72 * @tc.type: PERF
73 */
74 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioManagerInitAllPortsPerformance_001, TestSize.Level1)
75 {
76     int32_t ret;
77     struct PrepareAudioPara audiopara = {
78         .adapter = adapter, .delayTime = 0, .totalTime = 0, .averageDelayTime =0,
79     };
80     ASSERT_NE(nullptr, audiopara.adapter);
81 
82     for (int i = 0; i < COUNT; ++i) {
83         EXPECT_NE(nullptr, audiopara.adapter);
84         gettimeofday(&audiopara.start, NULL);
85         ret = audiopara.adapter->InitAllPorts(audiopara.adapter);
86         gettimeofday(&audiopara.end, NULL);
87         EXPECT_EQ(HDF_SUCCESS, ret);
88         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
89                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
90         audiopara.totalTime += audiopara.delayTime;
91     }
92     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
93     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
94 }
95 /**
96 * @tc.name  AudioGetPortCapabilityPerformance_001
97 * @tc.desc  tests the performace of GetPortCapability interface by executing 1000 times,
98 *           and calculates the delay time and average of Delay Time.
99 * @tc.type: PERF
100 */
101 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioGetPortCapabilityPerformance_001, TestSize.Level1)
102 {
103     int32_t ret;
104     struct PrepareAudioPara audiopara = {
105         .adapter = adapter, .delayTime = 0, .totalTime = 0, .averageDelayTime =0,
106     };
107     ASSERT_NE(nullptr, audiopara.adapter);
108     ret = audiopara.adapter->InitAllPorts(audiopara.adapter);
109     EXPECT_EQ(HDF_SUCCESS, ret);
110     for (int i = 0; i < COUNT; ++i) {
111         struct AudioPortCapability *capability = nullptr;
112         capability = (struct AudioPortCapability*)OsalMemCalloc(sizeof(struct AudioPortCapability));
113         ASSERT_NE(nullptr, capability);
114         gettimeofday(&audiopara.start, NULL);
115         ret = audiopara.adapter->GetPortCapability(audiopara.adapter, &audioPort, capability);
116         gettimeofday(&audiopara.end, NULL);
117         EXPECT_EQ(HDF_SUCCESS, ret);
118         EXPECT_NE(nullptr, capability->formats);
119         EXPECT_NE(nullptr, capability->subPorts);
120         if (capability->subPorts != nullptr) {
121             EXPECT_NE(nullptr, capability->subPorts->desc);
122         }
123         TestAudioPortCapabilityFree(capability, true);
124         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
125                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
126         audiopara.totalTime += audiopara.delayTime;
127     }
128     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
129     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
130 }
131 /**
132 * @tc.name  AudioSetPassthroughModePerformance_001
133 * @tc.desc  tests the performace of SetPassthroughMode interface by executing 1000 times,
134 *           and calculates the delay time and average of Delay Time.
135 * @tc.type: PERF
136 */
137 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioSetPassthroughModePerformance_001, TestSize.Level1)
138 {
139     int32_t ret;
140     struct PrepareAudioPara audiopara = {
141         .adapter = adapter, .mode = PORT_PASSTHROUGH_LPCM, .delayTime = 0, .totalTime = 0, .averageDelayTime =0,
142     };
143     ASSERT_NE(nullptr, audiopara.adapter);
144     ret = audiopara.adapter->InitAllPorts(audiopara.adapter);
145     EXPECT_EQ(HDF_SUCCESS, ret);
146     for (int i = 0; i < COUNT; ++i) {
147         AudioPortPassthroughMode mode = PORT_PASSTHROUGH_AUTO;
148         gettimeofday(&audiopara.start, NULL);
149         ret = audiopara.adapter->SetPassthroughMode(audiopara.adapter, &audioPort, audiopara.mode);
150         gettimeofday(&audiopara.end, NULL);
151         EXPECT_EQ(HDF_SUCCESS, ret);
152         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
153                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
154         audiopara.totalTime += audiopara.delayTime;
155         ret = audiopara.adapter->GetPassthroughMode(audiopara.adapter, &audioPort, &mode);
156         EXPECT_EQ(HDF_SUCCESS, ret);
157         EXPECT_EQ(PORT_PASSTHROUGH_LPCM, mode);
158     }
159     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
160     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
161 }
162 /**
163 * @tc.name  AudioGetPassthroughModePerformance_001
164 * @tc.desc  tests the performace of GetPassthroughMode interface by executing 1000 times,
165 * and calculates the delay time and average of Delay Time.
166 * @tc.type: PERF
167 */
168 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioGetPassthroughModePerformance_001, TestSize.Level1)
169 {
170     int32_t ret;
171     struct PrepareAudioPara audiopara = {
172         .adapter = adapter, .mode = PORT_PASSTHROUGH_LPCM, .delayTime = 0, .totalTime = 0, .averageDelayTime =0,
173     };
174     ASSERT_NE(nullptr, audiopara.adapter);
175     ret = audiopara.adapter->InitAllPorts(audiopara.adapter);
176     EXPECT_EQ(HDF_SUCCESS, ret);
177     ret = audiopara.adapter->SetPassthroughMode(audiopara.adapter, &audioPort, audiopara.mode);
178     EXPECT_EQ(HDF_SUCCESS, ret);
179 
180     for (int i = 0; i < COUNT; ++i) {
181         AudioPortPassthroughMode mode = PORT_PASSTHROUGH_AUTO;
182         gettimeofday(&audiopara.start, NULL);
183         ret = audiopara.adapter->GetPassthroughMode(audiopara.adapter, &audioPort, &mode);
184         gettimeofday(&audiopara.end, NULL);
185         EXPECT_EQ(HDF_SUCCESS, ret);
186         EXPECT_EQ(PORT_PASSTHROUGH_LPCM, mode);
187         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
188                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
189         audiopara.totalTime += audiopara.delayTime;
190     }
191     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
192     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
193 }
194 /**
195 * @tc.name  AudioCreateRenderPerformance_001
196 * @tc.desc  tests the performace of CreateRender interface by executing 1000 times,
197 *           and calculates the delay time and average of Delay Time.
198 * @tc.type: PERF
199 */
200 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioCreateRenderPerformance_001, TestSize.Level1)
201 {
202     int32_t ret;
203     struct PrepareAudioPara audiopara = {
204         .adapter = adapter, .delayTime = 0, .totalTime = 0, .averageDelayTime =0, .pins = PIN_OUT_SPEAKER
205     };
206     ASSERT_NE(nullptr, audiopara.adapter);
207     InitAttrs(audiopara.attrs);
208     InitDevDesc(audiopara.devDesc, audioPort.portId, audiopara.pins);
209 
210     for (int i = 0; i < COUNT; ++i) {
211         gettimeofday(&audiopara.start, NULL);
212         ret = audiopara.adapter->CreateRender(audiopara.adapter, &audiopara.devDesc, &audiopara.attrs,
213                                               &audiopara.render, &renderId_);
214         gettimeofday(&audiopara.end, NULL);
215         EXPECT_EQ(HDF_SUCCESS, ret);
216         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
217                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
218         audiopara.totalTime += audiopara.delayTime;
219         ret = audiopara.adapter->DestroyRender(audiopara.adapter, renderId_);
220         IAudioRenderRelease(audiopara.render, IS_STUB);
221         audiopara.render = nullptr;
222         EXPECT_EQ(HDF_SUCCESS, ret);
223     }
224     free(audiopara.devDesc.desc);
225     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
226     EXPECT_GT(HIGHLATENCY, audiopara.averageDelayTime);
227 }
228 /**
229 * @tc.name  AudioDestroyRenderPerformance_001
230 * @tc.desc  tests the performace of DestroyRender interface by executing 1000 times,
231 *           and calculates the delay time and average of Delay Time.
232 * @tc.type: PERF
233 */
234 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioDestroyRenderPerformance_001, TestSize.Level1)
235 {
236     int32_t ret;
237     struct PrepareAudioPara audiopara = {
238         .adapter = adapter, .delayTime = 0, .totalTime = 0, .averageDelayTime =0, .pins = PIN_OUT_SPEAKER
239     };
240     ASSERT_NE(nullptr, audiopara.adapter);
241     InitAttrs(audiopara.attrs);
242     InitDevDesc(audiopara.devDesc, audioPort.portId, audiopara.pins);
243 
244     for (int i = 0; i < COUNT; ++i) {
245         ret = audiopara.adapter->CreateRender(audiopara.adapter, &audiopara.devDesc, &audiopara.attrs,
246                                               &audiopara.render, &renderId_);
247         EXPECT_EQ(HDF_SUCCESS, ret);
248         gettimeofday(&audiopara.start, NULL);
249         audiopara.adapter->DestroyRender(audiopara.adapter, renderId_);
250         gettimeofday(&audiopara.end, NULL);
251         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
252                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
253         audiopara.totalTime += audiopara.delayTime;
254     }
255     free(audiopara.devDesc.desc);
256     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
257     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
258 }
259 /**
260 * @tc.name  AudioCreateCapturePerformance_001
261 * @tc.desc  tests the performace of AudioCreateCapture interface by executing 1000 times,
262 *              and calculates the delay time and average of Delay Time.
263 * @tc.type: PERF
264 */
265 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioCreateCapturePerformance_001, TestSize.Level1)
266 {
267     int32_t ret;
268     struct PrepareAudioPara audiopara = {
269         .adapter = adapter, .delayTime = 0, .averageDelayTime =0, .totalTime = 0, .pins = PIN_IN_MIC
270     };
271     ASSERT_NE(nullptr, audiopara.adapter);
272     InitAttrs(audiopara.attrs);
273     InitDevDesc(audiopara.devDesc, audioPort.portId, audiopara.pins);
274     for (int i = 0; i < COUNT; ++i) {
275         gettimeofday(&audiopara.start, NULL);
276         ret = audiopara.adapter->CreateCapture(audiopara.adapter, &audiopara.devDesc, &audiopara.attrs,
277                                                &audiopara.capture, &captureId_);
278         gettimeofday(&audiopara.end, NULL);
279         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
280                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
281         audiopara.totalTime += audiopara.delayTime;
282         ret = audiopara.adapter->DestroyCapture(audiopara.adapter, captureId_);
283         IAudioCaptureRelease(audiopara.capture, IS_STUB);
284         audiopara.capture = nullptr;
285         EXPECT_EQ(HDF_SUCCESS, ret);
286     }
287     free(audiopara.devDesc.desc);
288     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
289     EXPECT_GT(HIGHLATENCY, audiopara.averageDelayTime);
290 }
291 /**
292 * @tc.name  AudioDestroyCapturePerformance_001
293 * @tc.desc  tests the performace of AudioDestroyCapture interface by executing 1000 times,
294 *              and calculates the delay time and average of Delay Time.
295 * @tc.type: PERF
296 */
297 HWTEST_F(AudioIdlHdiAdapterPerformaceTest, AudioDestroyCapturePerformance_001, TestSize.Level1)
298 {
299     int32_t ret;
300     struct PrepareAudioPara audiopara = {
301         .adapter = adapter, .delayTime = 0, .totalTime = 0, .averageDelayTime =0, .pins = PIN_IN_MIC
302     };
303     ASSERT_NE(nullptr, audiopara.adapter);
304     InitAttrs(audiopara.attrs);
305     InitDevDesc(audiopara.devDesc, audioPort.portId, audiopara.pins);
306     for (int i = 0; i < COUNT; ++i) {
307         ret = audiopara.adapter->CreateCapture(audiopara.adapter, &audiopara.devDesc, &audiopara.attrs,
308                                                &audiopara.capture, &captureId_);
309         ASSERT_EQ(HDF_SUCCESS, ret);
310         gettimeofday(&audiopara.start, NULL);
311         ret = audiopara.adapter->DestroyCapture(audiopara.adapter, captureId_);
312         IAudioCaptureRelease(audiopara.capture, IS_STUB);
313         gettimeofday(&audiopara.end, NULL);
314         EXPECT_EQ(HDF_SUCCESS, ret);
315         audiopara.capture = nullptr;
316         audiopara.delayTime = (audiopara.end.tv_sec * MICROSECOND + audiopara.end.tv_usec) -
317                               (audiopara.start.tv_sec * MICROSECOND + audiopara.start.tv_usec);
318         audiopara.totalTime += audiopara.delayTime;
319     }
320     free(audiopara.devDesc.desc);
321     audiopara.averageDelayTime = (float)audiopara.totalTime / COUNT;
322     EXPECT_GT(LOWLATENCY, audiopara.averageDelayTime);
323 }
324 }
325