1 /*
2 * Copyright (c) 2025 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 "hpae_soft_link.h"
18 #include "hpae_manager_impl.h"
19 #include "hpae_audio_service_callback_unit_test.h"
20 namespace OHOS {
21 namespace AudioStandard {
22 namespace HPAE {
23 static std::string g_rootPath = "/data/";
24 class HpaeSoftLinkTest : public testing::Test {
25 public:
26 static void SetUpTestCase();
27 static void TearDownTestCase();
28 void SetUp();
29 void TearDown();
30 void OpenAudioPort(bool openSink = true);
31 void CloseAudioPort(bool closeSink = true);
32
33 static std::shared_ptr<HpaeAudioServiceCallbackUnitTest> callback_;
34 int32_t sinkId_ = -1;
35 int32_t sourceId_ = -1;
36 };
37
GetSinkAudioModeInfo(std::string name="Speaker_File")38 static AudioModuleInfo GetSinkAudioModeInfo(std::string name = "Speaker_File")
39 {
40 AudioModuleInfo audioModuleInfo;
41 audioModuleInfo.lib = "libmodule-hdi-sink.z.so";
42 audioModuleInfo.channels = "2";
43 audioModuleInfo.rate = "48000";
44 audioModuleInfo.name = name;
45 audioModuleInfo.adapterName = "file_io";
46 audioModuleInfo.className = "file_io";
47 audioModuleInfo.bufferSize = "7680";
48 audioModuleInfo.format = "s32le";
49 audioModuleInfo.fixedLatency = "1";
50 audioModuleInfo.offloadEnable = "0";
51 audioModuleInfo.networkId = "LocalDevice";
52 audioModuleInfo.fileName = g_rootPath + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" +
53 audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm";
54 std::stringstream typeValue;
55 typeValue << static_cast<int32_t>(DEVICE_TYPE_SPEAKER);
56 audioModuleInfo.deviceType = typeValue.str();
57 return audioModuleInfo;
58 }
59
GetSourceAudioModeInfo(std::string name="mic")60 static AudioModuleInfo GetSourceAudioModeInfo(std::string name = "mic")
61 {
62 AudioModuleInfo audioModuleInfo;
63 audioModuleInfo.lib = "libmodule-hdi-source.z.so";
64 audioModuleInfo.channels = "2";
65 audioModuleInfo.rate = "48000";
66 audioModuleInfo.name = name;
67 audioModuleInfo.adapterName = "file_io";
68 audioModuleInfo.className = "file_io";
69 audioModuleInfo.bufferSize = "3840";
70 audioModuleInfo.format = "s16le";
71 audioModuleInfo.fixedLatency = "1";
72 audioModuleInfo.offloadEnable = "0";
73 audioModuleInfo.networkId = "LocalDevice";
74 audioModuleInfo.fileName = g_rootPath + "source_" + audioModuleInfo.adapterName + "_" + audioModuleInfo.rate + "_" +
75 audioModuleInfo.channels + "_" + audioModuleInfo.format + ".pcm";
76 std::stringstream typeValue;
77 typeValue << static_cast<int32_t>(DEVICE_TYPE_FILE_SOURCE);
78 audioModuleInfo.deviceType = typeValue.str();
79 return audioModuleInfo;
80 }
81
82 std::shared_ptr<HpaeAudioServiceCallbackUnitTest> HpaeSoftLinkTest::callback_ =
83 std::make_shared<HpaeAudioServiceCallbackUnitTest>();
SetUpTestCase()84 void HpaeSoftLinkTest::SetUpTestCase()
85 {
86 IHpaeManager::GetHpaeManager().Init();
87 IHpaeManager::GetHpaeManager().RegisterSerivceCallback(callback_);
88 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 200ms for sleep
89 }
90
TearDownTestCase()91 void HpaeSoftLinkTest::TearDownTestCase()
92 {
93 IHpaeManager::GetHpaeManager().DeInit();
94 }
95
SetUp()96 void HpaeSoftLinkTest::SetUp()
97 {
98 OpenAudioPort(true);
99 OpenAudioPort(false);
100 }
101
TearDown()102 void HpaeSoftLinkTest::TearDown()
103 {
104 CloseAudioPort(true);
105 CloseAudioPort(false);
106 }
107
OpenAudioPort(bool openSink)108 void HpaeSoftLinkTest::OpenAudioPort(bool openSink)
109 {
110 AudioModuleInfo moduleInfo = openSink ? GetSinkAudioModeInfo() : GetSourceAudioModeInfo();
111 EXPECT_EQ(IHpaeManager::GetHpaeManager().OpenAudioPort(moduleInfo), SUCCESS);
112 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 200ms for sleep
113 if (openSink) {
114 sinkId_ = callback_->GetPortId();
115 } else {
116 sourceId_ = callback_->GetPortId();
117 }
118 }
119
CloseAudioPort(bool closeSink)120 void HpaeSoftLinkTest::CloseAudioPort(bool closeSink)
121 {
122 IHpaeManager::GetHpaeManager().CloseAudioPort(closeSink ? sinkId_ : sourceId_);
123 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 200ms for sleep
124 if (closeSink) {
125 sinkId_ = -1;
126 } else {
127 sourceId_ = -1;
128 }
129 }
130
TEST_F(HpaeSoftLinkTest,testSoftLink)131 TEST_F(HpaeSoftLinkTest, testSoftLink)
132 {
133 std::shared_ptr<HpaeSoftLink> softLink_ =
134 std::make_shared<HpaeSoftLink>(sinkId_, sourceId_, SoftLinkMode::HEARING_AID);
135 EXPECT_NE(softLink_, nullptr);
136 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::NEW);
137
138 EXPECT_EQ(softLink_->Init(), SUCCESS);
139 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::PREPARED);
140
141 EXPECT_EQ(softLink_->Init(), SUCCESS); // init after init
142 EXPECT_EQ(softLink_->Stop(), ERR_ILLEGAL_STATE); // stop after init
143
144 EXPECT_EQ(softLink_->Start(), SUCCESS);
145 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RUNNING);
146
147 EXPECT_EQ(softLink_->Init(), ERR_ILLEGAL_STATE); // init after start
148 EXPECT_EQ(softLink_->Start(), SUCCESS); // start after start
149
150 std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 2000ms for sleep
151
152 EXPECT_EQ(softLink_->Stop(), SUCCESS);
153 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::STOPPED);
154
155 EXPECT_EQ(softLink_->Stop(), SUCCESS); // stop after stop
156
157 EXPECT_EQ(softLink_->Release(), SUCCESS);
158 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RELEASED);
159 }
160
TEST_F(HpaeSoftLinkTest,testCapturerOverFlow)161 TEST_F(HpaeSoftLinkTest, testCapturerOverFlow)
162 {
163 std::shared_ptr<HpaeSoftLink> softLink_ =
164 std::make_shared<HpaeSoftLink>(sinkId_, sourceId_, SoftLinkMode::HEARING_AID);
165 EXPECT_NE(softLink_, nullptr);
166 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::NEW);
167 EXPECT_EQ(softLink_->Init(), SUCCESS);
168 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::PREPARED);
169 EXPECT_EQ(softLink_->Start(), SUCCESS);
170 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RUNNING);
171
172 auto &capturerSessionId = softLink_->capturerStreamInfo_.sessionId;
173 if (softLink_->state_ == HpaeSoftLinkState::RUNNING &&
174 softLink_->streamStateMap_.find(capturerSessionId) != softLink_->streamStateMap_.end()) {
175 EXPECT_EQ(softLink_->GetStreamStateById(capturerSessionId), HpaeSoftLinkState::RUNNING);
176 }
177
178 CloseAudioPort();
179 std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 2000ms for sleep
180 if (softLink_->state_ == HpaeSoftLinkState::RUNNING &&
181 softLink_->streamStateMap_.find(capturerSessionId) != softLink_->streamStateMap_.end()) {
182 AUDIO_INFO_LOG("capturer has stopped");
183 EXPECT_EQ(softLink_->GetStreamStateById(capturerSessionId), HpaeSoftLinkState::STOPPED);
184 }
185 EXPECT_EQ(softLink_->Release(), SUCCESS);
186 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RELEASED);
187 }
188
TEST_F(HpaeSoftLinkTest,testRendererUnderRun)189 TEST_F(HpaeSoftLinkTest, testRendererUnderRun)
190 {
191 std::shared_ptr<HpaeSoftLink> softLink_ =
192 std::make_shared<HpaeSoftLink>(sinkId_, sourceId_, SoftLinkMode::HEARING_AID);
193 EXPECT_NE(softLink_, nullptr);
194 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::NEW);
195 EXPECT_EQ(softLink_->Init(), SUCCESS);
196 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::PREPARED);
197 EXPECT_EQ(softLink_->Start(), SUCCESS);
198 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RUNNING);
199
200 auto &rendererSessionId = softLink_->rendererStreamInfo_.sessionId;
201 if (softLink_->state_ == HpaeSoftLinkState::RUNNING &&
202 softLink_->streamStateMap_.find(rendererSessionId) != softLink_->streamStateMap_.end()) {
203 EXPECT_EQ(softLink_->GetStreamStateById(rendererSessionId), HpaeSoftLinkState::RUNNING);
204 }
205
206 CloseAudioPort(false);
207 std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 2000ms for sleep
208 if (softLink_->state_ == HpaeSoftLinkState::RUNNING &&
209 softLink_->streamStateMap_.find(rendererSessionId) != softLink_->streamStateMap_.end()) {
210 AUDIO_INFO_LOG("renderer has stopped");
211 EXPECT_EQ(softLink_->GetStreamStateById(rendererSessionId), HpaeSoftLinkState::STOPPED);
212 }
213 EXPECT_EQ(softLink_->Release(), SUCCESS);
214 EXPECT_EQ(softLink_->state_, HpaeSoftLinkState::RELEASED);
215 }
216
TEST_F(HpaeSoftLinkTest,testStaticFunc)217 TEST_F(HpaeSoftLinkTest, testStaticFunc)
218 {
219 std::shared_ptr<IHpaeSoftLink> softLink1 =
220 IHpaeSoftLink::CreateSoftLink(sinkId_, sourceId_, SoftLinkMode::HEARING_AID);
221 EXPECT_NE(softLink1, nullptr);
222 softLink1->SetVolume(0.f);
223
224 CloseAudioPort(false);
225 std::shared_ptr<IHpaeSoftLink> softLink2 =
226 IHpaeSoftLink::CreateSoftLink(sinkId_, sourceId_, SoftLinkMode::HEARING_AID);
227 EXPECT_EQ(softLink2, nullptr);
228
229 std::shared_ptr<IHpaeSoftLink> softLink3 =
230 IHpaeSoftLink::CreateSoftLink(sinkId_, -1, SoftLinkMode::HEARING_AID);
231 EXPECT_EQ(softLink3, nullptr);
232
233 HpaeSoftLink::g_sessionId = 99999; // 99999 for max sessionId
234 EXPECT_EQ(HpaeSoftLink::GenerateSessionId(), 99999); // 99999 for max sessionId
235 EXPECT_EQ(HpaeSoftLink::g_sessionId, 90000); // 90000 for min sessionId
236 }
237 } // namespace HPAE
238 } // namespace AudioStandard
239 } // namespace OHOS
240