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 <iostream>
17 #include <cstddef>
18 #include <cstdint>
19 #include <vector>
20 #include <memory>
21 #include <queue>
22 #include <string>
23 #undef private
24 #include "hpae_process_cluster.h"
25 #include "hpae_sink_input_node.h"
26 #include "hpae_output_cluster.h"
27 #include "audio_engine_log.h"
28
29 using namespace std;
30 using namespace OHOS::AudioStandard::HPAE;
31
32
33 namespace OHOS {
34 namespace AudioStandard {
35 using namespace std;
36 static const uint8_t *RAW_DATA = nullptr;
37 static size_t g_dataSize = 0;
38 static size_t g_pos;
39 const size_t THRESHOLD = 10;
40 const uint32_t DEFAULT_FRAME_LENGTH = 960;
41 const uint32_t DEFAULT_NODE_ID = 1243;
42 static vector<HpaeProcessorType> hpaeProcessorTypeMap = {
43 HPAE_SCENE_DEFAULT,
44 HPAE_SCENE_MUSIC,
45 HPAE_SCENE_GAME,
46 HPAE_SCENE_MOVIE,
47 HPAE_SCENE_SPEECH,
48 HPAE_SCENE_RING,
49 HPAE_SCENE_VOIP_DOWN,
50 HPAE_SCENE_OTHERS,
51 HPAE_SCENE_EFFECT_NONE,
52 HPAE_SCENE_EFFECT_OUT,
53 HPAE_SCENE_SPLIT_MEDIA,
54 HPAE_SCENE_SPLIT_NAVIGATION,
55 HPAE_SCENE_SPLIT_COMMUNICATION,
56 HPAE_SCENE_VOIP_UP,
57 HPAE_SCENE_RECORD,
58 HPAE_SCENE_PRE_ENHANCE,
59 HPAE_SCENE_ASR,
60 HPAE_SCENE_VOICE_MESSAGE,
61 HPAE_SCENE_COLLABORATIVE,
62 };
63
64 typedef void (*TestPtr)(const uint8_t *, size_t);
65
66 template<class T>
GetData()67 T GetData()
68 {
69 T object {};
70 size_t objectSize = sizeof(object);
71 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
72 return object;
73 }
74 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
75 if (ret != EOK) {
76 return {};
77 }
78 g_pos += objectSize;
79 return object;
80 }
81
82 template<class T>
GetArrLength(T & arr)83 uint32_t GetArrLength(T& arr)
84 {
85 if (arr == nullptr) {
86 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
87 return 0;
88 }
89 return sizeof(arr) / sizeof(arr[0]);
90 }
91
GetTestNodeInfo(HpaeNodeInfo & nodeInfo)92 static void GetTestNodeInfo(HpaeNodeInfo &nodeInfo)
93 {
94 nodeInfo.nodeId = DEFAULT_NODE_ID;
95 nodeInfo.frameLen = DEFAULT_FRAME_LENGTH;
96 nodeInfo.samplingRate = SAMPLE_RATE_48000;
97 nodeInfo.channels = STEREO;
98 nodeInfo.format = SAMPLE_S16LE;
99 nodeInfo.sceneType = HPAE_SCENE_MUSIC;
100 nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC;
101 }
102
CreateHpaeInfo(HpaeNodeInfo & nodeInfo,HpaeSinkInfo & dummySinkInfo)103 static void CreateHpaeInfo(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo)
104 {
105 GetTestNodeInfo(nodeInfo);
106 dummySinkInfo.channels = STEREO;
107 dummySinkInfo.frameLen = DEFAULT_FRAME_LENGTH;
108 dummySinkInfo.format = SAMPLE_F32LE;
109 dummySinkInfo.samplingRate = SAMPLE_RATE_48000;
110 }
111
DoProcessFuzzTest()112 void DoProcessFuzzTest()
113 {
114 HpaeNodeInfo nodeInfo;
115 GetTestNodeInfo(nodeInfo);
116 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
117 hpaeOutputCluster->DoProcess();
118 }
119
ResetFuzzTest()120 void ResetFuzzTest()
121 {
122 HpaeNodeInfo nodeInfo;
123 GetTestNodeInfo(nodeInfo);
124 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
125 hpaeOutputCluster->Reset();
126 }
127
ResetAllFuzzTest()128 void ResetAllFuzzTest()
129 {
130 HpaeNodeInfo nodeInfo;
131 GetTestNodeInfo(nodeInfo);
132 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
133 hpaeOutputCluster->ResetAll();
134 }
135
ConnectFuzzTest()136 void ConnectFuzzTest()
137 {
138 HpaeNodeInfo nodeInfo;
139 HpaeSinkInfo dummySinkInfo;
140 CreateHpaeInfo(nodeInfo, dummySinkInfo);
141 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
142 std::shared_ptr<HpaeProcessCluster> ProcessCluster =
143 std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
144 hpaeOutputCluster->Connect(ProcessCluster);
145 hpaeOutputCluster->DisConnect(ProcessCluster);
146 }
147
DisConnectFuzzTest()148 void DisConnectFuzzTest()
149 {
150 HpaeNodeInfo nodeInfo;
151 HpaeSinkInfo dummySinkInfo;
152 CreateHpaeInfo(nodeInfo, dummySinkInfo);
153 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
154 std::shared_ptr<HpaeProcessCluster> ProcessCluster =
155 std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
156 hpaeOutputCluster->DisConnect(ProcessCluster);
157 }
158
GetConverterNodeCountFuzzTest()159 void GetConverterNodeCountFuzzTest()
160 {
161 HpaeNodeInfo nodeInfo;
162 GetTestNodeInfo(nodeInfo);
163 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
164 hpaeOutputCluster->GetConverterNodeCount();
165 }
166
GetPreOutNumFuzzTest()167 void GetPreOutNumFuzzTest()
168 {
169 HpaeNodeInfo nodeInfo;
170 GetTestNodeInfo(nodeInfo);
171 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
172 hpaeOutputCluster->GetPreOutNum();
173 }
174
GetInstanceFuzzTest()175 void GetInstanceFuzzTest()
176 {
177 HpaeNodeInfo nodeInfo;
178 GetTestNodeInfo(nodeInfo);
179 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
180 std::string deviceClass = "";
181 std::string deviceNetId = "";
182 hpaeOutputCluster->GetInstance(deviceClass, deviceNetId);
183 }
184
InitFuzzTest()185 void InitFuzzTest()
186 {
187 HpaeNodeInfo nodeInfo;
188 GetTestNodeInfo(nodeInfo);
189 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
190 IAudioSinkAttr attr;
191 hpaeOutputCluster->Init(attr);
192 }
193
DeInitFuzzTest()194 void DeInitFuzzTest()
195 {
196 HpaeNodeInfo nodeInfo;
197 GetTestNodeInfo(nodeInfo);
198 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
199 hpaeOutputCluster->DeInit();
200 }
201
FlushFuzzTest()202 void FlushFuzzTest()
203 {
204 HpaeNodeInfo nodeInfo;
205 GetTestNodeInfo(nodeInfo);
206 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
207 hpaeOutputCluster->Flush();
208 }
209
PauseFuzzTest()210 void PauseFuzzTest()
211 {
212 HpaeNodeInfo nodeInfo;
213 GetTestNodeInfo(nodeInfo);
214 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
215 hpaeOutputCluster->Pause();
216 }
217
ResetRenderFuzzTest()218 void ResetRenderFuzzTest()
219 {
220 HpaeNodeInfo nodeInfo;
221 GetTestNodeInfo(nodeInfo);
222 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
223 hpaeOutputCluster->ResetRender();
224 }
225
ResumeFuzzTest()226 void ResumeFuzzTest()
227 {
228 HpaeNodeInfo nodeInfo;
229 GetTestNodeInfo(nodeInfo);
230 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
231 hpaeOutputCluster->Resume();
232 }
233
StartFuzzTest()234 void StartFuzzTest()
235 {
236 HpaeNodeInfo nodeInfo;
237 GetTestNodeInfo(nodeInfo);
238 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
239 hpaeOutputCluster->Start();
240 }
241
StopFuzzTest()242 void StopFuzzTest()
243 {
244 HpaeNodeInfo nodeInfo;
245 GetTestNodeInfo(nodeInfo);
246 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
247 hpaeOutputCluster->Stop();
248 }
249
SetTimeoutStopThdFuzzTest()250 void SetTimeoutStopThdFuzzTest()
251 {
252 HpaeNodeInfo nodeInfo;
253 GetTestNodeInfo(nodeInfo);
254 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
255 uint32_t timeoutThdMs = GetData<uint32_t>();
256 hpaeOutputCluster->SetTimeoutStopThd(timeoutThdMs);
257 }
258
GetStateFuzzTest()259 void GetStateFuzzTest()
260 {
261 HpaeNodeInfo nodeInfo;
262 GetTestNodeInfo(nodeInfo);
263 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
264 hpaeOutputCluster->GetState();
265 }
266
IsProcessClusterConnectedFuzzTest()267 void IsProcessClusterConnectedFuzzTest()
268 {
269 HpaeNodeInfo nodeInfo;
270 GetTestNodeInfo(nodeInfo);
271 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
272 uint32_t index = GetData<uint32_t>() % hpaeProcessorTypeMap.size();
273 HpaeProcessorType sceneType = hpaeProcessorTypeMap[index];
274 hpaeOutputCluster->IsProcessClusterConnected(sceneType);
275 }
276
UpdateAppsUidFuzzTest()277 void UpdateAppsUidFuzzTest()
278 {
279 HpaeNodeInfo nodeInfo;
280 GetTestNodeInfo(nodeInfo);
281 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
282 std::vector<int32_t> appsUid = {GetData<uint32_t>()};
283 hpaeOutputCluster->UpdateAppsUid(appsUid);
284 }
285
SetPriPaPowerFuzzTest()286 void SetPriPaPowerFuzzTest()
287 {
288 HpaeNodeInfo nodeInfo;
289 GetTestNodeInfo(nodeInfo);
290 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
291 hpaeOutputCluster->SetPriPaPower();
292 }
293
SetSyncIdFuzzTest()294 void SetSyncIdFuzzTest()
295 {
296 HpaeNodeInfo nodeInfo;
297 GetTestNodeInfo(nodeInfo);
298 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
299 int32_t syncId = GetData<int32_t>();
300 hpaeOutputCluster->SetSyncId(syncId);
301 }
302
GetLatencyFuzzTest()303 void GetLatencyFuzzTest()
304 {
305 HpaeNodeInfo nodeInfo;
306 GetTestNodeInfo(nodeInfo);
307 auto hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
308 hpaeOutputCluster->GetLatency();
309 }
310
311 typedef void (*TestFuncs[23])();
312
313 TestFuncs g_testFuncs = {
314 DoProcessFuzzTest,
315 ResetFuzzTest,
316 ResetAllFuzzTest,
317 ConnectFuzzTest,
318 DisConnectFuzzTest,
319 GetConverterNodeCountFuzzTest,
320 GetPreOutNumFuzzTest,
321 GetInstanceFuzzTest,
322 InitFuzzTest,
323 DeInitFuzzTest,
324 FlushFuzzTest,
325 PauseFuzzTest,
326 ResetRenderFuzzTest,
327 ResumeFuzzTest,
328 StartFuzzTest,
329 StopFuzzTest,
330 SetTimeoutStopThdFuzzTest,
331 GetStateFuzzTest,
332 IsProcessClusterConnectedFuzzTest,
333 UpdateAppsUidFuzzTest,
334 SetPriPaPowerFuzzTest,
335 SetSyncIdFuzzTest,
336 GetLatencyFuzzTest,
337 };
338
FuzzTest(const uint8_t * rawData,size_t size)339 bool FuzzTest(const uint8_t* rawData, size_t size)
340 {
341 if (rawData == nullptr) {
342 return false;
343 }
344
345 // initialize data
346 RAW_DATA = rawData;
347 g_dataSize = size;
348 g_pos = 0;
349
350 uint32_t code = GetData<uint32_t>();
351 uint32_t len = GetArrLength(g_testFuncs);
352 if (len > 0) {
353 g_testFuncs[code % len]();
354 } else {
355 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
356 }
357
358 return true;
359 }
360
361 } // namespace AudioStandard
362 } // namesapce OHOS
363
364 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)365 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
366 {
367 if (size < OHOS::AudioStandard::THRESHOLD) {
368 return 0;
369 }
370
371 OHOS::AudioStandard::FuzzTest(data, size);
372 return 0;
373 }
374