1 /*
2 * Copyright (c) 2024-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 "native_audio_session_manager.h"
17 #include "native_audio_common.h"
18 #include "audio_session_manager.h"
19 #include <ostream>
20 #include <sstream>
21 #include <iostream>
22 #include <string>
23 #include <map>
24 #include <cstdint>
25 #include <cstdio>
26 #include <cstring>
27 #include <thread>
28 #include <chrono>
29 #include "audio_errors.h"
30 #include "audio_manager_log.h"
31 #include <cinttypes>
32 #include "common/native_audiostreambuilder.h"
33 #include "native_audiorenderer.h"
34
35 namespace OHOS {
36 namespace AudioStandard {
37
38 class SessionNdkTest {
39 public:
40 SessionNdkTest() = default;
41 ~SessionNdkTest() = default;
42 void Init();
43 static void RegisterCallback(OH_AudioSession_DeactivatedCallback callback);
44 static void UnregisterCallback(OH_AudioSession_DeactivatedCallback callback);
45 void ActivateAudioSession(OH_AudioSession_Strategy strategy);
46 static void DeactivateAudioSession();
47 static void IsAudioSessionActivated();
48 void RegisterAndActive(OH_AudioSession_DeactivatedCallback callback, OH_AudioSession_Strategy strategy);
49 int32_t MyCallbackFunction(OH_AudioSession_DeactivatedEvent event);
50 OH_AudioRenderer* StartPlay();
51 static void StopPlay(OH_AudioRenderer* audioRenderer);
52 OH_AudioRenderer* PlayMusic(OH_AudioSession_DeactivatedCallback callback,
53 OH_AudioSession_ConcurrencyMode mode);
54 void LogicPathCheck(int operate, OH_AudioSession_DeactivatedCallback callback);
55 void PlayCheck(int operate, OH_AudioSession_DeactivatedCallback callback);
56 };
57
58 OH_AudioSessionManager *audioSessionManager;
59
60 OH_AudioSession_DeactivatedEvent event;
61
62 std::shared_ptr<SessionNdkTest> g_sessionNdkTest = nullptr;
63
64 OH_AudioSession_Strategy strategy;
65
66 const int CASE_EXIT = 0;
67
68 const int CASE_REGISTER = 1;
69
70 const int CASE_UN_REGISTER = 2;
71
72 const int CASE_ACTIVE = 3;
73
74 const int CASE_DEACTIVE = 4;
75
76 const int CASE_IS_ACTIVE = 5;
77
78 const int CASE_REGISTER_ACTIVE = 6;
79
80 const int CASE_PAUSE_PLAY = 7;
81
82 const int CASE_MIX_PLAY = 8;
83
84 const int CASE_DUCK_PLAY = 9;
85
86 const int CASE_DEFAULT_PLAY = 10;
87
88 const int CASE_STOP_PLAY = 100;
89
90 // audio renderer
91 OH_AudioRenderer* audioRenderer;
92 std::string g_filePath = "/data/data/oh_test_audio_session.pcm";
93 FILE* g_file = nullptr;
94 bool g_readEnd = false;
95 int32_t g_samplingRate = 48000;
96 int32_t g_channelCount = 2;
97 int32_t g_latencyMode = 0;
98 int32_t g_sampleFormat = 1;
99 int32_t g_frameSize = 240;
100 float g_speed = 1.0f;
101
AudioRendererOnWriteData(OH_AudioRenderer * capturer,void * userData,void * buffer,int32_t bufferLen)102 static int32_t AudioRendererOnWriteData(OH_AudioRenderer* capturer,
103 void* userData,
104 void* buffer,
105 int32_t bufferLen)
106 {
107 size_t readCount = fread(buffer, bufferLen, 1, g_file);
108 if (!readCount) {
109 if (ferror(g_file)) {
110 std::cout << "Error reading myfile" << std::endl;
111 } else if (feof(g_file)) {
112 std::cout << "EOF found" << std::endl;
113 g_readEnd = true;
114 }
115 }
116 return 0;
117 }
118
AudioRendererDeviceChangeCb(OH_AudioRenderer * renderer,void * userData,OH_AudioStream_DeviceChangeReason reason)119 static void AudioRendererDeviceChangeCb(OH_AudioRenderer* renderer, void* userData,
120 OH_AudioStream_DeviceChangeReason reason)
121 {
122 std::cout << "AudioRendererDeviceChangeCb reason: " << reason << std::endl;
123 }
124
UserOperateDsiplay()125 static void UserOperateDsiplay()
126 {
127 std::cout << "Please Input Operate" << std::endl;
128 std::cout << "1 -----> Register Callback" << std::endl;
129 std::cout << "2 -----> UnRegister Callback" << std::endl;
130 std::cout << "3 -----> Activate AudioSession" << std::endl;
131 std::cout << "4 -----> DeActivate AudioSession" << std::endl;
132 std::cout << "5 -----> Is Activate Judging" << std::endl;
133 std::cout << "6 -----> Register and Active" << std::endl;
134 std::cout << "7 -----> Pause Play" << std::endl;
135 std::cout << "8 -----> Mix Play" << std::endl;
136 std::cout << "9 -----> Duck Play" << std::endl;
137 std::cout << "10 -----> Default Play" << std::endl;
138 std::cout << "100 -----> Stop Play" << std::endl;
139 std::cout << "0 -----> Exit" << std::endl;
140 }
141
Init()142 void SessionNdkTest::Init()
143 {
144 OH_AudioManager_GetAudioSessionManager(&audioSessionManager);
145 }
146
RegisterCallback(OH_AudioSession_DeactivatedCallback callback)147 void SessionNdkTest::RegisterCallback(OH_AudioSession_DeactivatedCallback callback)
148 {
149 std::cout << "Start Register callback" << std::endl;
150 OH_AudioCommon_Result result =
151 OH_AudioSessionManager_RegisterSessionDeactivatedCallback(audioSessionManager, callback);
152 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
153 std::cout << "Register callback SUCCESS" << std::endl;
154 } else {
155 std::cout << "Register callback FAILED" << std::endl;
156 }
157 }
158
UnregisterCallback(OH_AudioSession_DeactivatedCallback callback)159 void SessionNdkTest::UnregisterCallback(OH_AudioSession_DeactivatedCallback callback)
160 {
161 std::cout << "Start UnRegister callback" << std::endl;
162 OH_AudioCommon_Result result =
163 OH_AudioSessionManager_UnregisterSessionDeactivatedCallback(audioSessionManager, callback);
164 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
165 std::cout << "UnRegister callback SUCCESS" << std::endl;
166 } else {
167 std::cout << "UnRegister callback FAILED" << std::endl;
168 }
169 }
170
ActivateAudioSession(OH_AudioSession_Strategy strategy)171 void SessionNdkTest::ActivateAudioSession(OH_AudioSession_Strategy strategy)
172 {
173 std::cout << "Start Activate AudioSession" << std::endl;
174 OH_AudioCommon_Result result =
175 OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);
176 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
177 std::cout << "Activate AudioSession SUCCESS" << std::endl;
178 } else {
179 std::cout << "Activate AudioSession FAILED" << std::endl;
180 }
181 }
182
DeactivateAudioSession()183 void SessionNdkTest::DeactivateAudioSession()
184 {
185 std::cout << "Start DeActivate AudioSession" << std::endl;
186 OH_AudioCommon_Result result = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager);
187 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
188 std::cout << "DeActivate AudioSession SUCCESS" << std::endl;
189 } else {
190 std::cout << "DeActivate AudioSession FAILED" << std::endl;
191 }
192 }
193
IsAudioSessionActivated()194 void SessionNdkTest::IsAudioSessionActivated()
195 {
196 std::cout << "Start Is Activate AudioSession" << std::endl;
197 bool result = OH_AudioSessionManager_IsAudioSessionActivated(audioSessionManager);
198 if (result) {
199 std::cout << "Is Activate AudioSession SUCCESS" << std::endl;
200 } else {
201 std::cout << "Is Activate AudioSession FAILED" << std::endl;
202 }
203 }
204
RegisterAndActive(OH_AudioSession_DeactivatedCallback callback,OH_AudioSession_Strategy strategy)205 void SessionNdkTest::RegisterAndActive(OH_AudioSession_DeactivatedCallback callback,
206 OH_AudioSession_Strategy strategy)
207 {
208 RegisterCallback(callback);
209 ActivateAudioSession(strategy);
210 }
211
StartPlay()212 OH_AudioRenderer* SessionNdkTest::StartPlay()
213 {
214 OH_AudioStream_Result ret;
215
216 // 1. create builder
217 OH_AudioStreamBuilder* builder;
218 OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
219 ret = OH_AudioStreamBuilder_Create(&builder, type);
220 std::cout << "[Renderer] createcallback ret: " << ret << std::endl;
221
222 // 2. set params and callbacks
223 OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate);
224 OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount);
225 OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode);
226 OH_AudioStreamBuilder_SetSampleFormat(builder, (OH_AudioStream_SampleFormat)g_sampleFormat);
227
228 OH_AudioRenderer_Callbacks callbacks;
229 callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
230 ret = OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);
231 std::cout << "[Renderer] setcallback ret: " << ret << std::endl;
232
233 OH_AudioRenderer_OutputDeviceChangeCallback deviceChangeCb = AudioRendererDeviceChangeCb;
234 ret = OH_AudioStreamBuilder_SetRendererOutputDeviceChangeCallback(builder, deviceChangeCb, nullptr);
235 std::cout << "[Renderer] set device change callback ret: " << ret << std::endl;
236
237 // set buffer size to g_frameSize
238 ret = OH_AudioStreamBuilder_SetFrameSizeInCallback(builder, g_frameSize);
239 std::cout << "[Renderer] set buffer size, ret: " << ret << std::endl;
240
241 // 3. create OH_AudioRenderer
242 ret = OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
243 std::cout << "[Renderer] create renderer client, ret: " << ret << std::endl;
244
245 // 4. setspeed
246 ret = OH_AudioRenderer_SetSpeed(audioRenderer, g_speed);
247 std::cout << "[Renderer] speed ret: " << ret << std::endl;
248
249 // 5. start
250 ret = OH_AudioRenderer_Start(audioRenderer);
251 std::cout << "[Renderer] start ret: " << ret << std::endl;
252
253 int32_t frameSize;
254 OH_AudioRenderer_GetFrameSizeInCallback(audioRenderer, &frameSize);
255 std::cout << "[Renderer] framesize: " << frameSize << std::endl;
256 return audioRenderer;
257 }
258
StopPlay(OH_AudioRenderer * audioRenderer)259 void SessionNdkTest::StopPlay(OH_AudioRenderer* audioRenderer)
260 {
261 DeactivateAudioSession();
262 OH_AudioStream_Result ret = OH_AudioRenderer_Stop(audioRenderer);
263 std::cout << "[Renderer] stop ret: " << ret << std::endl;
264 ret = OH_AudioRenderer_Release(audioRenderer);
265 std::cout << "[Renderer] release ret: " << ret << std::endl;
266 }
267
PlayMusic(OH_AudioSession_DeactivatedCallback callback,OH_AudioSession_ConcurrencyMode mode)268 OH_AudioRenderer* SessionNdkTest::PlayMusic(OH_AudioSession_DeactivatedCallback callback,
269 OH_AudioSession_ConcurrencyMode mode)
270 {
271 event.reason = DEACTIVATED_LOWER_PRIORITY;
272 callback(event);
273 strategy.concurrencyMode = mode;
274 RegisterAndActive(callback, strategy);
275 g_file = fopen(g_filePath.c_str(), "rb");
276 if (g_file == nullptr) {
277 std::cout << "Unable to open file" << std::endl;
278 return nullptr;
279 }
280 return StartPlay();
281 }
282
LogicPathCheck(int operate,OH_AudioSession_DeactivatedCallback callback)283 void SessionNdkTest::LogicPathCheck(int operate, OH_AudioSession_DeactivatedCallback callback)
284 {
285 switch (operate) {
286 case CASE_REGISTER:
287 event.reason = DEACTIVATED_LOWER_PRIORITY;
288 callback(event);
289 RegisterCallback(callback);
290 break;
291 case CASE_UN_REGISTER:
292 event.reason = DEACTIVATED_TIMEOUT;
293 callback(event);
294 UnregisterCallback(callback);
295 break;
296 case CASE_ACTIVE:
297 strategy.concurrencyMode = CONCURRENCY_MIX_WITH_OTHERS;
298 ActivateAudioSession(strategy);
299 break;
300 case CASE_DEACTIVE:
301 DeactivateAudioSession();
302 break;
303 case CASE_IS_ACTIVE:
304 IsAudioSessionActivated();
305 break;
306 case CASE_REGISTER_ACTIVE:
307 event.reason = DEACTIVATED_LOWER_PRIORITY;
308 callback(event);
309 strategy.concurrencyMode = CONCURRENCY_MIX_WITH_OTHERS;
310 RegisterAndActive(callback, strategy);
311 break;
312 default:
313 std::cout << "Continue" << std::endl;
314 }
315 }
316
PlayCheck(int operate,OH_AudioSession_DeactivatedCallback callback)317 void SessionNdkTest::PlayCheck(int operate, OH_AudioSession_DeactivatedCallback callback)
318 {
319 switch (operate) {
320 case CASE_PAUSE_PLAY:
321 audioRenderer = PlayMusic(callback, CONCURRENCY_PAUSE_OTHERS);
322 if (audioRenderer == nullptr) {
323 std::cout << "[PAUSE] Start play failed" << std::endl;
324 } else {
325 std::cout << "[PAUSE] Start play completed" << std::endl;
326 }
327 break;
328 case CASE_MIX_PLAY:
329 audioRenderer = PlayMusic(callback, CONCURRENCY_MIX_WITH_OTHERS);
330 if (audioRenderer == nullptr) {
331 std::cout << "[MIX] Start play failed" << std::endl;
332 } else {
333 std::cout << "[MIX] Start play completed" << std::endl;
334 }
335 break;
336 case CASE_DUCK_PLAY:
337 audioRenderer = PlayMusic(callback, CONCURRENCY_DUCK_OTHERS);
338 if (audioRenderer == nullptr) {
339 std::cout << "[DUCK] Start play failed" << std::endl;
340 } else {
341 std::cout << "[DUCK] Start play completed" << std::endl;
342 }
343 break;
344 case CASE_DEFAULT_PLAY:
345 audioRenderer = PlayMusic(callback, CONCURRENCY_DEFAULT);
346 if (audioRenderer == nullptr) {
347 std::cout << "[DEFAULT] Start play failed" << std::endl;
348 } else {
349 std::cout << "[DEFAULT] Start play completed" << std::endl;
350 }
351 break;
352 case CASE_STOP_PLAY:
353 StopPlay(audioRenderer);
354 std::cout << "Stop play completed" << std::endl;
355 break;
356 default:
357 std::cout << "End" << std::endl;
358 }
359 }
360
MyCallbackFunction(OH_AudioSession_DeactivatedEvent event)361 int32_t MyCallbackFunction(OH_AudioSession_DeactivatedEvent event)
362 {
363 std::cout << "Callback For Event Reason: " << static_cast<int>(event.reason) << std::endl;
364 return 0;
365 }
366
367 } // namespace AudioStandard
368 } // namespace OHOS
369
370
371 using namespace OHOS::AudioStandard;
main()372 int main()
373 {
374 // Init Get AudioSessionManager
375 g_sessionNdkTest = std::make_shared<SessionNdkTest>();
376
377 g_sessionNdkTest->Init();
378
379 std::cout << "Init Completed, Start Test" << std::endl;
380
381 bool runFlag = true;
382 int operate;
383
384 OH_AudioSession_DeactivatedCallback callback = MyCallbackFunction;
385
386 while (runFlag) {
387 UserOperateDsiplay();
388
389 std::cin >> operate;
390
391 if (operate == CASE_EXIT) {
392 runFlag = false;
393 }
394
395 g_sessionNdkTest->LogicPathCheck(operate, callback);
396 g_sessionNdkTest->PlayCheck(operate, callback);
397
398 if (operate != CASE_REGISTER && operate != CASE_UN_REGISTER && operate != CASE_ACTIVE &&
399 operate != CASE_DEACTIVE && operate != CASE_IS_ACTIVE && operate != CASE_REGISTER_ACTIVE &&
400 operate != CASE_PAUSE_PLAY && operate != CASE_MIX_PLAY && operate != CASE_DUCK_PLAY &&
401 operate != CASE_DEFAULT_PLAY && operate != CASE_STOP_PLAY) {
402 std::cout << "Input Valid, RE Input";
403 }
404 }
405 if (g_file != nullptr) {
406 fclose(g_file);
407 g_file = nullptr;
408 }
409 std::cout << "End Test" << std::endl;
410 }