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