1 /*
2 * Copyright (c) 2021-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 "audio_service_client.h"
17
18 #include <fstream>
19 #include <sstream>
20
21 #include "iservice_registry.h"
22 #include "audio_log.h"
23 #include "audio_utils.h"
24 #include "hisysevent.h"
25 #include "securec.h"
26 #include "system_ability_definition.h"
27 #include "unistd.h"
28 #include "audio_errors.h"
29 #include "audio_info.h"
30
31 using namespace std;
32
33 namespace OHOS {
34 namespace AudioStandard {
35 AudioRendererCallbacks::~AudioRendererCallbacks() = default;
36 AudioCapturerCallbacks::~AudioCapturerCallbacks() = default;
37 const uint32_t CHECK_UTIL_SUCCESS = 0;
38 const uint32_t INIT_TIMEOUT_IN_SEC = 3;
39 const uint32_t DRAIN_TIMEOUT_IN_SEC = 3;
40 const uint32_t WRITE_TIMEOUT_IN_SEC = 2;
41 const uint32_t READ_TIMEOUT_IN_SEC = 5;
42 const uint32_t DOUBLE_VALUE = 2;
43 const uint32_t MAX_LENGTH_FACTOR = 5;
44 const uint32_t T_LENGTH_FACTOR = 4;
45 const uint64_t MIN_BUF_DURATION_IN_USEC = 92880;
46 const uint32_t LATENCY_THRESHOLD = 35;
47 const int32_t NO_OF_PREBUF_TIMES = 6;
48
49
50 const string PATH_SEPARATOR = "/";
51 const string COOKIE_FILE_NAME = "cookie";
52 static const string INNER_CAPTURER_SOURCE = "InnerCapturer.monitor";
53
54 static const std::unordered_map<AudioStreamType, std::string> STREAM_TYPE_ENUM_STRING_MAP = {
55 {STREAM_VOICE_CALL, "voice_call"},
56 {STREAM_MUSIC, "music"},
57 {STREAM_RING, "ring"},
58 {STREAM_MEDIA, "media"},
59 {STREAM_VOICE_ASSISTANT, "voice_assistant"},
60 {STREAM_SYSTEM, "system"},
61 {STREAM_ALARM, "alarm"},
62 {STREAM_NOTIFICATION, "notification"},
63 {STREAM_BLUETOOTH_SCO, "bluetooth_sco"},
64 {STREAM_ENFORCED_AUDIBLE, "enforced_audible"},
65 {STREAM_DTMF, "dtmf"},
66 {STREAM_TTS, "tts"},
67 {STREAM_ACCESSIBILITY, "accessibility"},
68 {STREAM_RECORDING, "recording"},
69 {STREAM_MOVIE, "movie"},
70 {STREAM_GAME, "game"},
71 {STREAM_SPEECH, "speech"},
72 {STREAM_SYSTEM_ENFORCED, "system_enforced"},
73 {STREAM_ULTRASONIC, "ultrasonic"},
74 {STREAM_WAKEUP, "wakeup"},
75 {STREAM_VOICE_MESSAGE, "voice_message"},
76 {STREAM_NAVIGATION, "navigation"}
77 };
78
CheckReturnIfinvalid(bool expr,const int32_t retVal)79 static int32_t CheckReturnIfinvalid(bool expr, const int32_t retVal)
80 {
81 do {
82 if (!(expr)) {
83 return retVal;
84 }
85 } while (false);
86 return CHECK_UTIL_SUCCESS;
87 }
88
CheckPaStatusIfinvalid(pa_threaded_mainloop * mainLoop,pa_context * context,pa_stream * paStream,const int32_t retVal)89 static int32_t CheckPaStatusIfinvalid(pa_threaded_mainloop *mainLoop, pa_context *context,
90 pa_stream *paStream, const int32_t retVal)
91 {
92 return CheckReturnIfinvalid(mainLoop && context &&
93 paStream && PA_CONTEXT_IS_GOOD(pa_context_get_state(context)) &&
94 PA_STREAM_IS_GOOD(pa_stream_get_state(paStream)), retVal);
95 }
96
CheckPaStatusIfinvalid(pa_threaded_mainloop * mainLoop,pa_context * context,pa_stream * paStream,const int32_t retVal,int32_t & pError)97 static int32_t CheckPaStatusIfinvalid(pa_threaded_mainloop *mainLoop, pa_context *context,
98 pa_stream *paStream, const int32_t retVal, int32_t &pError)
99 {
100 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, -1) < 0) {
101 pError = pa_context_errno(context);
102 return -1;
103 }
104 return retVal;
105 }
106
ConvertFromPAAudioParams(pa_sample_spec paSampleSpec)107 AudioStreamParams AudioServiceClient::ConvertFromPAAudioParams(pa_sample_spec paSampleSpec)
108 {
109 AudioStreamParams audioParams;
110
111 audioParams.channels = paSampleSpec.channels;
112 audioParams.samplingRate = paSampleSpec.rate;
113 audioParams.encoding = ENCODING_PCM;
114
115 switch (paSampleSpec.format) {
116 case PA_SAMPLE_U8:
117 audioParams.format = SAMPLE_U8;
118 break;
119 case PA_SAMPLE_S16LE:
120 audioParams.format = SAMPLE_S16LE;
121 break;
122 case PA_SAMPLE_S24LE:
123 audioParams.format = SAMPLE_S24LE;
124 break;
125 case PA_SAMPLE_S32LE:
126 audioParams.format = SAMPLE_S32LE;
127 break;
128 default:
129 audioParams.format = INVALID_WIDTH;
130 break;
131 }
132
133 return audioParams;
134 }
135
ConvertToPAAudioParams(AudioStreamParams audioParams)136 pa_sample_spec AudioServiceClient::ConvertToPAAudioParams(AudioStreamParams audioParams)
137 {
138 pa_sample_spec paSampleSpec;
139
140 paSampleSpec.channels = audioParams.channels;
141 paSampleSpec.rate = audioParams.samplingRate;
142
143 switch ((AudioSampleFormat)audioParams.format) {
144 case SAMPLE_U8:
145 paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_U8;
146 break;
147 case SAMPLE_S16LE:
148 paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S16LE;
149 break;
150 case SAMPLE_S24LE:
151 paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S24LE;
152 break;
153 case SAMPLE_S32LE:
154 paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S32LE;
155 break;
156 default:
157 paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_INVALID;
158 break;
159 }
160
161 return paSampleSpec;
162 }
163
AlignToAudioFrameSize(size_t l,const pa_sample_spec & ss)164 static size_t AlignToAudioFrameSize(size_t l, const pa_sample_spec &ss)
165 {
166 size_t fs = pa_frame_size(&ss);
167 if (fs == 0) {
168 AUDIO_ERR_LOG(" Error: pa_frame_size returned 0");
169 return 0;
170 }
171
172 return (l / fs) * fs;
173 }
174
PAStreamStartSuccessCb(pa_stream * stream,int32_t success,void * userdata)175 void AudioServiceClient::PAStreamStartSuccessCb(pa_stream *stream, int32_t success, void *userdata)
176 {
177 if (!userdata) {
178 AUDIO_ERR_LOG("PAStreamStartSuccessCb: userdata is null");
179 return;
180 }
181
182 AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
183 pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
184
185 asClient->state_ = RUNNING;
186 asClient->WriteStateChangedSysEvents();
187 std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
188 if (streamCb != nullptr) {
189 streamCb->OnStateChange(asClient->state_, asClient->stateChangeCmdType_);
190 }
191 asClient->stateChangeCmdType_ = CMD_FROM_CLIENT;
192 asClient->streamCmdStatus_ = success;
193 pa_threaded_mainloop_signal(mainLoop, 0);
194 }
195
PAStreamStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)196 void AudioServiceClient::PAStreamStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
197 {
198 AUDIO_DEBUG_LOG("PAStreamStopSuccessCb in");
199 if (!userdata) {
200 AUDIO_ERR_LOG("PAStreamStopSuccessCb: userdata is null");
201 return;
202 }
203
204 AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
205 pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
206
207 asClient->state_ = STOPPED;
208 asClient->WriteStateChangedSysEvents();
209 std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
210 if (streamCb != nullptr) {
211 streamCb->OnStateChange(asClient->state_);
212 }
213 asClient->streamCmdStatus_ = success;
214 AUDIO_DEBUG_LOG("PAStreamStopSuccessCb: start signal");
215 pa_threaded_mainloop_signal(mainLoop, 0);
216 AUDIO_DEBUG_LOG("PAStreamStopSuccessCb out");
217 }
218
PAStreamAsyncStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)219 void AudioServiceClient::PAStreamAsyncStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
220 {
221 AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb in");
222 if (!userdata) {
223 AUDIO_ERR_LOG("PAStreamAsyncStopSuccessCb: userdata is null");
224 return;
225 }
226
227 AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
228 pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
229 unique_lock<mutex> lockstopping(asClient->stoppingMutex_);
230
231 asClient->state_ = STOPPED;
232 asClient->WriteStateChangedSysEvents();
233 std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
234 if (streamCb != nullptr) {
235 streamCb->OnStateChange(asClient->state_);
236 }
237 asClient->streamCmdStatus_ = success;
238 AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb: start signal");
239 lockstopping.unlock();
240 pa_threaded_mainloop_signal(mainLoop, 0);
241 asClient->dataCv_.notify_one();
242 AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb out");
243 }
244
PAStreamPauseSuccessCb(pa_stream * stream,int32_t success,void * userdata)245 void AudioServiceClient::PAStreamPauseSuccessCb(pa_stream *stream, int32_t success, void *userdata)
246 {
247 if (!userdata) {
248 AUDIO_ERR_LOG("PAStreamPauseSuccessCb: userdata is null");
249 return;
250 }
251
252 AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
253 pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
254
255 asClient->state_ = PAUSED;
256 asClient->WriteStateChangedSysEvents();
257 std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
258 if (streamCb != nullptr) {
259 streamCb->OnStateChange(asClient->state_, asClient->stateChangeCmdType_);
260 }
261 asClient->stateChangeCmdType_ = CMD_FROM_CLIENT;
262 asClient->streamCmdStatus_ = success;
263 pa_threaded_mainloop_signal(mainLoop, 0);
264 }
265
PAStreamDrainSuccessCb(pa_stream * stream,int32_t success,void * userdata)266 void AudioServiceClient::PAStreamDrainSuccessCb(pa_stream *stream, int32_t success, void *userdata)
267 {
268 if (!userdata) {
269 AUDIO_ERR_LOG("PAStreamDrainSuccessCb: userdata is null");
270 return;
271 }
272
273 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
274 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
275
276 asClient->streamDrainStatus_ = success;
277 pa_threaded_mainloop_signal(mainLoop, 0);
278 }
279
PAStreamDrainInStopCb(pa_stream * stream,int32_t success,void * userdata)280 void AudioServiceClient::PAStreamDrainInStopCb(pa_stream *stream, int32_t success, void *userdata)
281 {
282 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
283 pa_operation *operation = pa_stream_cork(asClient->paStream, 1, asClient->PAStreamCorkSuccessCb, userdata);
284 pa_operation_unref(operation);
285
286 asClient->streamDrainStatus_ = success;
287 }
288
PAStreamFlushSuccessCb(pa_stream * stream,int32_t success,void * userdata)289 void AudioServiceClient::PAStreamFlushSuccessCb(pa_stream *stream, int32_t success, void *userdata)
290 {
291 if (!userdata) {
292 AUDIO_ERR_LOG("PAStreamFlushSuccessCb: userdata is null");
293 return;
294 }
295 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
296 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
297
298 asClient->streamFlushStatus_ = success;
299 pa_threaded_mainloop_signal(mainLoop, 0);
300 }
301
PAStreamSetBufAttrSuccessCb(pa_stream * stream,int32_t success,void * userdata)302 void AudioServiceClient::PAStreamSetBufAttrSuccessCb(pa_stream *stream, int32_t success, void *userdata)
303 {
304 if (!userdata) {
305 AUDIO_ERR_LOG("PAStreamSetBufAttrSuccessCb: userdata is null");
306 return;
307 }
308 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
309 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
310
311 AUDIO_DEBUG_LOG("SetBufAttr %{public}s", success ? "success" : "faild");
312
313 pa_threaded_mainloop_signal(mainLoop, 0);
314 }
315
SetAudioRenderMode(AudioRenderMode renderMode)316 int32_t AudioServiceClient::SetAudioRenderMode(AudioRenderMode renderMode)
317 {
318 AUDIO_DEBUG_LOG("SetAudioRenderMode begin");
319 renderMode_ = renderMode;
320
321 if (renderMode_ != RENDER_MODE_CALLBACK) {
322 return AUDIO_CLIENT_SUCCESS;
323 }
324
325 if (CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_ERR) < 0) {
326 return AUDIO_CLIENT_ERR;
327 }
328
329 pa_threaded_mainloop_lock(mainLoop);
330 pa_buffer_attr bufferAttr;
331 bufferAttr.fragsize = static_cast<uint32_t>(-1);
332 bufferAttr.prebuf = AlignToAudioFrameSize(pa_usec_to_bytes(MIN_BUF_DURATION_IN_USEC, &sampleSpec), sampleSpec);
333 bufferAttr.maxlength = bufferAttr.prebuf * MAX_LENGTH_FACTOR;
334 bufferAttr.tlength = bufferAttr.prebuf * T_LENGTH_FACTOR;
335 bufferAttr.minreq = bufferAttr.prebuf;
336 pa_operation *operation = pa_stream_set_buffer_attr(paStream, &bufferAttr,
337 PAStreamSetBufAttrSuccessCb, (void *)this);
338 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
339 pa_threaded_mainloop_wait(mainLoop);
340 }
341 pa_operation_unref(operation);
342 pa_threaded_mainloop_unlock(mainLoop);
343
344 AUDIO_DEBUG_LOG("SetAudioRenderMode end");
345
346 return AUDIO_CLIENT_SUCCESS;
347 }
348
GetAudioRenderMode()349 AudioRenderMode AudioServiceClient::GetAudioRenderMode()
350 {
351 return renderMode_;
352 }
353
SetAudioCaptureMode(AudioCaptureMode captureMode)354 int32_t AudioServiceClient::SetAudioCaptureMode(AudioCaptureMode captureMode)
355 {
356 AUDIO_DEBUG_LOG("SetAudioCaptureMode.");
357 captureMode_ = captureMode;
358
359 return AUDIO_CLIENT_SUCCESS;
360 }
361
GetAudioCaptureMode()362 AudioCaptureMode AudioServiceClient::GetAudioCaptureMode()
363 {
364 return captureMode_;
365 }
366
PAStreamWriteCb(pa_stream * stream,size_t length,void * userdata)367 void AudioServiceClient::PAStreamWriteCb(pa_stream *stream, size_t length, void *userdata)
368 {
369 if (!userdata) {
370 AUDIO_ERR_LOG("PAStreamWriteCb: userdata is null");
371 return;
372 }
373
374 auto asClient = static_cast<AudioServiceClient *>(userdata);
375 int64_t now = ClockTime::GetCurNano() / AUDIO_US_PER_SECOND;
376 AUDIO_DEBUG_LOG("Inside PA write callback cost[%{public}" PRId64 "]",
377 (now - asClient->mWriteCbStamp));
378 asClient->mWriteCbStamp = now;
379 auto mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
380 pa_threaded_mainloop_signal(mainLoop, 0);
381 }
382
PAStreamReadCb(pa_stream * stream,size_t length,void * userdata)383 void AudioServiceClient::PAStreamReadCb(pa_stream *stream, size_t length, void *userdata)
384 {
385 AUDIO_DEBUG_LOG("PAStreamReadCb Inside PA read callback");
386 if (!userdata) {
387 AUDIO_ERR_LOG("PAStreamReadCb: userdata is null");
388 return;
389 }
390 auto asClient = static_cast<AudioServiceClient *>(userdata);
391 auto mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
392 pa_threaded_mainloop_signal(mainLoop, 0);
393 }
394
PAStreamUnderFlowCb(pa_stream * stream,void * userdata)395 void AudioServiceClient::PAStreamUnderFlowCb(pa_stream *stream, void *userdata)
396 {
397 Trace trace("PAStreamUnderFlow");
398 if (!userdata) {
399 AUDIO_ERR_LOG("PAStreamUnderFlowCb: userdata is null");
400 return;
401 }
402
403 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
404 asClient->underFlowCount++;
405 AUDIO_WARNING_LOG("AudioServiceClient underrun: %{public}d!", asClient->underFlowCount);
406 }
407
PAStreamLatencyUpdateCb(pa_stream * stream,void * userdata)408 void AudioServiceClient::PAStreamLatencyUpdateCb(pa_stream *stream, void *userdata)
409 {
410 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)userdata;
411 pa_threaded_mainloop_signal(mainLoop, 0);
412 }
413
PAStreamMovedCb(pa_stream * stream,void * userdata)414 void AudioServiceClient::PAStreamMovedCb(pa_stream *stream, void *userdata)
415 {
416 if (!userdata) {
417 AUDIO_ERR_LOG("PAStreamMovedCb: userdata is null");
418 return;
419 }
420
421 // get stream informations.
422 uint32_t deviceIndex = pa_stream_get_device_index(stream); // pa_context_get_sink_info_by_index
423
424 // Return 1 if the sink or source this stream is connected to has been suspended.
425 // This will return 0 if not, and a negative value on error.
426 int res = pa_stream_is_suspended(stream);
427 AUDIO_DEBUG_LOG("PAstream moved to index:[%{public}d] suspended:[%{public}d]",
428 deviceIndex, res);
429 }
430
PAStreamStateCb(pa_stream * stream,void * userdata)431 void AudioServiceClient::PAStreamStateCb(pa_stream *stream, void *userdata)
432 {
433 if (!userdata) {
434 AUDIO_ERR_LOG("PAStreamStateCb: userdata is null");
435 return;
436 }
437
438 AudioServiceClient *asClient = (AudioServiceClient *)userdata;
439 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
440
441 if (asClient->mAudioRendererCallbacks)
442 asClient->mAudioRendererCallbacks->OnStreamStateChangeCb();
443
444 AUDIO_INFO_LOG("Current Stream State: %{public}d", pa_stream_get_state(stream));
445
446 switch (pa_stream_get_state(stream)) {
447 case PA_STREAM_READY:
448 case PA_STREAM_FAILED:
449 case PA_STREAM_TERMINATED:
450 pa_threaded_mainloop_signal(mainLoop, 0);
451 break;
452
453 case PA_STREAM_UNCONNECTED:
454 case PA_STREAM_CREATING:
455 default:
456 break;
457 }
458 }
459
PAContextStateCb(pa_context * context,void * userdata)460 void AudioServiceClient::PAContextStateCb(pa_context *context, void *userdata)
461 {
462 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)userdata;
463 AUDIO_INFO_LOG("Current Context State: %{public}d", pa_context_get_state(context));
464
465 switch (pa_context_get_state(context)) {
466 case PA_CONTEXT_READY:
467 AudioSystemManager::GetInstance()->RequestThreadPriority(gettid());
468 pa_threaded_mainloop_signal(mainLoop, 0);
469 break;
470 case PA_CONTEXT_TERMINATED:
471 case PA_CONTEXT_FAILED:
472 pa_threaded_mainloop_signal(mainLoop, 0);
473 break;
474
475 case PA_CONTEXT_UNCONNECTED:
476 case PA_CONTEXT_CONNECTING:
477 case PA_CONTEXT_AUTHORIZING:
478 case PA_CONTEXT_SETTING_NAME:
479 default:
480 break;
481 }
482 }
483
AudioServiceClient()484 AudioServiceClient::AudioServiceClient()
485 : AppExecFwk::EventHandler(AppExecFwk::EventRunner::Create("AudioServiceClientRunner"))
486 {
487 isMainLoopStarted_ = false;
488 isContextConnected_ = false;
489 isStreamConnected_ = false;
490 isInnerCapturerStream_ = false;
491
492 sinkDevices.clear();
493 sourceDevices.clear();
494 sinkInputs.clear();
495 sourceOutputs.clear();
496 clientInfo.clear();
497
498 mVolumeFactor = 1.0f;
499 mPowerVolumeFactor = 1.0f;
500 mStreamType = STREAM_MUSIC;
501 mAudioSystemMgr = nullptr;
502
503 streamIndex = 0;
504 sessionID_ = 0;
505 volumeChannels = STEREO;
506 streamInfoUpdated = false;
507 firstFrame_ = true;
508
509 renderRate = RENDER_RATE_NORMAL;
510 renderMode_ = RENDER_MODE_NORMAL;
511
512 captureMode_ = CAPTURE_MODE_NORMAL;
513
514 eAudioClientType = AUDIO_SERVICE_CLIENT_PLAYBACK;
515 effectSceneName = "SCENE_MUSIC";
516 effectMode = EFFECT_DEFAULT;
517
518 mFrameSize = 0;
519 mFrameMarkPosition = 0;
520 mMarkReached = false;
521 mFramePeriodNumber = 0;
522
523 mTotalBytesWritten = 0;
524 mFramePeriodWritten = 0;
525 mTotalBytesRead = 0;
526 mFramePeriodRead = 0;
527 mRenderPositionCb = nullptr;
528 mRenderPeriodPositionCb = nullptr;
529
530 mAudioRendererCallbacks = nullptr;
531 mAudioCapturerCallbacks = nullptr;
532 internalReadBuffer_ = nullptr;
533 mainLoop = nullptr;
534 paStream = nullptr;
535 context = nullptr;
536 api = nullptr;
537
538 internalRdBufIndex_ = 0;
539 internalRdBufLen_ = 0;
540 streamCmdStatus_ = 0;
541 streamDrainStatus_ = 0;
542 streamFlushStatus_ = 0;
543 underFlowCount = 0;
544
545 acache_.readIndex = 0;
546 acache_.writeIndex = 0;
547 acache_.isFull = false;
548 acache_.totalCacheSize = 0;
549 acache_.buffer = nullptr;
550
551 setBufferSize_ = 0;
552 PAStreamCorkSuccessCb = PAStreamStopSuccessCb;
553 rendererSampleRate = 0;
554
555 mPrivacyType = PRIVACY_TYPE_PUBLIC;
556 mStreamUsage = STREAM_USAGE_UNKNOWN;
557 }
558
ResetPAAudioClient()559 void AudioServiceClient::ResetPAAudioClient()
560 {
561 AUDIO_INFO_LOG("Enter ResetPAAudioClient");
562 lock_guard<mutex> lock(ctrlMutex_);
563 if (mainLoop && (isMainLoopStarted_ == true))
564 pa_threaded_mainloop_stop(mainLoop);
565
566 if (paStream) {
567 pa_stream_set_state_callback(paStream, nullptr, nullptr);
568 pa_stream_set_write_callback(paStream, nullptr, nullptr);
569 pa_stream_set_read_callback(paStream, nullptr, nullptr);
570 pa_stream_set_latency_update_callback(paStream, nullptr, nullptr);
571 pa_stream_set_underflow_callback(paStream, nullptr, nullptr);
572
573 if (isStreamConnected_ == true) {
574 pa_stream_disconnect(paStream);
575 pa_stream_unref(paStream);
576 isStreamConnected_ = false;
577 paStream = nullptr;
578 }
579 }
580
581 if (context) {
582 pa_context_set_state_callback(context, nullptr, nullptr);
583 if (isContextConnected_ == true) {
584 pa_threaded_mainloop_lock(mainLoop);
585 pa_context_disconnect(context);
586 pa_context_unref(context);
587 pa_threaded_mainloop_unlock(mainLoop);
588 isContextConnected_ = false;
589 context = nullptr;
590 }
591 }
592
593 if (mainLoop) {
594 pa_threaded_mainloop_free(mainLoop);
595 isMainLoopStarted_ = false;
596 mainLoop = nullptr;
597 }
598
599 for (auto &thread : mPositionCBThreads) {
600 if (thread && thread->joinable()) {
601 thread->join();
602 }
603 }
604
605 for (auto &thread : mPeriodPositionCBThreads) {
606 if (thread && thread->joinable()) {
607 thread->join();
608 }
609 }
610
611 if (appCookiePath.compare("")) {
612 remove(appCookiePath.c_str());
613 appCookiePath = "";
614 }
615
616 sinkDevices.clear();
617 sourceDevices.clear();
618 sinkInputs.clear();
619 sourceOutputs.clear();
620 clientInfo.clear();
621
622 mAudioRendererCallbacks = nullptr;
623 mAudioCapturerCallbacks = nullptr;
624 internalReadBuffer_ = nullptr;
625
626 api = nullptr;
627
628 internalRdBufIndex_ = 0;
629 internalRdBufLen_ = 0;
630 underFlowCount = 0;
631
632 acache_.buffer = nullptr;
633 acache_.readIndex = 0;
634 acache_.writeIndex = 0;
635 acache_.isFull = false;
636 acache_.totalCacheSize = 0;
637
638 setBufferSize_ = 0;
639 PAStreamCorkSuccessCb = nullptr;
640 }
641
~AudioServiceClient()642 AudioServiceClient::~AudioServiceClient()
643 {
644 lock_guard<mutex> lockdata(dataMutex_);
645 AUDIO_INFO_LOG("start ~AudioServiceClient");
646 ResetPAAudioClient();
647 StopTimer();
648 }
649
SetEnv()650 void AudioServiceClient::SetEnv()
651 {
652 AUDIO_INFO_LOG("SetEnv called");
653
654 int ret = setenv("HOME", PA_HOME_DIR, 1);
655 AUDIO_DEBUG_LOG("set env HOME: %{public}d", ret);
656
657 ret = setenv("PULSE_RUNTIME_PATH", PA_RUNTIME_DIR, 1);
658 AUDIO_DEBUG_LOG("set env PULSE_RUNTIME_DIR: %{public}d", ret);
659
660 ret = setenv("PULSE_STATE_PATH", PA_STATE_DIR, 1);
661 AUDIO_DEBUG_LOG("set env PULSE_STATE_PATH: %{public}d", ret);
662 }
663
SetApplicationCachePath(const std::string cachePath)664 void AudioServiceClient::SetApplicationCachePath(const std::string cachePath)
665 {
666 AUDIO_DEBUG_LOG("SetApplicationCachePath in");
667
668 char realPath[PATH_MAX] = {0x00};
669
670 if ((strlen(cachePath.c_str()) >= PATH_MAX) || (realpath(cachePath.c_str(), realPath) == nullptr)) {
671 AUDIO_ERR_LOG("Invalid cache path. err = %{public}d", errno);
672 return;
673 }
674
675 cachePath_ = realPath;
676 }
677
CheckRecordingCreate(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid)678 bool AudioServiceClient::CheckRecordingCreate(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid)
679 {
680 return AudioPolicyManager::GetInstance().CheckRecordingCreate(appTokenId, appFullTokenId, appUid);
681 }
682
CheckRecordingStateChange(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,AudioPermissionState state)683 bool AudioServiceClient::CheckRecordingStateChange(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
684 AudioPermissionState state)
685 {
686 return AudioPolicyManager::GetInstance().CheckRecordingStateChange(appTokenId, appFullTokenId, appUid, state);
687 }
688
Initialize(ASClientType eClientType)689 int32_t AudioServiceClient::Initialize(ASClientType eClientType)
690 {
691 int error = PA_ERR_INTERNAL;
692 eAudioClientType = eClientType;
693
694 mMarkReached = false;
695 mTotalBytesWritten = 0;
696 mFramePeriodWritten = 0;
697 mTotalBytesRead = 0;
698 mFramePeriodRead = 0;
699
700 SetEnv();
701
702 mAudioSystemMgr = AudioSystemManager::GetInstance();
703 lock_guard<mutex> lockdata(dataMutex_);
704 mainLoop = pa_threaded_mainloop_new();
705 if (mainLoop == nullptr)
706 return AUDIO_CLIENT_INIT_ERR;
707 api = pa_threaded_mainloop_get_api(mainLoop);
708 if (api == nullptr) {
709 ResetPAAudioClient();
710 return AUDIO_CLIENT_INIT_ERR;
711 }
712 stringstream ss;
713 string packageName = "";
714 ss << "app-pid<" << getpid() << ">-uid<" << getuid() << ">";
715 ss >> packageName;
716 AUDIO_DEBUG_LOG("AudioServiceClient:Initialize [%{public}s]", packageName.c_str());
717 context = pa_context_new(api, packageName.c_str());
718 if (context == nullptr) {
719 ResetPAAudioClient();
720 return AUDIO_CLIENT_INIT_ERR;
721 }
722
723 pa_context_set_state_callback(context, PAContextStateCb, mainLoop);
724
725 if (!cachePath_.empty()) {
726 AUDIO_DEBUG_LOG("abilityContext not null");
727 int32_t size = 0;
728
729 const char *cookieData = mAudioSystemMgr->RetrieveCookie(size);
730 if (size <= 0) {
731 AUDIO_ERR_LOG("Error retrieving cookie");
732 return AUDIO_CLIENT_INIT_ERR;
733 }
734
735 appCookiePath = cachePath_ + PATH_SEPARATOR + COOKIE_FILE_NAME;
736
737 ofstream cookieCache(appCookiePath.c_str(), std::ofstream::binary);
738 cookieCache.write(cookieData, size);
739 cookieCache.flush();
740 cookieCache.close();
741
742 pa_context_load_cookie_from_file(context, appCookiePath.c_str());
743 }
744
745 if (pa_context_connect(context, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
746 error = pa_context_errno(context);
747 AUDIO_ERR_LOG("context connect error: %{public}s", pa_strerror(error));
748 ResetPAAudioClient();
749 return AUDIO_CLIENT_INIT_ERR;
750 }
751
752 isContextConnected_ = true;
753 pa_threaded_mainloop_lock(mainLoop);
754
755 if (pa_threaded_mainloop_start(mainLoop) < 0) {
756 pa_threaded_mainloop_unlock(mainLoop);
757 ResetPAAudioClient();
758 return AUDIO_CLIENT_INIT_ERR;
759 }
760
761 isMainLoopStarted_ = true;
762 while (true) {
763 pa_context_state_t state = pa_context_get_state(context);
764 if (state == PA_CONTEXT_READY)
765 break;
766
767 if (!PA_CONTEXT_IS_GOOD(state)) {
768 error = pa_context_errno(context);
769 AUDIO_ERR_LOG("context bad state error: %{public}s", pa_strerror(error));
770 pa_threaded_mainloop_unlock(mainLoop);
771 ResetPAAudioClient();
772 return AUDIO_CLIENT_INIT_ERR;
773 }
774
775 StartTimer(INIT_TIMEOUT_IN_SEC);
776 pa_threaded_mainloop_wait(mainLoop);
777 StopTimer();
778 if (IsTimeOut()) {
779 AUDIO_ERR_LOG("Initialize timeout");
780 pa_threaded_mainloop_unlock(mainLoop);
781 return AUDIO_CLIENT_INIT_ERR;
782 }
783 }
784
785 if (appCookiePath.compare("")) {
786 remove(appCookiePath.c_str());
787 appCookiePath = "";
788 }
789
790 pa_threaded_mainloop_unlock(mainLoop);
791 return AUDIO_CLIENT_SUCCESS;
792 }
793
GetStreamName(AudioStreamType audioType)794 const std::string AudioServiceClient::GetStreamName(AudioStreamType audioType)
795 {
796 std::string name = "unknown";
797 if (STREAM_TYPE_ENUM_STRING_MAP.find(audioType) != STREAM_TYPE_ENUM_STRING_MAP.end()) {
798 name = STREAM_TYPE_ENUM_STRING_MAP.at(audioType);
799 } else {
800 AUDIO_ERR_LOG("GetStreamName: Invalid stream type [%{public}d], return unknown", audioType);
801 }
802 const std::string streamName = name;
803 return streamName;
804 }
805
GetDeviceNameForConnect()806 std::pair<const int32_t, const std::string> AudioServiceClient::GetDeviceNameForConnect()
807 {
808 string deviceName;
809 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
810 const std::string selectDevice = AudioSystemManager::GetInstance()->GetSelectedDeviceInfo(clientUid_,
811 clientPid_,
812 mStreamType);
813 deviceName = (selectDevice.empty() ? "" : selectDevice);
814 return {AUDIO_CLIENT_SUCCESS, deviceName};
815 }
816
817 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
818 if (isInnerCapturerStream_) {
819 return {AUDIO_CLIENT_SUCCESS, INNER_CAPTURER_SOURCE};
820 }
821
822 if (isWakeupCapturerStream_) {
823 int32_t no = AudioPolicyManager::GetInstance().SetWakeUpAudioCapturer({});
824 if (no < 0) {
825 AUDIO_ERR_LOG("SetWakeUpAudioCapturer Error! ErrorCode: %{public}d", no);
826 return {no, ""};
827 }
828
829 if (no >= WAKEUP_LIMIT) {
830 AUDIO_ERR_LOG("SetWakeUpAudioCapturer Error! client no>=WAKEUP_LIMIT no=: %{public}d", no);
831 return {AUDIO_CLIENT_CREATE_STREAM_ERR, ""};
832 }
833
834 if (no < WAKEUP_LIMIT) {
835 deviceName = WAKEUP_NAMES[no];
836 return {AUDIO_CLIENT_SUCCESS, deviceName};
837 }
838 }
839 }
840 return {AUDIO_CLIENT_SUCCESS, deviceName};
841 }
842
ConnectStreamToPA()843 int32_t AudioServiceClient::ConnectStreamToPA()
844 {
845 AUDIO_DEBUG_LOG("Enter AudioServiceClient::ConnectStreamToPA");
846 int error, result;
847
848 if (CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_ERR) < 0) {
849 return AUDIO_CLIENT_ERR;
850 }
851 int32_t latency_in_msec = AudioSystemManager::GetInstance()->GetAudioLatencyFromXml();
852 if (latency_in_msec < 0) {
853 AUDIO_ERR_LOG("Get audio latency failed");
854 return AUDIO_CLIENT_CREATE_STREAM_ERR;
855 }
856 sinkLatencyInMsec_ = AudioSystemManager::GetInstance()->GetSinkLatencyFromXml();
857
858 auto [errorCode, deviceNameS] = GetDeviceNameForConnect();
859 if (errorCode != AUDIO_CLIENT_SUCCESS) {
860 return errorCode;
861 }
862
863 const char* deviceName = deviceNameS.empty() ? nullptr : deviceNameS.c_str();
864
865 pa_threaded_mainloop_lock(mainLoop);
866
867 pa_buffer_attr bufferAttr;
868 bufferAttr.fragsize = static_cast<uint32_t>(-1);
869 if (latency_in_msec <= LATENCY_THRESHOLD) {
870 bufferAttr.prebuf = AlignToAudioFrameSize(pa_usec_to_bytes(latency_in_msec * PA_USEC_PER_MSEC, &sampleSpec),
871 sampleSpec);
872 bufferAttr.maxlength = NO_OF_PREBUF_TIMES * bufferAttr.prebuf;
873 bufferAttr.tlength = static_cast<uint32_t>(-1);
874 } else {
875 bufferAttr.prebuf = pa_usec_to_bytes(latency_in_msec * PA_USEC_PER_MSEC, &sampleSpec);
876 bufferAttr.maxlength = pa_usec_to_bytes(latency_in_msec * PA_USEC_PER_MSEC * MAX_LENGTH_FACTOR, &sampleSpec);
877 bufferAttr.tlength = pa_usec_to_bytes(latency_in_msec * PA_USEC_PER_MSEC * T_LENGTH_FACTOR, &sampleSpec);
878 }
879 bufferAttr.minreq = bufferAttr.prebuf;
880
881 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
882 result = pa_stream_connect_playback(paStream, deviceName, &bufferAttr,
883 (pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_START_CORKED |
884 PA_STREAM_VARIABLE_RATE), nullptr, nullptr);
885 preBuf_ = make_unique<uint8_t[]>(bufferAttr.maxlength);
886 if (preBuf_ == nullptr) {
887 AUDIO_ERR_LOG("Allocate memory for buffer failed.");
888 pa_threaded_mainloop_unlock(mainLoop);
889 return AUDIO_CLIENT_INIT_ERR;
890 }
891 if (memset_s(preBuf_.get(), bufferAttr.maxlength, 0, bufferAttr.maxlength) != 0) {
892 AUDIO_ERR_LOG("memset_s for buffer failed.");
893 pa_threaded_mainloop_unlock(mainLoop);
894 return AUDIO_CLIENT_INIT_ERR;
895 }
896 } else {
897 AUDIO_DEBUG_LOG("pa_stream_connect_record connect to:%{public}s",
898 deviceName ? deviceName : "nullptr");
899 result = pa_stream_connect_record(paStream, deviceName, nullptr,
900 (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING
901 | PA_STREAM_ADJUST_LATENCY
902 | PA_STREAM_START_CORKED
903 | PA_STREAM_AUTO_TIMING_UPDATE));
904 }
905 if (result < 0) {
906 error = pa_context_errno(context);
907 AUDIO_ERR_LOG("connection to stream error: %{public}d", error);
908 pa_threaded_mainloop_unlock(mainLoop);
909 ResetPAAudioClient();
910 return AUDIO_CLIENT_CREATE_STREAM_ERR;
911 }
912
913 while (true) {
914 pa_stream_state_t state = pa_stream_get_state(paStream);
915 if (state == PA_STREAM_READY)
916 break;
917
918 if (!PA_STREAM_IS_GOOD(state)) {
919 error = pa_context_errno(context);
920 pa_threaded_mainloop_unlock(mainLoop);
921 AUDIO_ERR_LOG("connection to stream error: %{public}d", error);
922 ResetPAAudioClient();
923 return AUDIO_CLIENT_CREATE_STREAM_ERR;
924 }
925
926 pa_threaded_mainloop_wait(mainLoop);
927 }
928
929 isStreamConnected_ = true;
930 pa_threaded_mainloop_unlock(mainLoop);
931 return AUDIO_CLIENT_SUCCESS;
932 }
933
InitializeAudioCache()934 int32_t AudioServiceClient::InitializeAudioCache()
935 {
936 AUDIO_DEBUG_LOG("Initializing internal audio cache");
937
938 if (CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_PA_ERR) < 0) {
939 return AUDIO_CLIENT_PA_ERR;
940 }
941
942 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
943 if (bufferAttr == nullptr) {
944 AUDIO_ERR_LOG("pa stream get buffer attribute returned null");
945 return AUDIO_CLIENT_INIT_ERR;
946 }
947
948 acache_.buffer = make_unique<uint8_t[]>(bufferAttr->minreq);
949 if (acache_.buffer == nullptr) {
950 AUDIO_ERR_LOG("Allocate memory for buffer failed");
951 return AUDIO_CLIENT_INIT_ERR;
952 }
953
954 acache_.readIndex = 0;
955 acache_.writeIndex = 0;
956 acache_.totalCacheSize = bufferAttr->minreq;
957 acache_.isFull = false;
958 return AUDIO_CLIENT_SUCCESS;
959 }
960
CreateStream(AudioStreamParams audioParams,AudioStreamType audioType)961 int32_t AudioServiceClient::CreateStream(AudioStreamParams audioParams, AudioStreamType audioType)
962 {
963 AUDIO_INFO_LOG("Enter AudioServiceClient::CreateStream");
964 int error;
965 lock_guard<mutex> lockdata(dataMutex_);
966 if (CheckReturnIfinvalid(mainLoop && context, AUDIO_CLIENT_ERR) < 0) {
967 return AUDIO_CLIENT_ERR;
968 }
969
970 if (eAudioClientType == AUDIO_SERVICE_CLIENT_CONTROLLER) {
971 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
972 }
973 pa_threaded_mainloop_lock(mainLoop);
974 mStreamType = audioType;
975 const std::string streamName = GetStreamName(audioType);
976
977 auto timenow = chrono::system_clock::to_time_t(chrono::system_clock::now());
978 const std::string streamStartTime = ctime(&timenow);
979
980 sampleSpec = ConvertToPAAudioParams(audioParams);
981 mFrameSize = pa_frame_size(&sampleSpec);
982
983 pa_proplist *propList = pa_proplist_new();
984 if (propList == nullptr) {
985 AUDIO_ERR_LOG("pa_proplist_new failed");
986 ResetPAAudioClient();
987 pa_threaded_mainloop_unlock(mainLoop);
988 return AUDIO_CLIENT_CREATE_STREAM_ERR;
989 }
990
991 // for remote audio device router filter.
992 pa_proplist_sets(propList, "stream.client.uid", std::to_string(clientUid_).c_str());
993 pa_proplist_sets(propList, "stream.client.pid", std::to_string(clientPid_).c_str());
994
995 pa_proplist_sets(propList, "stream.type", streamName.c_str());
996 pa_proplist_sets(propList, "stream.volumeFactor", std::to_string(mVolumeFactor).c_str());
997 pa_proplist_sets(propList, "stream.powerVolumeFactor", std::to_string(mPowerVolumeFactor).c_str());
998 sessionID_ = pa_context_get_index(context);
999 pa_proplist_sets(propList, "stream.sessionID", std::to_string(sessionID_).c_str());
1000 pa_proplist_sets(propList, "stream.startTime", streamStartTime.c_str());
1001
1002 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1003 pa_proplist_sets(propList, "stream.isInnerCapturer", std::to_string(isInnerCapturerStream_).c_str());
1004 pa_proplist_sets(propList, "stream.isWakeupCapturer", std::to_string(isWakeupCapturerStream_).c_str());
1005 } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1006 pa_proplist_sets(propList, "stream.privacyType", std::to_string(mPrivacyType).c_str());
1007 pa_proplist_sets(propList, "stream.usage", std::to_string(mStreamUsage).c_str());
1008 }
1009
1010 AUDIO_DEBUG_LOG("Creating stream of channels %{public}d", audioParams.channels);
1011 pa_channel_map map;
1012 if (audioParams.channels > CHANNEL_6) {
1013 pa_channel_map_init(&map);
1014 map.channels = audioParams.channels;
1015 switch (audioParams.channels) {
1016 case CHANNEL_8:
1017 map.map[CHANNEL8_IDX] = PA_CHANNEL_POSITION_AUX1;
1018 [[fallthrough]];
1019 case CHANNEL_7:
1020 map.map[CHANNEL1_IDX] = PA_CHANNEL_POSITION_FRONT_LEFT;
1021 map.map[CHANNEL2_IDX] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
1022 map.map[CHANNEL3_IDX] = PA_CHANNEL_POSITION_FRONT_CENTER;
1023 map.map[CHANNEL4_IDX] = PA_CHANNEL_POSITION_FRONT_RIGHT;
1024 map.map[CHANNEL5_IDX] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
1025 map.map[CHANNEL6_IDX] = PA_CHANNEL_POSITION_REAR_CENTER;
1026 map.map[CHANNEL7_IDX] = PA_CHANNEL_POSITION_AUX0;
1027 break;
1028 default:
1029 AUDIO_ERR_LOG("Invalid channel count");
1030 pa_threaded_mainloop_unlock(mainLoop);
1031 return AUDIO_CLIENT_CREATE_STREAM_ERR;
1032 }
1033
1034 paStream = pa_stream_new_with_proplist(context, streamName.c_str(), &sampleSpec, &map, propList);
1035 } else {
1036 paStream = pa_stream_new_with_proplist(context, streamName.c_str(), &sampleSpec, nullptr, propList);
1037 }
1038
1039 if (!paStream) {
1040 error = pa_context_errno(context);
1041 AUDIO_ERR_LOG("create stream Failed, error: %{public}d", error);
1042 pa_proplist_free(propList);
1043 pa_threaded_mainloop_unlock(mainLoop);
1044 ResetPAAudioClient();
1045 AUDIO_ERR_LOG("pa_stream_new_with_proplist failed, error: %{public}d", error);
1046 return AUDIO_CLIENT_CREATE_STREAM_ERR;
1047 }
1048
1049 pa_proplist_free(propList);
1050 pa_stream_set_state_callback(paStream, PAStreamStateCb, (void *)this);
1051 pa_stream_set_moved_callback(paStream, PAStreamMovedCb, (void *)this); // used to notify sink/source moved
1052 pa_stream_set_write_callback(paStream, PAStreamWriteCb, (void *)this);
1053 pa_stream_set_read_callback(paStream, PAStreamReadCb, (void *)this);
1054 pa_stream_set_latency_update_callback(paStream, PAStreamLatencyUpdateCb, mainLoop);
1055 pa_stream_set_underflow_callback(paStream, PAStreamUnderFlowCb, (void *)this);
1056
1057 pa_threaded_mainloop_unlock(mainLoop);
1058
1059 error = ConnectStreamToPA();
1060 streamInfoUpdated = false;
1061 if (error < 0) {
1062 AUDIO_ERR_LOG("Create Stream Failed");
1063 ResetPAAudioClient();
1064 return AUDIO_CLIENT_CREATE_STREAM_ERR;
1065 }
1066
1067 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1068 error = InitializeAudioCache();
1069 if (error < 0) {
1070 AUDIO_ERR_LOG("Initialize audio cache failed");
1071 ResetPAAudioClient();
1072 return AUDIO_CLIENT_CREATE_STREAM_ERR;
1073 }
1074
1075 if (SetStreamRenderRate(renderRate) != AUDIO_CLIENT_SUCCESS) {
1076 AUDIO_ERR_LOG("Set render rate failed");
1077 }
1078
1079 effectSceneName = IAudioStream::GetEffectSceneName(audioType);
1080 if (SetStreamAudioEffectMode(effectMode) != AUDIO_CLIENT_SUCCESS) {
1081 AUDIO_ERR_LOG("Set audio effect mode failed");
1082 }
1083 }
1084
1085 state_ = PREPARED;
1086 WriteStateChangedSysEvents();
1087 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1088 if (streamCb != nullptr) {
1089 streamCb->OnStateChange(state_);
1090 }
1091 return AUDIO_CLIENT_SUCCESS;
1092 }
1093
GetUnderflowCount()1094 uint32_t AudioServiceClient::GetUnderflowCount()
1095 {
1096 return underFlowCount;
1097 }
1098
GetSessionID(uint32_t & sessionID) const1099 int32_t AudioServiceClient::GetSessionID(uint32_t &sessionID) const
1100 {
1101 AUDIO_DEBUG_LOG("GetSessionID sessionID: %{public}d", sessionID_);
1102 if (sessionID_ == PA_INVALID_INDEX || sessionID_ == 0) {
1103 return AUDIO_CLIENT_ERR;
1104 }
1105 sessionID = sessionID_;
1106 return AUDIO_CLIENT_SUCCESS;
1107 }
1108
StartStream(StateChangeCmdType cmdType)1109 int32_t AudioServiceClient::StartStream(StateChangeCmdType cmdType)
1110 {
1111 AUDIO_INFO_LOG("Enter AudioServiceClient::StartStream");
1112 int error;
1113 lock_guard<mutex> lockdata(dataMutex_);
1114 unique_lock<mutex> stoppinglock(stoppingMutex_);
1115 dataCv_.wait(stoppinglock, [this] {return state_ != STOPPING;});
1116 stoppinglock.unlock();
1117 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1118 return AUDIO_CLIENT_PA_ERR;
1119 }
1120 pa_operation *operation = nullptr;
1121
1122 pa_threaded_mainloop_lock(mainLoop);
1123
1124 pa_stream_state_t state = pa_stream_get_state(paStream);
1125 if (state != PA_STREAM_READY) {
1126 error = pa_context_errno(context);
1127 pa_threaded_mainloop_unlock(mainLoop);
1128 AUDIO_ERR_LOG("Stream Start Failed, error: %{public}d", error);
1129 ResetPAAudioClient();
1130 return AUDIO_CLIENT_START_STREAM_ERR;
1131 }
1132
1133 streamCmdStatus_ = 0;
1134 stateChangeCmdType_ = cmdType;
1135 operation = pa_stream_cork(paStream, 0, PAStreamStartSuccessCb, (void *)this);
1136
1137 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1138 pa_threaded_mainloop_wait(mainLoop);
1139 }
1140 pa_operation_unref(operation);
1141 pa_threaded_mainloop_unlock(mainLoop);
1142
1143 if (!streamCmdStatus_) {
1144 AUDIO_ERR_LOG("Stream Start Failed");
1145 ResetPAAudioClient();
1146 return AUDIO_CLIENT_START_STREAM_ERR;
1147 } else {
1148 return AUDIO_CLIENT_SUCCESS;
1149 }
1150 }
1151
PauseStream(StateChangeCmdType cmdType)1152 int32_t AudioServiceClient::PauseStream(StateChangeCmdType cmdType)
1153 {
1154 AUDIO_INFO_LOG("Enter AudioServiceClient::PauseStream");
1155 lock_guard<mutex> lockdata(dataMutex_);
1156 lock_guard<mutex> lockctrl(ctrlMutex_);
1157 PAStreamCorkSuccessCb = PAStreamPauseSuccessCb;
1158 stateChangeCmdType_ = cmdType;
1159
1160 int32_t ret = CorkStream();
1161 if (ret) {
1162 return ret;
1163 }
1164
1165 if (!streamCmdStatus_) {
1166 AUDIO_ERR_LOG("Stream Pause Failed");
1167 return AUDIO_CLIENT_ERR;
1168 } else {
1169 return AUDIO_CLIENT_SUCCESS;
1170 }
1171 }
1172
StopStream()1173 int32_t AudioServiceClient::StopStream()
1174 {
1175 AUDIO_INFO_LOG("Enter AudioServiceClient::StopStream");
1176 lock_guard<mutex> lockdata(dataMutex_);
1177 lock_guard<mutex> lockctrl(ctrlMutex_);
1178 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1179 PAStreamCorkSuccessCb = PAStreamAsyncStopSuccessCb;
1180 state_ = STOPPING;
1181 DrainAudioCache();
1182
1183 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1184 return AUDIO_CLIENT_PA_ERR;
1185 }
1186
1187 pa_threaded_mainloop_lock(mainLoop);
1188
1189 streamDrainStatus_ = 0;
1190 pa_operation *operation = pa_stream_drain(paStream, PAStreamDrainInStopCb, (void *)this);
1191
1192 if (operation == nullptr) {
1193 pa_threaded_mainloop_unlock(mainLoop);
1194 AUDIO_ERR_LOG("pa_stream_drain operation is null");
1195 return AUDIO_CLIENT_ERR;
1196 }
1197
1198 pa_operation_unref(operation);
1199 pa_threaded_mainloop_unlock(mainLoop);
1200 return AUDIO_CLIENT_SUCCESS;
1201 } else {
1202 PAStreamCorkSuccessCb = PAStreamStopSuccessCb;
1203 int32_t ret = CorkStream();
1204 if (ret) {
1205 return ret;
1206 }
1207
1208 if (!streamCmdStatus_) {
1209 AUDIO_ERR_LOG("Stream Stop Failed");
1210 return AUDIO_CLIENT_ERR;
1211 } else {
1212 if (internalRdBufLen_) {
1213 (void)pa_stream_drop(paStream);
1214 internalReadBuffer_ = nullptr;
1215 internalRdBufLen_ = 0;
1216 internalRdBufIndex_ = 0;
1217 }
1218 return AUDIO_CLIENT_SUCCESS;
1219 }
1220 }
1221 }
1222
CorkStream()1223 int32_t AudioServiceClient::CorkStream()
1224 {
1225 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1226 return AUDIO_CLIENT_PA_ERR;
1227 }
1228
1229 pa_operation *operation = nullptr;
1230
1231 pa_threaded_mainloop_lock(mainLoop);
1232 pa_stream_state_t state = pa_stream_get_state(paStream);
1233 if (state != PA_STREAM_READY) {
1234 int32_t error = pa_context_errno(context);
1235 pa_threaded_mainloop_unlock(mainLoop);
1236 AUDIO_ERR_LOG("Stream Stop Failed : %{public}d", error);
1237 return AUDIO_CLIENT_ERR;
1238 }
1239
1240 streamCmdStatus_ = 0;
1241 operation = pa_stream_cork(paStream, 1, PAStreamCorkSuccessCb, (void *)this);
1242
1243 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1244 pa_threaded_mainloop_wait(mainLoop);
1245 }
1246 pa_operation_unref(operation);
1247 pa_threaded_mainloop_unlock(mainLoop);
1248
1249 return AUDIO_CLIENT_SUCCESS;
1250 }
1251
FlushStream()1252 int32_t AudioServiceClient::FlushStream()
1253 {
1254 AUDIO_INFO_LOG("Enter AudioServiceClient::FlushStream");
1255 lock_guard<mutex> lock(dataMutex_);
1256 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1257 return AUDIO_CLIENT_PA_ERR;
1258 }
1259
1260 pa_operation *operation = nullptr;
1261 pa_threaded_mainloop_lock(mainLoop);
1262
1263 pa_stream_state_t state = pa_stream_get_state(paStream);
1264 if (state != PA_STREAM_READY) {
1265 int error = pa_context_errno(context);
1266 pa_threaded_mainloop_unlock(mainLoop);
1267 AUDIO_ERR_LOG("Stream Flush Failed, error: %{public}d", error);
1268 return AUDIO_CLIENT_ERR;
1269 }
1270
1271 streamFlushStatus_ = 0;
1272 operation = pa_stream_flush(paStream, PAStreamFlushSuccessCb, (void *)this);
1273 if (operation == nullptr) {
1274 AUDIO_ERR_LOG("Stream Flush Operation Failed");
1275 pa_threaded_mainloop_unlock(mainLoop);
1276 return AUDIO_CLIENT_ERR;
1277 }
1278
1279 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1280 pa_threaded_mainloop_wait(mainLoop);
1281 }
1282 pa_operation_unref(operation);
1283 pa_threaded_mainloop_unlock(mainLoop);
1284
1285 if (!streamFlushStatus_) {
1286 AUDIO_ERR_LOG("Stream Flush Failed");
1287 return AUDIO_CLIENT_ERR;
1288 } else {
1289 acache_.readIndex = 0;
1290 acache_.writeIndex = 0;
1291 acache_.isFull = false;
1292 return AUDIO_CLIENT_SUCCESS;
1293 }
1294 }
1295
DrainStream()1296 int32_t AudioServiceClient::DrainStream()
1297 {
1298 AUDIO_INFO_LOG("Enter AudioServiceClient::DrainStream");
1299 int32_t error;
1300
1301 if (eAudioClientType != AUDIO_SERVICE_CLIENT_PLAYBACK) {
1302 AUDIO_ERR_LOG("Drain is not supported");
1303 return AUDIO_CLIENT_ERR;
1304 }
1305
1306 lock_guard<mutex> lock(dataMutex_);
1307
1308 error = DrainAudioCache();
1309 if (error != AUDIO_CLIENT_SUCCESS) {
1310 AUDIO_ERR_LOG("Audio cache drain failed");
1311 return AUDIO_CLIENT_ERR;
1312 }
1313 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1314 return AUDIO_CLIENT_PA_ERR;
1315 }
1316
1317 pa_operation *operation = nullptr;
1318
1319 pa_threaded_mainloop_lock(mainLoop);
1320
1321 pa_stream_state_t state = pa_stream_get_state(paStream);
1322 if (state != PA_STREAM_READY) {
1323 error = pa_context_errno(context);
1324 pa_threaded_mainloop_unlock(mainLoop);
1325 AUDIO_ERR_LOG("Stream Drain Failed");
1326 return AUDIO_CLIENT_ERR;
1327 }
1328
1329 streamDrainStatus_ = 0;
1330 operation = pa_stream_drain(paStream, PAStreamDrainSuccessCb, (void *)this);
1331
1332 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1333 StartTimer(DRAIN_TIMEOUT_IN_SEC);
1334 pa_threaded_mainloop_wait(mainLoop);
1335 StopTimer();
1336 if (IsTimeOut()) {
1337 AUDIO_ERR_LOG("Drain timeout");
1338 return AUDIO_CLIENT_ERR;
1339 }
1340 }
1341 pa_operation_unref(operation);
1342 pa_threaded_mainloop_unlock(mainLoop);
1343
1344 if (!streamDrainStatus_) {
1345 AUDIO_ERR_LOG("Stream Drain Failed");
1346 return AUDIO_CLIENT_ERR;
1347 } else {
1348 return AUDIO_CLIENT_SUCCESS;
1349 }
1350 }
1351
PaWriteStream(const uint8_t * buffer,size_t & length)1352 int32_t AudioServiceClient::PaWriteStream(const uint8_t *buffer, size_t &length)
1353 {
1354 int error = 0;
1355 if (firstFrame_) {
1356 AudioSystemManager::GetInstance()->RequestThreadPriority(gettid());
1357 firstFrame_ = false;
1358 }
1359
1360 while (length > 0) {
1361 size_t writableSize;
1362 size_t origWritableSize = 0;
1363
1364 Trace trace1("PaWriteStream Wait");
1365 while (!(writableSize = pa_stream_writable_size(paStream))) {
1366 AUDIO_DEBUG_LOG("PaWriteStream: wait");
1367 StartTimer(WRITE_TIMEOUT_IN_SEC);
1368 pa_threaded_mainloop_wait(mainLoop);
1369 StopTimer();
1370 if (IsTimeOut()) {
1371 AUDIO_ERR_LOG("Write timeout");
1372 error = AUDIO_CLIENT_WRITE_STREAM_ERR;
1373 return error;
1374 }
1375 }
1376
1377 AUDIO_DEBUG_LOG("Write stream: writable size = %{public}zu, length = %{public}zu", writableSize, length);
1378 origWritableSize = writableSize;
1379 if (writableSize > length) {
1380 writableSize = length;
1381 }
1382
1383 writableSize = AlignToAudioFrameSize(writableSize, sampleSpec);
1384 if (writableSize == 0) {
1385 AUDIO_ERR_LOG("Align to frame size failed");
1386 error = AUDIO_CLIENT_WRITE_STREAM_ERR;
1387 break;
1388 }
1389
1390 Trace trace2("PaWriteStream Write:" + std::to_string(writableSize) + "/" + std::to_string(origWritableSize));
1391 error = pa_stream_write(paStream, (void *)buffer, writableSize, nullptr, 0LL,
1392 PA_SEEK_RELATIVE);
1393 if (error < 0) {
1394 AUDIO_ERR_LOG("Write stream failed");
1395 error = AUDIO_CLIENT_WRITE_STREAM_ERR;
1396 break;
1397 }
1398
1399 AUDIO_DEBUG_LOG("Writable size: %{public}zu, bytes to write: %{public}zu, return val: %{public}d",
1400 writableSize, length, error);
1401 buffer = buffer + writableSize;
1402 length -= writableSize;
1403
1404 HandleRenderPositionCallbacks(writableSize);
1405 }
1406
1407 return error;
1408 }
1409
HandleRenderPositionCallbacks(size_t bytesWritten)1410 void AudioServiceClient::HandleRenderPositionCallbacks(size_t bytesWritten)
1411 {
1412 mTotalBytesWritten += bytesWritten;
1413 if (mFrameSize == 0) {
1414 AUDIO_ERR_LOG("HandleRenderPositionCallbacks: capturePeriodPositionCb not set");
1415 return;
1416 }
1417
1418 uint64_t writtenFrameNumber = mTotalBytesWritten / mFrameSize;
1419 AUDIO_DEBUG_LOG("frame size: %{public}d", mFrameSize);
1420
1421 {
1422 std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
1423 if (!mMarkReached) {
1424 AUDIO_DEBUG_LOG("frame mark position: %{public}" PRIu64 ", Total frames written: %{public}" PRIu64,
1425 static_cast<uint64_t>(mFrameMarkPosition), static_cast<uint64_t>(writtenFrameNumber));
1426 if (writtenFrameNumber >= mFrameMarkPosition) {
1427 AUDIO_DEBUG_LOG("audio service client OnMarkReached");
1428 SendRenderMarkReachedRequestEvent(mFrameMarkPosition);
1429 mMarkReached = true;
1430 }
1431 }
1432 }
1433
1434 {
1435 std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
1436 mFramePeriodWritten += (bytesWritten / mFrameSize);
1437 AUDIO_DEBUG_LOG("frame period number: %{public}" PRIu64 ", Total frames written: %{public}" PRIu64,
1438 static_cast<uint64_t>(mFramePeriodNumber), static_cast<uint64_t>(writtenFrameNumber));
1439 if (mFramePeriodWritten >= mFramePeriodNumber) {
1440 mFramePeriodWritten %= mFramePeriodNumber;
1441 AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRIu64,
1442 static_cast<uint64_t>(mFramePeriodWritten));
1443 SendRenderPeriodReachedRequestEvent(mFramePeriodNumber);
1444 }
1445 }
1446 }
1447
DrainAudioCache()1448 int32_t AudioServiceClient::DrainAudioCache()
1449 {
1450 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1451 return AUDIO_CLIENT_PA_ERR;
1452 }
1453
1454 pa_threaded_mainloop_lock(mainLoop);
1455
1456 int32_t error = 0;
1457 if (acache_.buffer == nullptr) {
1458 AUDIO_ERR_LOG("Drain cache failed");
1459 pa_threaded_mainloop_unlock(mainLoop);
1460 return AUDIO_CLIENT_ERR;
1461 }
1462
1463 size_t length = acache_.writeIndex - acache_.readIndex;
1464 const uint8_t *buffer = acache_.buffer.get();
1465
1466 error = PaWriteStream(buffer, length);
1467
1468 acache_.readIndex = 0;
1469 acache_.writeIndex = 0;
1470
1471 pa_threaded_mainloop_unlock(mainLoop);
1472 return error;
1473 }
1474
WriteToAudioCache(const StreamBuffer & stream)1475 size_t AudioServiceClient::WriteToAudioCache(const StreamBuffer &stream)
1476 {
1477 if (stream.buffer == nullptr) {
1478 return 0;
1479 }
1480
1481 const uint8_t *inputBuffer = stream.buffer;
1482 uint8_t *cacheBuffer = acache_.buffer.get() + acache_.writeIndex;
1483
1484 size_t inputLen = stream.bufferLen;
1485
1486 while (inputLen > 0) {
1487 size_t writableSize = acache_.totalCacheSize - acache_.writeIndex;
1488
1489 if (writableSize > inputLen) {
1490 writableSize = inputLen;
1491 }
1492
1493 if (writableSize == 0) {
1494 break;
1495 }
1496
1497 if (memcpy_s(cacheBuffer, acache_.totalCacheSize, inputBuffer, writableSize)) {
1498 break;
1499 }
1500
1501 inputBuffer = inputBuffer + writableSize;
1502 cacheBuffer = cacheBuffer + writableSize;
1503 inputLen -= writableSize;
1504 acache_.writeIndex += writableSize;
1505 }
1506
1507 if ((acache_.writeIndex - acache_.readIndex) == acache_.totalCacheSize) {
1508 acache_.isFull = true;
1509 }
1510
1511 return (stream.bufferLen - inputLen);
1512 }
1513
WriteStreamInCb(const StreamBuffer & stream,int32_t & pError)1514 size_t AudioServiceClient::WriteStreamInCb(const StreamBuffer &stream, int32_t &pError)
1515 {
1516 lock_guard<mutex> lock(dataMutex_);
1517 int error = 0;
1518 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, 0, pError) < 0) {
1519 return 0;
1520 }
1521
1522 pa_threaded_mainloop_lock(mainLoop);
1523
1524 const uint8_t *buffer = stream.buffer;
1525 size_t length = stream.bufferLen;
1526 error = PaWriteStream(buffer, length);
1527 pa_threaded_mainloop_unlock(mainLoop);
1528 pError = error;
1529 return (stream.bufferLen - length);
1530 }
1531
WriteStream(const StreamBuffer & stream,int32_t & pError)1532 size_t AudioServiceClient::WriteStream(const StreamBuffer &stream, int32_t &pError)
1533 {
1534 lock_guard<mutex> lock(dataMutex_);
1535 int error = 0;
1536 size_t cachedLen = WriteToAudioCache(stream);
1537
1538 if (!acache_.isFull) {
1539 pError = error;
1540 return cachedLen;
1541 }
1542 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, 0, pError) < 0) {
1543 return 0;
1544 }
1545 pa_threaded_mainloop_lock(mainLoop);
1546
1547 if (acache_.buffer == nullptr) {
1548 AUDIO_ERR_LOG("Buffer is null");
1549 pa_threaded_mainloop_unlock(mainLoop);
1550 pError = AUDIO_CLIENT_WRITE_STREAM_ERR;
1551 return cachedLen;
1552 }
1553
1554 const uint8_t *buffer = acache_.buffer.get();
1555 size_t length = acache_.totalCacheSize;
1556
1557 error = PaWriteStream(buffer, length);
1558 acache_.readIndex += acache_.totalCacheSize;
1559 acache_.isFull = false;
1560
1561 if (!error && (length >= 0) && !acache_.isFull) {
1562 uint8_t *cacheBuffer = acache_.buffer.get();
1563 uint32_t offset = acache_.readIndex;
1564 if (acache_.writeIndex > acache_.readIndex) {
1565 uint32_t size = (acache_.writeIndex - acache_.readIndex);
1566 if (memcpy_s(cacheBuffer, acache_.totalCacheSize, cacheBuffer + offset, size)) {
1567 AUDIO_ERR_LOG("Update cache failed");
1568 pa_threaded_mainloop_unlock(mainLoop);
1569 pError = AUDIO_CLIENT_WRITE_STREAM_ERR;
1570 return cachedLen;
1571 }
1572 AUDIO_INFO_LOG("rearranging the audio cache");
1573 }
1574 acache_.readIndex = 0;
1575 acache_.writeIndex = 0;
1576
1577 if (cachedLen < stream.bufferLen) {
1578 StreamBuffer str;
1579 str.buffer = stream.buffer + cachedLen;
1580 str.bufferLen = stream.bufferLen - cachedLen;
1581 AUDIO_DEBUG_LOG("writing pending data to audio cache: %{public}d", str.bufferLen);
1582 cachedLen += WriteToAudioCache(str);
1583 }
1584 }
1585
1586 pa_threaded_mainloop_unlock(mainLoop);
1587 pError = error;
1588 return cachedLen;
1589 }
1590
UpdateReadBuffer(uint8_t * buffer,size_t & length,size_t & readSize)1591 int32_t AudioServiceClient::UpdateReadBuffer(uint8_t *buffer, size_t &length, size_t &readSize)
1592 {
1593 size_t l = (internalRdBufLen_ < length) ? internalRdBufLen_ : length;
1594 if (memcpy_s(buffer, length, (const uint8_t*)internalReadBuffer_ + internalRdBufIndex_, l)) {
1595 AUDIO_ERR_LOG("Update read buffer failed");
1596 return AUDIO_CLIENT_READ_STREAM_ERR;
1597 }
1598
1599 length -= l;
1600 internalRdBufIndex_ += l;
1601 internalRdBufLen_ -= l;
1602 readSize += l;
1603
1604 if (!internalRdBufLen_) {
1605 int retVal = pa_stream_drop(paStream);
1606 internalReadBuffer_ = nullptr;
1607 internalRdBufLen_ = 0;
1608 internalRdBufIndex_ = 0;
1609 if (retVal < 0) {
1610 AUDIO_ERR_LOG("pa_stream_drop failed, retVal: %{public}d", retVal);
1611 return AUDIO_CLIENT_READ_STREAM_ERR;
1612 }
1613 }
1614
1615 return 0;
1616 }
1617
RenderPrebuf(uint32_t writeLen)1618 int32_t AudioServiceClient::RenderPrebuf(uint32_t writeLen)
1619 {
1620 Trace trace("RenderPrebuf");
1621 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1622 if (bufferAttr == nullptr) {
1623 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
1624 return AUDIO_CLIENT_ERR;
1625 }
1626
1627 if (bufferAttr->maxlength <= writeLen) {
1628 return AUDIO_CLIENT_SUCCESS;
1629 }
1630 size_t diff = bufferAttr->maxlength - writeLen;
1631
1632 int32_t writeError;
1633 StreamBuffer prebufStream;
1634 prebufStream.buffer = preBuf_.get();
1635 if (writeLen == 0) {
1636 return AUDIO_CLIENT_SUCCESS;
1637 } else if (writeLen > diff) {
1638 prebufStream.bufferLen = diff;
1639 } else {
1640 prebufStream.bufferLen = writeLen;
1641 }
1642
1643 size_t bytesWritten {0};
1644 while (true) {
1645 bytesWritten += WriteStream(prebufStream, writeError);
1646 if (writeError) {
1647 AUDIO_ERR_LOG("RenderPrebuf failed: %{public}d", writeError);
1648 return AUDIO_CLIENT_ERR;
1649 }
1650
1651 if (diff <= bytesWritten) {
1652 break;
1653 }
1654
1655 if ((diff - bytesWritten) < writeLen) {
1656 prebufStream.bufferLen = diff - bytesWritten;
1657 }
1658 }
1659
1660 return AUDIO_CLIENT_SUCCESS;
1661 }
1662
OnTimeOut()1663 void AudioServiceClient::OnTimeOut()
1664 {
1665 AUDIO_ERR_LOG("Inside read timeout callback");
1666 if (mainLoop == nullptr) {
1667 AUDIO_ERR_LOG("OnTimeOut failed: mainLoop == nullptr");
1668 return;
1669 }
1670 pa_threaded_mainloop_signal(mainLoop, 0);
1671 }
1672
SetClientID(int32_t clientPid,int32_t clientUid)1673 void AudioServiceClient::SetClientID(int32_t clientPid, int32_t clientUid)
1674 {
1675 AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid);
1676 clientPid_ = clientPid;
1677 clientUid_ = clientUid;
1678 }
1679
GetStreamClass()1680 IAudioStream::StreamClass AudioServiceClient::GetStreamClass()
1681 {
1682 return streamClass_;
1683 }
1684
GetStreamSwitchInfo(SwitchInfo & info)1685 void AudioServiceClient::GetStreamSwitchInfo(SwitchInfo& info)
1686 {
1687 info.cachePath = cachePath_;
1688 info.rendererSampleRate = rendererSampleRate;
1689 info.underFlowCount = underFlowCount;
1690 info.effectMode = effectMode;
1691 info.renderMode = renderMode_;
1692 info.captureMode = captureMode_;
1693 info.renderRate = renderRate;
1694 info.clientPid = clientPid_;
1695 info.clientUid = clientUid_;
1696 info.volume = mVolumeFactor;
1697
1698 info.frameMarkPosition = mFrameMarkPosition;
1699 info.renderPositionCb = mRenderPositionCb;
1700 info.capturePositionCb = mCapturePositionCb;
1701
1702 info.framePeriodNumber = mFramePeriodNumber;
1703 info.renderPeriodPositionCb = mRenderPeriodPositionCb;
1704 info.capturePeriodPositionCb = mCapturePeriodPositionCb;
1705
1706 info.rendererWriteCallback = writeCallback_;
1707 }
1708
HandleCapturePositionCallbacks(size_t bytesRead)1709 void AudioServiceClient::HandleCapturePositionCallbacks(size_t bytesRead)
1710 {
1711 mTotalBytesRead += bytesRead;
1712 if (mFrameSize == 0) {
1713 AUDIO_ERR_LOG("HandleCapturePositionCallbacks: capturePeriodPositionCb not set");
1714 return;
1715 }
1716
1717 uint64_t readFrameNumber = mTotalBytesRead / mFrameSize;
1718 AUDIO_DEBUG_LOG("frame size: %{public}d", mFrameSize);
1719 {
1720 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
1721 if (!mMarkReached) {
1722 AUDIO_DEBUG_LOG("frame mark position: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1723 static_cast<uint64_t>(mFrameMarkPosition), static_cast<uint64_t>(readFrameNumber));
1724 if (readFrameNumber >= mFrameMarkPosition) {
1725 AUDIO_DEBUG_LOG("audio service client capturer OnMarkReached");
1726 SendCapturerMarkReachedRequestEvent(mFrameMarkPosition);
1727 mMarkReached = true;
1728 }
1729 }
1730 }
1731
1732 {
1733 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
1734 mFramePeriodRead += (bytesRead / mFrameSize);
1735 AUDIO_DEBUG_LOG("frame period number: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1736 static_cast<uint64_t>(mFramePeriodNumber), static_cast<uint64_t>(readFrameNumber));
1737 if (mFramePeriodRead >= mFramePeriodNumber) {
1738 mFramePeriodRead %= mFramePeriodNumber;
1739 AUDIO_DEBUG_LOG("audio service client OnPeriodReached, remaining frames: %{public}" PRIu64,
1740 static_cast<uint64_t>(mFramePeriodRead));
1741 SendCapturerPeriodReachedRequestEvent(mFramePeriodNumber);
1742 }
1743 }
1744 }
1745
ReadStream(StreamBuffer & stream,bool isBlocking)1746 int32_t AudioServiceClient::ReadStream(StreamBuffer &stream, bool isBlocking)
1747 {
1748 uint8_t *buffer = stream.buffer;
1749 size_t length = stream.bufferLen;
1750 size_t readSize = 0;
1751 lock_guard<mutex> lock(dataMutex_);
1752 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1753 return AUDIO_CLIENT_PA_ERR;
1754 }
1755
1756 pa_threaded_mainloop_lock(mainLoop);
1757 while (length > 0) {
1758 while (!internalReadBuffer_) {
1759 int retVal = pa_stream_peek(paStream, &internalReadBuffer_, &internalRdBufLen_);
1760 if (retVal < 0) {
1761 AUDIO_ERR_LOG("pa_stream_peek failed, retVal: %{public}d", retVal);
1762 pa_threaded_mainloop_unlock(mainLoop);
1763 return AUDIO_CLIENT_READ_STREAM_ERR;
1764 }
1765
1766 if (internalRdBufLen_ <= 0) {
1767 if (isBlocking) {
1768 StartTimer(READ_TIMEOUT_IN_SEC);
1769 pa_threaded_mainloop_wait(mainLoop);
1770 StopTimer();
1771 if (IsTimeOut()) {
1772 AUDIO_ERR_LOG("Read timeout");
1773 pa_threaded_mainloop_unlock(mainLoop);
1774 return AUDIO_CLIENT_READ_STREAM_ERR;
1775 }
1776 } else {
1777 pa_threaded_mainloop_unlock(mainLoop);
1778 HandleCapturePositionCallbacks(readSize);
1779 return readSize;
1780 }
1781 } else if (!internalReadBuffer_) {
1782 retVal = pa_stream_drop(paStream);
1783 if (retVal < 0) {
1784 AUDIO_ERR_LOG("pa_stream_drop failed, retVal: %{public}d", retVal);
1785 pa_threaded_mainloop_unlock(mainLoop);
1786 return AUDIO_CLIENT_READ_STREAM_ERR;
1787 }
1788 } else {
1789 internalRdBufIndex_ = 0;
1790 AUDIO_DEBUG_LOG("buffer size from PA: %{public}zu", internalRdBufLen_);
1791 }
1792 }
1793
1794 if (UpdateReadBuffer(buffer, length, readSize) != 0) {
1795 pa_threaded_mainloop_unlock(mainLoop);
1796 return AUDIO_CLIENT_READ_STREAM_ERR;
1797 }
1798 buffer = stream.buffer + readSize;
1799 }
1800 pa_threaded_mainloop_unlock(mainLoop);
1801 HandleCapturePositionCallbacks(readSize);
1802
1803 return readSize;
1804 }
1805
ReleaseStream(bool releaseRunner)1806 int32_t AudioServiceClient::ReleaseStream(bool releaseRunner)
1807 {
1808 state_ = RELEASED;
1809 lock_guard<mutex> lockdata(dataMutex_);
1810 WriteStateChangedSysEvents();
1811 ResetPAAudioClient();
1812
1813 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1814 if (streamCb != nullptr) {
1815 streamCb->OnStateChange(state_);
1816 }
1817
1818 {
1819 lock_guard<mutex> runnerlock(runnerMutex_);
1820 if (releaseRunner) {
1821 AUDIO_INFO_LOG("runner remove");
1822 SetEventRunner(nullptr);
1823 runnerReleased_ = true;
1824 }
1825 }
1826
1827 return AUDIO_CLIENT_SUCCESS;
1828 }
1829
SetBufferSizeInMsec(int32_t bufferSizeInMsec)1830 int32_t AudioServiceClient::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
1831 {
1832 size_t bufferSize = pa_usec_to_bytes(bufferSizeInMsec * PA_USEC_PER_MSEC, &sampleSpec);
1833 setBufferSize_ = bufferSize;
1834 return AUDIO_CLIENT_SUCCESS;
1835 }
1836
GetMinimumBufferSize(size_t & minBufferSize) const1837 int32_t AudioServiceClient::GetMinimumBufferSize(size_t &minBufferSize) const
1838 {
1839 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1840 return AUDIO_CLIENT_PA_ERR;
1841 }
1842
1843 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1844
1845 if (bufferAttr == nullptr) {
1846 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
1847 return AUDIO_CLIENT_ERR;
1848 }
1849
1850 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1851 if (renderMode_ == RENDER_MODE_CALLBACK) {
1852 minBufferSize = (size_t)bufferAttr->minreq;
1853 } else {
1854 if (setBufferSize_) {
1855 minBufferSize = setBufferSize_;
1856 } else {
1857 minBufferSize = (size_t)bufferAttr->minreq;
1858 }
1859 }
1860 }
1861
1862 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1863 minBufferSize = (size_t)bufferAttr->fragsize;
1864 }
1865
1866 return AUDIO_CLIENT_SUCCESS;
1867 }
1868
GetMinimumFrameCount(uint32_t & frameCount) const1869 int32_t AudioServiceClient::GetMinimumFrameCount(uint32_t &frameCount) const
1870 {
1871 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1872 return AUDIO_CLIENT_PA_ERR;
1873 }
1874
1875 size_t minBufferSize = 0;
1876
1877 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1878
1879 if (bufferAttr == nullptr) {
1880 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
1881 return AUDIO_CLIENT_ERR;
1882 }
1883
1884 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1885 if (renderMode_ == RENDER_MODE_CALLBACK) {
1886 minBufferSize = (size_t)bufferAttr->minreq;
1887 } else {
1888 if (setBufferSize_) {
1889 minBufferSize = setBufferSize_;
1890 } else {
1891 minBufferSize = (size_t)bufferAttr->minreq;
1892 }
1893 }
1894 }
1895
1896 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1897 minBufferSize = (size_t)bufferAttr->fragsize;
1898 }
1899
1900 uint32_t bytesPerSample = pa_frame_size(&sampleSpec);
1901 if (bytesPerSample == 0) {
1902 AUDIO_ERR_LOG("GetMinimumFrameCount Failed");
1903 return AUDIO_CLIENT_ERR;
1904 }
1905
1906 frameCount = minBufferSize / bytesPerSample;
1907 AUDIO_INFO_LOG("frame count: %{public}d", frameCount);
1908 return AUDIO_CLIENT_SUCCESS;
1909 }
1910
GetSamplingRate() const1911 uint32_t AudioServiceClient::GetSamplingRate() const
1912 {
1913 return DEFAULT_SAMPLING_RATE;
1914 }
1915
GetChannelCount() const1916 uint8_t AudioServiceClient::GetChannelCount() const
1917 {
1918 return DEFAULT_CHANNEL_COUNT;
1919 }
1920
GetSampleSize() const1921 uint8_t AudioServiceClient::GetSampleSize() const
1922 {
1923 return DEFAULT_SAMPLE_SIZE;
1924 }
1925
GetAudioStreamParams(AudioStreamParams & audioParams) const1926 int32_t AudioServiceClient::GetAudioStreamParams(AudioStreamParams& audioParams) const
1927 {
1928 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1929 return AUDIO_CLIENT_PA_ERR;
1930 }
1931
1932 const pa_sample_spec *paSampleSpec = pa_stream_get_sample_spec(paStream);
1933
1934 if (!paSampleSpec) {
1935 AUDIO_ERR_LOG("GetAudioStreamParams Failed");
1936 return AUDIO_CLIENT_ERR;
1937 }
1938
1939 audioParams = ConvertFromPAAudioParams(*paSampleSpec);
1940 return AUDIO_CLIENT_SUCCESS;
1941 }
1942
GetCurrentTimeStamp(uint64_t & timeStamp)1943 int32_t AudioServiceClient::GetCurrentTimeStamp(uint64_t &timeStamp)
1944 {
1945 lock_guard<mutex> lock(dataMutex_);
1946 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1947 return AUDIO_CLIENT_PA_ERR;
1948 }
1949 pa_threaded_mainloop_lock(mainLoop);
1950
1951 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1952 pa_operation *operation = pa_stream_update_timing_info(paStream, NULL, NULL);
1953 if (operation != nullptr) {
1954 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1955 pa_threaded_mainloop_wait(mainLoop);
1956 }
1957 pa_operation_unref(operation);
1958 } else {
1959 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
1960 }
1961 }
1962
1963 const pa_timing_info *info = pa_stream_get_timing_info(paStream);
1964 if (info == nullptr) {
1965 AUDIO_ERR_LOG("pa_stream_get_timing_info failed");
1966 pa_threaded_mainloop_unlock(mainLoop);
1967 return AUDIO_CLIENT_ERR;
1968 }
1969
1970 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1971 timeStamp = pa_bytes_to_usec(info->write_index, &sampleSpec);
1972 } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1973 if (pa_stream_get_time(paStream, &timeStamp)) {
1974 AUDIO_ERR_LOG("GetCurrentTimeStamp failed for AUDIO_SERVICE_CLIENT_RECORD");
1975 pa_threaded_mainloop_unlock(mainLoop);
1976 return AUDIO_CLIENT_ERR;
1977 }
1978 int32_t uid = static_cast<int32_t>(getuid());
1979
1980 // 1013 is media_service's uid
1981 int32_t media_service = 1013;
1982 if (uid == media_service) {
1983 timeStamp = pa_bytes_to_usec(mTotalBytesRead, &sampleSpec);
1984 }
1985 }
1986
1987 pa_threaded_mainloop_unlock(mainLoop);
1988
1989 return AUDIO_CLIENT_SUCCESS;
1990 }
1991
GetAudioLatency(uint64_t & latency)1992 int32_t AudioServiceClient::GetAudioLatency(uint64_t &latency)
1993 {
1994 lock_guard<mutex> lock(dataMutex_);
1995 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1996 return AUDIO_CLIENT_PA_ERR;
1997 }
1998 pa_usec_t paLatency {0};
1999 pa_usec_t cacheLatency {0};
2000 int negative {0};
2001
2002 // Get PA latency
2003 pa_threaded_mainloop_lock(mainLoop);
2004 while (true) {
2005 pa_operation *operation = pa_stream_update_timing_info(paStream, NULL, NULL);
2006 if (operation != nullptr) {
2007 pa_operation_unref(operation);
2008 } else {
2009 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
2010 }
2011 if (pa_stream_get_latency(paStream, &paLatency, &negative) >= 0) {
2012 if (negative) {
2013 latency = 0;
2014 pa_threaded_mainloop_unlock(mainLoop);
2015 return AUDIO_CLIENT_ERR;
2016 }
2017 break;
2018 }
2019 AUDIO_INFO_LOG("waiting for audio latency information");
2020 pa_threaded_mainloop_wait(mainLoop);
2021 }
2022 pa_threaded_mainloop_unlock(mainLoop);
2023
2024 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2025 // Get audio write cache latency
2026 cacheLatency = pa_bytes_to_usec((acache_.totalCacheSize - acache_.writeIndex), &sampleSpec);
2027
2028 // Total latency will be sum of audio write cache latency + PA latency
2029 uint64_t fwLatency = paLatency + cacheLatency;
2030 uint64_t sinkLatency = sinkLatencyInMsec_ * PA_USEC_PER_MSEC;
2031 if (fwLatency > sinkLatency) {
2032 latency = fwLatency - sinkLatency;
2033 } else {
2034 latency = fwLatency;
2035 }
2036 AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}"
2037 PRIu64 ", cache latency: %{public}" PRIu64, latency, paLatency, cacheLatency);
2038 } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
2039 // Get audio read cache latency
2040 cacheLatency = pa_bytes_to_usec(internalRdBufLen_, &sampleSpec);
2041
2042 // Total latency will be sum of audio read cache latency + PA latency
2043 latency = paLatency + cacheLatency;
2044 AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}" PRIu64, latency, paLatency);
2045 }
2046
2047 return AUDIO_CLIENT_SUCCESS;
2048 }
2049
RegisterAudioRendererCallbacks(const AudioRendererCallbacks & cb)2050 void AudioServiceClient::RegisterAudioRendererCallbacks(const AudioRendererCallbacks &cb)
2051 {
2052 AUDIO_DEBUG_LOG("Registering audio render callbacks");
2053 mAudioRendererCallbacks = (AudioRendererCallbacks *)&cb;
2054 }
2055
RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks & cb)2056 void AudioServiceClient::RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks &cb)
2057 {
2058 AUDIO_DEBUG_LOG("Registering audio record callbacks");
2059 mAudioCapturerCallbacks = (AudioCapturerCallbacks *)&cb;
2060 }
2061
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)2062 void AudioServiceClient::SetRendererPositionCallback(int64_t markPosition,
2063 const std::shared_ptr<RendererPositionCallback> &callback)
2064 {
2065 std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
2066 AUDIO_INFO_LOG("Registering render frame position callback mark position: %{public}" PRIu64, markPosition);
2067 mFrameMarkPosition = markPosition;
2068 SendSetRenderMarkReachedRequestEvent(callback);
2069 mMarkReached = false;
2070 }
2071
UnsetRendererPositionCallback()2072 void AudioServiceClient::UnsetRendererPositionCallback()
2073 {
2074 AUDIO_INFO_LOG("Unregistering render frame position callback");
2075 std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
2076 SendUnsetRenderMarkReachedRequestEvent();
2077 mMarkReached = false;
2078 mFrameMarkPosition = 0;
2079 }
2080
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)2081 void AudioServiceClient::SetRendererPeriodPositionCallback(int64_t periodPosition,
2082 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2083 {
2084 std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
2085 AUDIO_INFO_LOG("Registering render period position callback");
2086 mFramePeriodNumber = periodPosition;
2087 if ((mFrameSize != 0) && (mFramePeriodNumber != 0)) {
2088 mFramePeriodWritten = (mTotalBytesWritten / mFrameSize) % mFramePeriodNumber;
2089 } else {
2090 AUDIO_ERR_LOG("SetRendererPeriodPositionCallback failed");
2091 return;
2092 }
2093 SendSetRenderPeriodReachedRequestEvent(callback);
2094 }
2095
UnsetRendererPeriodPositionCallback()2096 void AudioServiceClient::UnsetRendererPeriodPositionCallback()
2097 {
2098 AUDIO_INFO_LOG("Unregistering render period position callback");
2099 std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
2100 SendUnsetRenderPeriodReachedRequestEvent();
2101 mFramePeriodWritten = 0;
2102 mFramePeriodNumber = 0;
2103 }
2104
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)2105 void AudioServiceClient::SetCapturerPositionCallback(int64_t markPosition,
2106 const std::shared_ptr<CapturerPositionCallback> &callback)
2107 {
2108 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
2109 AUDIO_INFO_LOG("Registering capture frame position callback, mark position: %{public}" PRIu64, markPosition);
2110 mFrameMarkPosition = markPosition;
2111 SendSetCapturerMarkReachedRequestEvent(callback);
2112 mMarkReached = false;
2113 }
2114
UnsetCapturerPositionCallback()2115 void AudioServiceClient::UnsetCapturerPositionCallback()
2116 {
2117 AUDIO_INFO_LOG("Unregistering capture frame position callback");
2118 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
2119 SendUnsetCapturerMarkReachedRequestEvent();
2120 mMarkReached = false;
2121 mFrameMarkPosition = 0;
2122 }
2123
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2124 void AudioServiceClient::SetCapturerPeriodPositionCallback(int64_t periodPosition,
2125 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2126 {
2127 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
2128 AUDIO_INFO_LOG("Registering period position callback");
2129 mFramePeriodNumber = periodPosition;
2130 if ((mFrameSize != 0) && (mFramePeriodNumber != 0)) {
2131 mFramePeriodRead = (mTotalBytesRead / mFrameSize) % mFramePeriodNumber;
2132 } else {
2133 AUDIO_ERR_LOG("SetCapturerPeriodPositionCallback failed");
2134 return;
2135 }
2136 SendSetCapturerPeriodReachedRequestEvent(callback);
2137 }
2138
UnsetCapturerPeriodPositionCallback()2139 void AudioServiceClient::UnsetCapturerPeriodPositionCallback()
2140 {
2141 AUDIO_INFO_LOG("Unregistering period position callback");
2142 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
2143 SendUnsetCapturerPeriodReachedRequestEvent();
2144 mFramePeriodRead = 0;
2145 mFramePeriodNumber = 0;
2146 }
2147
SetStreamType(AudioStreamType audioStreamType)2148 int32_t AudioServiceClient::SetStreamType(AudioStreamType audioStreamType)
2149 {
2150 AUDIO_INFO_LOG("SetStreamType: %{public}d", audioStreamType);
2151
2152 if (context == nullptr) {
2153 AUDIO_ERR_LOG("context is null");
2154 return AUDIO_CLIENT_ERR;
2155 }
2156
2157 pa_threaded_mainloop_lock(mainLoop);
2158
2159 mStreamType = audioStreamType;
2160 const std::string streamName = GetStreamName(audioStreamType);
2161 effectSceneName = IAudioStream::GetEffectSceneName(audioStreamType);
2162
2163 pa_proplist *propList = pa_proplist_new();
2164 if (propList == nullptr) {
2165 AUDIO_ERR_LOG("pa_proplist_new failed");
2166 pa_threaded_mainloop_unlock(mainLoop);
2167 return AUDIO_CLIENT_ERR;
2168 }
2169
2170 pa_proplist_sets(propList, "stream.type", streamName.c_str());
2171 pa_proplist_sets(propList, "media.name", streamName.c_str());
2172 pa_proplist_sets(propList, "scene.type", effectSceneName.c_str());
2173 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2174 nullptr, nullptr);
2175 pa_proplist_free(propList);
2176 pa_operation_unref(updatePropOperation);
2177
2178 pa_threaded_mainloop_unlock(mainLoop);
2179
2180 return AUDIO_CLIENT_SUCCESS;
2181 }
2182
SetStreamVolume(float volume)2183 int32_t AudioServiceClient::SetStreamVolume(float volume)
2184 {
2185 lock_guard<mutex> lock(ctrlMutex_);
2186 AUDIO_INFO_LOG("SetVolume volume: %{public}f", volume);
2187
2188 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2189 AUDIO_ERR_LOG("set stream volume: invalid stream state");
2190 return AUDIO_CLIENT_PA_ERR;
2191 }
2192
2193 /* Validate and return INVALID_PARAMS error */
2194 if ((volume < MIN_STREAM_VOLUME_LEVEL) || (volume > MAX_STREAM_VOLUME_LEVEL)) {
2195 AUDIO_ERR_LOG("Invalid Volume Input!");
2196 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2197 }
2198
2199 pa_threaded_mainloop_lock(mainLoop);
2200
2201 mVolumeFactor = volume;
2202 pa_proplist *propList = pa_proplist_new();
2203 if (propList == nullptr) {
2204 AUDIO_ERR_LOG("pa_proplist_new failed");
2205 pa_threaded_mainloop_unlock(mainLoop);
2206 return AUDIO_CLIENT_ERR;
2207 }
2208
2209 pa_proplist_sets(propList, "stream.volumeFactor", std::to_string(mVolumeFactor).c_str());
2210 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2211 nullptr, nullptr);
2212 if (updatePropOperation == nullptr) {
2213 AUDIO_ERR_LOG("pa_stream_proplist_update returned null");
2214 pa_proplist_free(propList);
2215 pa_threaded_mainloop_unlock(mainLoop);
2216 return AUDIO_CLIENT_ERR;
2217 }
2218
2219 pa_proplist_free(propList);
2220 pa_operation_unref(updatePropOperation);
2221
2222 if (mAudioSystemMgr == nullptr) {
2223 AUDIO_ERR_LOG("System manager instance is null");
2224 pa_threaded_mainloop_unlock(mainLoop);
2225 return AUDIO_CLIENT_ERR;
2226 }
2227
2228 if (!streamInfoUpdated) {
2229 uint32_t idx = pa_stream_get_index(paStream);
2230 pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
2231 reinterpret_cast<void *>(this));
2232 if (operation == nullptr) {
2233 AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
2234 pa_threaded_mainloop_unlock(mainLoop);
2235 return AUDIO_CLIENT_ERR;
2236 }
2237
2238 pa_threaded_mainloop_accept(mainLoop);
2239
2240 pa_operation_unref(operation);
2241 } else {
2242 SetPaVolume(*this);
2243 }
2244
2245 pa_threaded_mainloop_unlock(mainLoop);
2246
2247 return AUDIO_CLIENT_SUCCESS;
2248 }
2249
GetStreamVolume()2250 float AudioServiceClient::GetStreamVolume()
2251 {
2252 return mVolumeFactor;
2253 }
2254
GetSinkInputInfoCb(pa_context * context,const pa_sink_input_info * info,int eol,void * userdata)2255 void AudioServiceClient::GetSinkInputInfoCb(pa_context *context, const pa_sink_input_info *info, int eol,
2256 void *userdata)
2257 {
2258 AUDIO_INFO_LOG("GetSinkInputInfoVolumeCb in");
2259 AudioServiceClient *thiz = reinterpret_cast<AudioServiceClient *>(userdata);
2260
2261 if (eol < 0) {
2262 AUDIO_ERR_LOG("Failed to get sink input information: %{public}s", pa_strerror(pa_context_errno(context)));
2263 return;
2264 }
2265
2266 if (eol) {
2267 pa_threaded_mainloop_signal(thiz->mainLoop, 1);
2268 return;
2269 }
2270
2271 if (info->proplist == nullptr) {
2272 AUDIO_ERR_LOG("Invalid prop list for sink input (%{public}d).", info->index);
2273 return;
2274 }
2275
2276 uint32_t sessionID = 0;
2277 const char *sessionCStr = pa_proplist_gets(info->proplist, "stream.sessionID");
2278 if (sessionCStr != nullptr) {
2279 std::stringstream sessionStr;
2280 sessionStr << sessionCStr;
2281 sessionStr >> sessionID;
2282 }
2283
2284 thiz->cvolume = info->volume;
2285 thiz->streamIndex = info->index;
2286 thiz->sessionID_ = sessionID;
2287 thiz->volumeChannels = info->channel_map.channels;
2288 thiz->streamInfoUpdated = true;
2289
2290 SetPaVolume(*thiz);
2291
2292 return;
2293 }
2294
SetPaVolume(const AudioServiceClient & client)2295 void AudioServiceClient::SetPaVolume(const AudioServiceClient &client)
2296 {
2297 pa_cvolume cv = client.cvolume;
2298 AudioVolumeType volumeType = GetVolumeTypeFromStreamType(client.mStreamType);
2299 int32_t systemVolumeLevel = AudioSystemManager::GetInstance()->GetVolume(volumeType);
2300 DeviceType deviceType = AudioSystemManager::GetInstance()->GetActiveOutputDevice();
2301 float systemVolumeDb = AudioPolicyManager::GetInstance().GetSystemVolumeInDb(volumeType,
2302 systemVolumeLevel, deviceType);
2303 float vol = systemVolumeDb * client.mVolumeFactor * client.mPowerVolumeFactor;
2304
2305 uint32_t volume = pa_sw_volume_from_linear(vol);
2306 pa_cvolume_set(&cv, client.volumeChannels, volume);
2307 pa_operation_unref(pa_context_set_sink_input_volume(client.context, client.streamIndex, &cv, nullptr, nullptr));
2308
2309 AUDIO_INFO_LOG("Applied volume %{public}f, systemVolume %{public}f, volumeFactor %{public}f", vol, systemVolumeDb,
2310 client.mVolumeFactor);
2311 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO,
2312 "VOLUME_CHANGE", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
2313 "ISOUTPUT", 1,
2314 "STREAMID", client.sessionID_,
2315 "APP_UID", client.clientUid_,
2316 "APP_PID", client.clientPid_,
2317 "STREAMTYPE", client.mStreamType,
2318 "VOLUME", vol,
2319 "SYSVOLUME", systemVolumeDb,
2320 "VOLUMEFACTOR", client.mVolumeFactor,
2321 "POWERVOLUMEFACTOR", client.mPowerVolumeFactor);
2322 }
2323
GetVolumeTypeFromStreamType(AudioStreamType streamType)2324 AudioVolumeType AudioServiceClient::GetVolumeTypeFromStreamType(AudioStreamType streamType)
2325 {
2326 switch (streamType) {
2327 case STREAM_VOICE_CALL:
2328 case STREAM_VOICE_MESSAGE:
2329 return STREAM_VOICE_CALL;
2330 case STREAM_RING:
2331 case STREAM_SYSTEM:
2332 case STREAM_NOTIFICATION:
2333 case STREAM_SYSTEM_ENFORCED:
2334 case STREAM_DTMF:
2335 return STREAM_RING;
2336 case STREAM_MUSIC:
2337 case STREAM_MEDIA:
2338 case STREAM_MOVIE:
2339 case STREAM_GAME:
2340 case STREAM_SPEECH:
2341 case STREAM_NAVIGATION:
2342 return STREAM_MUSIC;
2343 case STREAM_VOICE_ASSISTANT:
2344 return STREAM_VOICE_ASSISTANT;
2345 case STREAM_ALARM:
2346 return STREAM_ALARM;
2347 case STREAM_ACCESSIBILITY:
2348 return STREAM_ACCESSIBILITY;
2349 case STREAM_ULTRASONIC:
2350 return STREAM_ULTRASONIC;
2351 default:
2352 AUDIO_ERR_LOG("GetVolumeTypeFromStreamType streamType = %{public}d not supported", streamType);
2353 return streamType;
2354 }
2355 }
2356
SetStreamRenderRate(AudioRendererRate audioRendererRate)2357 int32_t AudioServiceClient::SetStreamRenderRate(AudioRendererRate audioRendererRate)
2358 {
2359 AUDIO_INFO_LOG("SetStreamRenderRate in");
2360 if (!paStream) {
2361 return AUDIO_CLIENT_SUCCESS;
2362 }
2363
2364 uint32_t rate = sampleSpec.rate;
2365 switch (audioRendererRate) {
2366 case RENDER_RATE_NORMAL:
2367 break;
2368 case RENDER_RATE_DOUBLE:
2369 rate *= DOUBLE_VALUE;
2370 break;
2371 case RENDER_RATE_HALF:
2372 rate /= DOUBLE_VALUE;
2373 break;
2374 default:
2375 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2376 }
2377 renderRate = audioRendererRate;
2378
2379 pa_threaded_mainloop_lock(mainLoop);
2380 pa_operation *operation = pa_stream_update_sample_rate(paStream, rate, nullptr, nullptr);
2381 pa_operation_unref(operation);
2382 pa_threaded_mainloop_unlock(mainLoop);
2383
2384 return AUDIO_CLIENT_SUCCESS;
2385 }
2386
SetRendererSamplingRate(uint32_t sampleRate)2387 int32_t AudioServiceClient::SetRendererSamplingRate(uint32_t sampleRate)
2388 {
2389 AUDIO_INFO_LOG("SetStreamRendererSamplingRate %{public}d", sampleRate);
2390 if (!paStream) {
2391 return AUDIO_CLIENT_SUCCESS;
2392 }
2393
2394 if (sampleRate <= 0) {
2395 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2396 }
2397 rendererSampleRate = sampleRate;
2398
2399 pa_threaded_mainloop_lock(mainLoop);
2400 pa_operation *operation = pa_stream_update_sample_rate(paStream, sampleRate, nullptr, nullptr);
2401 pa_operation_unref(operation);
2402 pa_threaded_mainloop_unlock(mainLoop);
2403
2404 return AUDIO_CLIENT_SUCCESS;
2405 }
2406
GetRendererSamplingRate()2407 uint32_t AudioServiceClient::GetRendererSamplingRate()
2408 {
2409 if (rendererSampleRate == 0) {
2410 return sampleSpec.rate;
2411 }
2412 return rendererSampleRate;
2413 }
2414
GetStreamRenderRate()2415 AudioRendererRate AudioServiceClient::GetStreamRenderRate()
2416 {
2417 return renderRate;
2418 }
2419
SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> & callback)2420 void AudioServiceClient::SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> &callback)
2421 {
2422 streamCallback_ = callback;
2423
2424 if (state_ != PREPARED) {
2425 return;
2426 }
2427
2428 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
2429 if (streamCb != nullptr) {
2430 streamCb->OnStateChange(state_);
2431 }
2432 }
2433
WriteStateChangedSysEvents()2434 void AudioServiceClient::WriteStateChangedSysEvents()
2435 {
2436 uint32_t sessionID = 0;
2437 uint64_t transactionId = 0;
2438 DeviceType deviceType = DEVICE_TYPE_INVALID;
2439
2440 bool isOutput = true;
2441 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2442 deviceType = mAudioSystemMgr->GetActiveOutputDevice();
2443 transactionId = mAudioSystemMgr->GetTransactionId(deviceType, OUTPUT_DEVICE);
2444 } else {
2445 deviceType = mAudioSystemMgr->GetActiveInputDevice();
2446 transactionId = mAudioSystemMgr->GetTransactionId(deviceType, INPUT_DEVICE);
2447 isOutput = false;
2448 }
2449
2450 GetSessionID(sessionID);
2451
2452 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO, "STREAM_CHANGE",
2453 HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
2454 "ISOUTPUT", isOutput ? 1 : 0,
2455 "STREAMID", sessionID,
2456 "UID", clientUid_,
2457 "PID", clientPid_,
2458 "TRANSACTIONID", transactionId,
2459 "STREAMTYPE", mStreamType,
2460 "STATE", state_,
2461 "DEVICETYPE", deviceType);
2462 }
2463
SetStreamLowPowerVolume(float powerVolumeFactor)2464 int32_t AudioServiceClient::SetStreamLowPowerVolume(float powerVolumeFactor)
2465 {
2466 lock_guard<mutex> lock(ctrlMutex_);
2467 AUDIO_INFO_LOG("SetPowerVolumeFactor volume: %{public}f", powerVolumeFactor);
2468
2469 if (context == nullptr) {
2470 AUDIO_ERR_LOG("context is null");
2471 return AUDIO_CLIENT_ERR;
2472 }
2473
2474 /* Validate and return INVALID_PARAMS error */
2475 if ((powerVolumeFactor < MIN_STREAM_VOLUME_LEVEL) || (powerVolumeFactor > MAX_STREAM_VOLUME_LEVEL)) {
2476 AUDIO_ERR_LOG("Invalid Power Volume Set!");
2477 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2478 }
2479
2480 pa_threaded_mainloop_lock(mainLoop);
2481
2482 mPowerVolumeFactor = powerVolumeFactor;
2483 pa_proplist *propList = pa_proplist_new();
2484 if (propList == nullptr) {
2485 AUDIO_ERR_LOG("pa_proplist_new failed");
2486 pa_threaded_mainloop_unlock(mainLoop);
2487 return AUDIO_CLIENT_ERR;
2488 }
2489
2490 pa_proplist_sets(propList, "stream.powerVolumeFactor", std::to_string(mPowerVolumeFactor).c_str());
2491 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2492 nullptr, nullptr);
2493 pa_proplist_free(propList);
2494 pa_operation_unref(updatePropOperation);
2495
2496 if (mAudioSystemMgr == nullptr) {
2497 AUDIO_ERR_LOG("System manager instance is null");
2498 pa_threaded_mainloop_unlock(mainLoop);
2499 return AUDIO_CLIENT_ERR;
2500 }
2501
2502 if (!streamInfoUpdated) {
2503 uint32_t idx = pa_stream_get_index(paStream);
2504 pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
2505 reinterpret_cast<void *>(this));
2506 if (operation == nullptr) {
2507 AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
2508 pa_threaded_mainloop_unlock(mainLoop);
2509 return AUDIO_CLIENT_ERR;
2510 }
2511
2512 pa_threaded_mainloop_accept(mainLoop);
2513
2514 pa_operation_unref(operation);
2515 } else {
2516 SetPaVolume(*this);
2517 }
2518
2519 pa_threaded_mainloop_unlock(mainLoop);
2520
2521 return AUDIO_CLIENT_SUCCESS;
2522 }
2523
GetStreamLowPowerVolume()2524 float AudioServiceClient::GetStreamLowPowerVolume()
2525 {
2526 return mPowerVolumeFactor;
2527 }
2528
GetSingleStreamVol()2529 float AudioServiceClient::GetSingleStreamVol()
2530 {
2531 int32_t systemVolumeLevel = mAudioSystemMgr->GetVolume(static_cast<AudioVolumeType>(mStreamType));
2532 DeviceType deviceType = mAudioSystemMgr->GetActiveOutputDevice();
2533 float systemVolumeDb = AudioPolicyManager::GetInstance().GetSystemVolumeInDb(mStreamType,
2534 systemVolumeLevel, deviceType);
2535 return systemVolumeDb * mVolumeFactor * mPowerVolumeFactor;
2536 }
2537
2538 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)2539 void AudioServiceClient::SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
2540 {
2541 lock_guard<mutex> runnerlock(runnerMutex_);
2542 if (runnerReleased_) {
2543 AUDIO_WARNING_LOG("SendRenderMarkReachedRequestEvent runner released");
2544 return;
2545 }
2546 SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_MARK_REACHED_REQUEST, mFrameMarkPosition));
2547 }
2548
HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)2549 void AudioServiceClient::HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)
2550 {
2551 if (mRenderPositionCb) {
2552 mRenderPositionCb->OnMarkReached(mFrameMarkPosition);
2553 }
2554 }
2555
2556 // SetRenderMarkReached by eventHandler
SendSetRenderMarkReachedRequestEvent(const std::shared_ptr<RendererPositionCallback> & callback)2557 void AudioServiceClient::SendSetRenderMarkReachedRequestEvent(
2558 const std::shared_ptr<RendererPositionCallback> &callback)
2559 {
2560 lock_guard<mutex> runnerlock(runnerMutex_);
2561 if (runnerReleased_) {
2562 AUDIO_WARNING_LOG("SendSetRenderMarkReachedRequestEvent runner released");
2563 return;
2564 }
2565 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_MARK_REACHED_REQUEST, callback));
2566 }
2567
HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> & callback)2568 void AudioServiceClient::HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> &callback)
2569 {
2570 mRenderPositionCb = callback;
2571 }
2572
2573 // UnsetRenderMarkReach by eventHandler
SendUnsetRenderMarkReachedRequestEvent()2574 void AudioServiceClient::SendUnsetRenderMarkReachedRequestEvent()
2575 {
2576 lock_guard<mutex> runnerlock(runnerMutex_);
2577 if (runnerReleased_) {
2578 AUDIO_WARNING_LOG("SendUnsetRenderMarkReachedRequestEvent runner released");
2579 return;
2580 }
2581 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_MARK_REACHED_REQUEST));
2582 }
2583
HandleUnsetRenderMarkReachedEvent()2584 void AudioServiceClient::HandleUnsetRenderMarkReachedEvent()
2585 {
2586 mRenderPositionCb = nullptr;
2587 }
2588
2589 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)2590 void AudioServiceClient::SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
2591 {
2592 lock_guard<mutex> runnerlock(runnerMutex_);
2593 if (runnerReleased_) {
2594 AUDIO_WARNING_LOG("SendRenderPeriodReachedRequestEvent runner released");
2595 return;
2596 }
2597 SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
2598 }
2599
HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)2600 void AudioServiceClient::HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)
2601 {
2602 if (mRenderPeriodPositionCb) {
2603 mRenderPeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
2604 }
2605 }
2606
2607 // SetRenderPeriodReach by eventHandler
SendSetRenderPeriodReachedRequestEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)2608 void AudioServiceClient::SendSetRenderPeriodReachedRequestEvent(
2609 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2610 {
2611 lock_guard<mutex> runnerlock(runnerMutex_);
2612 if (runnerReleased_) {
2613 AUDIO_WARNING_LOG("SendSetRenderPeriodReachedRequestEvent runner released");
2614 return;
2615 }
2616 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_PERIOD_REACHED_REQUEST, callback));
2617 }
2618
HandleSetRenderPeriodReachedEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)2619 void AudioServiceClient::HandleSetRenderPeriodReachedEvent(
2620 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2621 {
2622 if (callback) {
2623 mRenderPeriodPositionCb = callback;
2624 }
2625 }
2626
2627 // UnsetRenderPeriodReach by eventHandler
SendUnsetRenderPeriodReachedRequestEvent()2628 void AudioServiceClient::SendUnsetRenderPeriodReachedRequestEvent()
2629 {
2630 lock_guard<mutex> runnerlock(runnerMutex_);
2631 if (runnerReleased_) {
2632 AUDIO_WARNING_LOG("SendUnsetRenderPeriodReachedRequestEvent runner released");
2633 return;
2634 }
2635 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_PERIOD_REACHED_REQUEST));
2636 }
2637
HandleUnsetRenderPeriodReachedEvent()2638 void AudioServiceClient::HandleUnsetRenderPeriodReachedEvent()
2639 {
2640 mRenderPeriodPositionCb = nullptr;
2641 }
2642
2643 // OnCapturerMarkReach by eventHandler
SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)2644 void AudioServiceClient::SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
2645 {
2646 lock_guard<mutex> runnerlock(runnerMutex_);
2647 if (runnerReleased_) {
2648 AUDIO_WARNING_LOG("SendCapturerMarkReachedRequestEvent runner released");
2649 return;
2650 }
2651 SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_MARK_REACHED_REQUEST, mFrameMarkPosition));
2652 }
2653
HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)2654 void AudioServiceClient::HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)
2655 {
2656 if (mCapturePositionCb) {
2657 mCapturePositionCb->OnMarkReached(mFrameMarkPosition);
2658 }
2659 }
2660
2661 // SetCapturerMarkReach by eventHandler
SendSetCapturerMarkReachedRequestEvent(const std::shared_ptr<CapturerPositionCallback> & callback)2662 void AudioServiceClient::SendSetCapturerMarkReachedRequestEvent(
2663 const std::shared_ptr<CapturerPositionCallback> &callback)
2664 {
2665 lock_guard<mutex> runnerlock(runnerMutex_);
2666 if (runnerReleased_) {
2667 AUDIO_WARNING_LOG("SendSetCapturerMarkReachedRequestEvent runner released");
2668 return;
2669 }
2670 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_MARK_REACHED_REQUEST, callback));
2671 }
2672
HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> & callback)2673 void AudioServiceClient::HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> &callback)
2674 {
2675 mCapturePositionCb = callback;
2676 }
2677
2678 // UnsetCapturerMarkReach by eventHandler
SendUnsetCapturerMarkReachedRequestEvent()2679 void AudioServiceClient::SendUnsetCapturerMarkReachedRequestEvent()
2680 {
2681 lock_guard<mutex> runnerlock(runnerMutex_);
2682 if (runnerReleased_) {
2683 AUDIO_WARNING_LOG("SendUnsetCapturerMarkReachedRequestEvent runner released");
2684 return;
2685 }
2686 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_MARK_REACHED_REQUEST));
2687 }
2688
HandleUnsetCapturerMarkReachedEvent()2689 void AudioServiceClient::HandleUnsetCapturerMarkReachedEvent()
2690 {
2691 mCapturePositionCb = nullptr;
2692 }
2693
2694 // OnCapturerPeriodReach by eventHandler
SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)2695 void AudioServiceClient::SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
2696 {
2697 lock_guard<mutex> runnerlock(runnerMutex_);
2698 if (runnerReleased_) {
2699 AUDIO_WARNING_LOG("SendCapturerPeriodReachedRequestEvent runner released");
2700 return;
2701 }
2702 SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
2703 }
2704
HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)2705 void AudioServiceClient::HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)
2706 {
2707 if (mCapturePeriodPositionCb) {
2708 mCapturePeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
2709 }
2710 }
2711
2712 // SetCapturerPeriodReach by eventHandler
SendSetCapturerPeriodReachedRequestEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2713 void AudioServiceClient::SendSetCapturerPeriodReachedRequestEvent(
2714 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2715 {
2716 lock_guard<mutex> runnerlock(runnerMutex_);
2717 if (runnerReleased_) {
2718 AUDIO_WARNING_LOG("SendSetCapturerPeriodReachedRequestEvent runner released");
2719 return;
2720 }
2721 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_PERIOD_REACHED_REQUEST, callback));
2722 }
2723
HandleSetCapturerPeriodReachedEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2724 void AudioServiceClient::HandleSetCapturerPeriodReachedEvent(
2725 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2726 {
2727 mCapturePeriodPositionCb = callback;
2728 }
2729
2730 // UnsetCapturerPeriodReach by eventHandler
SendUnsetCapturerPeriodReachedRequestEvent()2731 void AudioServiceClient::SendUnsetCapturerPeriodReachedRequestEvent()
2732 {
2733 lock_guard<mutex> runnerlock(runnerMutex_);
2734 if (runnerReleased_) {
2735 AUDIO_WARNING_LOG("SendUnsetCapturerPeriodReachedRequestEvent runner released");
2736 return;
2737 }
2738 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_PERIOD_REACHED_REQUEST));
2739 }
2740
HandleUnsetCapturerPeriodReachedEvent()2741 void AudioServiceClient::HandleUnsetCapturerPeriodReachedEvent()
2742 {
2743 mCapturePeriodPositionCb = nullptr;
2744 }
2745
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)2746 int32_t AudioServiceClient::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
2747 {
2748 std::lock_guard<std::mutex> lockSet(writeCallbackMutex_);
2749 if (!callback) {
2750 AUDIO_ERR_LOG("SetRendererWriteCallback callback is nullptr");
2751 return ERR_INVALID_PARAM;
2752 }
2753 writeCallback_ = callback;
2754 return SUCCESS;
2755 }
2756
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)2757 int32_t AudioServiceClient::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
2758 {
2759 if (!callback) {
2760 AUDIO_ERR_LOG("SetCapturerReadCallback callback is nullptr");
2761 return ERR_INVALID_PARAM;
2762 }
2763 readCallback_ = callback;
2764 return SUCCESS;
2765 }
2766
SendWriteBufferRequestEvent()2767 void AudioServiceClient::SendWriteBufferRequestEvent()
2768 {
2769 // send write event to handler
2770 lock_guard<mutex> runnerlock(runnerMutex_);
2771 if (runnerReleased_) {
2772 AUDIO_WARNING_LOG("SendWriteBufferRequestEvent after runner released");
2773 return;
2774 }
2775 SendEvent(AppExecFwk::InnerEvent::Get(WRITE_BUFFER_REQUEST));
2776 }
2777
SendReadBufferRequestEvent()2778 void AudioServiceClient::SendReadBufferRequestEvent()
2779 {
2780 // send write event to handler
2781 lock_guard<mutex> runnerlock(runnerMutex_);
2782 if (runnerReleased_) {
2783 AUDIO_WARNING_LOG("SendReadBufferRequestEvent after runner released");
2784 return;
2785 }
2786 SendEvent(AppExecFwk::InnerEvent::Get(READ_BUFFER_REQUEST));
2787 }
2788
HandleWriteRequestEvent()2789 void AudioServiceClient::HandleWriteRequestEvent()
2790 {
2791 std::lock_guard<std::mutex> lockSet(writeCallbackMutex_);
2792 // do callback to application
2793 if (writeCallback_) {
2794 size_t requestSize;
2795 GetMinimumBufferSize(requestSize);
2796 writeCallback_->OnWriteData(requestSize);
2797 }
2798 }
2799
HandleReadRequestEvent()2800 void AudioServiceClient::HandleReadRequestEvent()
2801 {
2802 // do callback to application
2803 if (readCallback_) {
2804 size_t requestSize;
2805 GetMinimumBufferSize(requestSize);
2806 readCallback_->OnReadData(requestSize);
2807 }
2808 }
2809
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)2810 void AudioServiceClient::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
2811 {
2812 uint32_t eventId = event->GetInnerEventId();
2813 uint64_t mFrameMarkPosition;
2814 uint64_t mFramePeriodNumber;
2815 std::shared_ptr<RendererPositionCallback> renderPositionCb;
2816 std::shared_ptr<RendererPeriodPositionCallback> renderPeriodPositionCb;
2817 std::shared_ptr<CapturerPositionCallback> capturePositionCb;
2818 std::shared_ptr<CapturerPeriodPositionCallback> capturePeriodPositionCb;
2819
2820 switch (eventId) {
2821 case WRITE_BUFFER_REQUEST:
2822 HandleWriteRequestEvent();
2823 break;
2824 case READ_BUFFER_REQUEST:
2825 HandleReadRequestEvent();
2826 break;
2827
2828 // RenderMarkReach
2829 case RENDERER_MARK_REACHED_REQUEST:
2830 mFrameMarkPosition = event->GetParam();
2831 HandleRenderMarkReachedEvent(mFrameMarkPosition);
2832 break;
2833 case SET_RENDERER_MARK_REACHED_REQUEST:
2834 renderPositionCb = event->GetSharedObject<RendererPositionCallback>();
2835 HandleSetRenderMarkReachedEvent(renderPositionCb);
2836 break;
2837 case UNSET_RENDERER_MARK_REACHED_REQUEST:
2838 HandleUnsetRenderMarkReachedEvent();
2839 break;
2840
2841 // RenderPeriodReach
2842 case RENDERER_PERIOD_REACHED_REQUEST:
2843 mFramePeriodNumber = event->GetParam();
2844 HandleRenderPeriodReachedEvent(mFramePeriodNumber);
2845 break;
2846 case SET_RENDERER_PERIOD_REACHED_REQUEST:
2847 renderPeriodPositionCb = event->GetSharedObject<RendererPeriodPositionCallback>();
2848 HandleSetRenderPeriodReachedEvent(renderPeriodPositionCb);
2849 break;
2850 case UNSET_RENDERER_PERIOD_REACHED_REQUEST:
2851 HandleUnsetRenderPeriodReachedEvent();
2852 break;
2853
2854 // CapturerMarkReach
2855 case CAPTURER_MARK_REACHED_REQUEST:
2856 mFrameMarkPosition = event->GetParam();
2857 HandleCapturerMarkReachedEvent(mFrameMarkPosition);
2858 break;
2859 case SET_CAPTURER_MARK_REACHED_REQUEST:
2860 capturePositionCb = event->GetSharedObject<CapturerPositionCallback>();
2861 HandleSetCapturerMarkReachedEvent(capturePositionCb);
2862 break;
2863 case UNSET_CAPTURER_MARK_REACHED_REQUEST:
2864 HandleUnsetCapturerMarkReachedEvent();
2865 break;
2866
2867 // CapturerPeriodReach
2868 case CAPTURER_PERIOD_REACHED_REQUEST:
2869 mFramePeriodNumber = event->GetParam();
2870 HandleCapturerPeriodReachedEvent(mFramePeriodNumber);
2871 break;
2872 case SET_CAPTURER_PERIOD_REACHED_REQUEST:
2873 capturePeriodPositionCb = event->GetSharedObject<CapturerPeriodPositionCallback>();
2874 HandleSetCapturerPeriodReachedEvent(capturePeriodPositionCb);
2875 break;
2876 case UNSET_CAPTURER_PERIOD_REACHED_REQUEST:
2877 HandleUnsetCapturerPeriodReachedEvent();
2878 break;
2879
2880 default:
2881 break;
2882 }
2883 }
2884
GetEffectModeName(AudioEffectMode effectMode)2885 const std::string AudioServiceClient::GetEffectModeName(AudioEffectMode effectMode)
2886 {
2887 std::string name;
2888 switch (effectMode) {
2889 case EFFECT_NONE:
2890 name = "EFFECT_NONE";
2891 break;
2892 default:
2893 name = "EFFECT_DEFAULT";
2894 }
2895
2896 const std::string modeName = name;
2897 return modeName;
2898 }
2899
GetStreamAudioEffectMode()2900 AudioEffectMode AudioServiceClient::GetStreamAudioEffectMode()
2901 {
2902 return effectMode;
2903 }
2904
GetStreamFramesWritten()2905 int64_t AudioServiceClient::GetStreamFramesWritten()
2906 {
2907 if (mFrameSize == 0) {
2908 AUDIO_ERR_LOG("Error frame size");
2909 return ERROR;
2910 }
2911 return mTotalBytesWritten / mFrameSize;
2912 }
2913
GetStreamFramesRead()2914 int64_t AudioServiceClient::GetStreamFramesRead()
2915 {
2916 if (mFrameSize == 0) {
2917 AUDIO_ERR_LOG("Error frame size");
2918 return ERROR;
2919 }
2920 return mTotalBytesRead / mFrameSize;
2921 }
2922
SetStreamAudioEffectMode(AudioEffectMode audioEffectMode)2923 int32_t AudioServiceClient::SetStreamAudioEffectMode(AudioEffectMode audioEffectMode)
2924 {
2925 AUDIO_INFO_LOG("SetStreamAudioEffectMode: %{public}d", audioEffectMode);
2926
2927 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2928 AUDIO_ERR_LOG("set stream audio effect mode: invalid stream state");
2929 return AUDIO_CLIENT_PA_ERR;
2930 }
2931
2932 pa_threaded_mainloop_lock(mainLoop);
2933
2934 effectMode = audioEffectMode;
2935 const std::string effectModeName = GetEffectModeName(audioEffectMode);
2936
2937 pa_proplist *propList = pa_proplist_new();
2938 if (propList == nullptr) {
2939 AUDIO_ERR_LOG("pa_proplist_new failed");
2940 pa_threaded_mainloop_unlock(mainLoop);
2941 return AUDIO_CLIENT_ERR;
2942 }
2943
2944 pa_proplist_sets(propList, "scene.type", effectSceneName.c_str());
2945 pa_proplist_sets(propList, "scene.mode", effectModeName.c_str());
2946 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2947 nullptr, nullptr);
2948 pa_stream_flush(paStream, NULL, NULL);
2949 pa_proplist_free(propList);
2950 pa_operation_unref(updatePropOperation);
2951
2952 pa_threaded_mainloop_unlock(mainLoop);
2953
2954 return AUDIO_CLIENT_SUCCESS;
2955 }
2956
SetStreamInnerCapturerState(bool isInnerCapturer)2957 void AudioServiceClient::SetStreamInnerCapturerState(bool isInnerCapturer)
2958 {
2959 AUDIO_DEBUG_LOG("SetInnerCapturerState: %{public}d", isInnerCapturer);
2960 isInnerCapturerStream_ = isInnerCapturer;
2961 }
2962
SetStreamPrivacyType(AudioPrivacyType privacyType)2963 void AudioServiceClient::SetStreamPrivacyType(AudioPrivacyType privacyType)
2964 {
2965 AUDIO_DEBUG_LOG("SetInnerCapturerState: %{public}d", privacyType);
2966 mPrivacyType = privacyType;
2967 }
2968
SetStreamUsage(StreamUsage usage)2969 void AudioServiceClient::SetStreamUsage(StreamUsage usage)
2970 {
2971 AUDIO_DEBUG_LOG("SetStreamUsage: %{public}d", usage);
2972 mStreamUsage = usage;
2973 }
2974
SetWakeupCapturerState(bool isWakeupCapturer)2975 void AudioServiceClient::SetWakeupCapturerState(bool isWakeupCapturer)
2976 {
2977 AUDIO_DEBUG_LOG("SetWakeupCapturerState: %{public}d", isWakeupCapturer);
2978 isWakeupCapturerStream_ = isWakeupCapturer;
2979 }
2980
2981 } // namespace AudioStandard
2982 } // namespace OHOS
2983