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_lock(mainLoop);
1554 pa_threaded_mainloop_signal(mainLoop, 0);
1555 pa_threaded_mainloop_unlock(mainLoop);
1556 }
1557
SetClientID(int32_t clientPid,int32_t clientUid)1558 void AudioServiceClient::SetClientID(int32_t clientPid, int32_t clientUid)
1559 {
1560 AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid);
1561 clientPid_ = clientPid;
1562 clientUid_ = clientUid;
1563 }
1564
HandleCapturePositionCallbacks(size_t bytesRead)1565 void AudioServiceClient::HandleCapturePositionCallbacks(size_t bytesRead)
1566 {
1567 mTotalBytesRead += bytesRead;
1568 if (mFrameSize == 0) {
1569 AUDIO_ERR_LOG("HandleCapturePositionCallbacks: capturePeriodPositionCb not set");
1570 return;
1571 }
1572
1573 uint64_t readFrameNumber = mTotalBytesRead / mFrameSize;
1574 AUDIO_DEBUG_LOG("frame size: %{public}d", mFrameSize);
1575 {
1576 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
1577 if (!mMarkReached) {
1578 AUDIO_DEBUG_LOG("frame mark position: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1579 static_cast<uint64_t>(mFrameMarkPosition), static_cast<uint64_t>(readFrameNumber));
1580 if (readFrameNumber >= mFrameMarkPosition) {
1581 AUDIO_DEBUG_LOG("audio service client capturer OnMarkReached");
1582 SendCapturerMarkReachedRequestEvent(mFrameMarkPosition);
1583 mMarkReached = true;
1584 }
1585 }
1586 }
1587
1588 {
1589 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
1590 mFramePeriodRead += (bytesRead / mFrameSize);
1591 AUDIO_DEBUG_LOG("frame period number: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1592 static_cast<uint64_t>(mFramePeriodNumber), static_cast<uint64_t>(readFrameNumber));
1593 if (mFramePeriodRead >= mFramePeriodNumber) {
1594 mFramePeriodRead %= mFramePeriodNumber;
1595 AUDIO_DEBUG_LOG("audio service client OnPeriodReached, remaining frames: %{public}" PRIu64,
1596 static_cast<uint64_t>(mFramePeriodRead));
1597 SendCapturerPeriodReachedRequestEvent(mFramePeriodNumber);
1598 }
1599 }
1600 }
1601
ReadStream(StreamBuffer & stream,bool isBlocking)1602 int32_t AudioServiceClient::ReadStream(StreamBuffer &stream, bool isBlocking)
1603 {
1604 uint8_t *buffer = stream.buffer;
1605 size_t length = stream.bufferLen;
1606 size_t readSize = 0;
1607 lock_guard<mutex> lock(dataMutex);
1608 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1609 return AUDIO_CLIENT_PA_ERR;
1610 }
1611
1612 pa_threaded_mainloop_lock(mainLoop);
1613 while (length > 0) {
1614 while (!internalReadBuffer) {
1615 int retVal = pa_stream_peek(paStream, &internalReadBuffer, &internalRdBufLen);
1616 if (retVal < 0) {
1617 AUDIO_ERR_LOG("pa_stream_peek failed, retVal: %{public}d", retVal);
1618 pa_threaded_mainloop_unlock(mainLoop);
1619 return AUDIO_CLIENT_READ_STREAM_ERR;
1620 }
1621
1622 if (internalRdBufLen <= 0) {
1623 if (isBlocking) {
1624 StartTimer(READ_TIMEOUT_IN_SEC);
1625 pa_threaded_mainloop_wait(mainLoop);
1626 StopTimer();
1627 if (IsTimeOut()) {
1628 AUDIO_ERR_LOG("Read timeout");
1629 pa_threaded_mainloop_unlock(mainLoop);
1630 return AUDIO_CLIENT_READ_STREAM_ERR;
1631 }
1632 } else {
1633 pa_threaded_mainloop_unlock(mainLoop);
1634 HandleCapturePositionCallbacks(readSize);
1635 return readSize;
1636 }
1637 } else if (!internalReadBuffer) {
1638 retVal = pa_stream_drop(paStream);
1639 if (retVal < 0) {
1640 AUDIO_ERR_LOG("pa_stream_drop failed, retVal: %{public}d", retVal);
1641 pa_threaded_mainloop_unlock(mainLoop);
1642 return AUDIO_CLIENT_READ_STREAM_ERR;
1643 }
1644 } else {
1645 internalRdBufIndex = 0;
1646 AUDIO_DEBUG_LOG("buffer size from PA: %{public}zu", internalRdBufLen);
1647 }
1648 }
1649
1650 if (UpdateReadBuffer(buffer, length, readSize) != 0) {
1651 pa_threaded_mainloop_unlock(mainLoop);
1652 return AUDIO_CLIENT_READ_STREAM_ERR;
1653 }
1654 buffer = stream.buffer + readSize;
1655 }
1656 pa_threaded_mainloop_unlock(mainLoop);
1657 HandleCapturePositionCallbacks(readSize);
1658
1659 return readSize;
1660 }
1661
ReleaseStream(bool releaseRunner)1662 int32_t AudioServiceClient::ReleaseStream(bool releaseRunner)
1663 {
1664 state_ = RELEASED;
1665 lock_guard<mutex> lockdata(dataMutex);
1666 WriteStateChangedSysEvents();
1667 ResetPAAudioClient();
1668
1669 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1670 if (streamCb != nullptr) {
1671 streamCb->OnStateChange(state_);
1672 }
1673
1674 {
1675 lock_guard<mutex> runnerlock(runnerMutex_);
1676 if (releaseRunner) {
1677 AUDIO_INFO_LOG("runner remove");
1678 SetEventRunner(nullptr);
1679 runnerReleased_ = true;
1680 }
1681 }
1682
1683 return AUDIO_CLIENT_SUCCESS;
1684 }
1685
SetBufferSizeInMsec(int32_t bufferSizeInMsec)1686 int32_t AudioServiceClient::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
1687 {
1688 size_t bufferSize = pa_usec_to_bytes(bufferSizeInMsec * PA_USEC_PER_MSEC, &sampleSpec);
1689 setBufferSize = bufferSize;
1690 return AUDIO_CLIENT_SUCCESS;
1691 }
1692
GetMinimumBufferSize(size_t & minBufferSize) const1693 int32_t AudioServiceClient::GetMinimumBufferSize(size_t &minBufferSize) const
1694 {
1695 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1696 return AUDIO_CLIENT_PA_ERR;
1697 }
1698
1699 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1700
1701 if (bufferAttr == nullptr) {
1702 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
1703 return AUDIO_CLIENT_ERR;
1704 }
1705
1706 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1707 if (renderMode_ == RENDER_MODE_CALLBACK) {
1708 minBufferSize = (size_t)bufferAttr->minreq;
1709 } else {
1710 if (setBufferSize) {
1711 minBufferSize = setBufferSize;
1712 } else {
1713 minBufferSize = (size_t)bufferAttr->minreq;
1714 }
1715 }
1716 }
1717
1718 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1719 minBufferSize = (size_t)bufferAttr->fragsize;
1720 }
1721
1722 return AUDIO_CLIENT_SUCCESS;
1723 }
1724
GetMinimumFrameCount(uint32_t & frameCount) const1725 int32_t AudioServiceClient::GetMinimumFrameCount(uint32_t &frameCount) const
1726 {
1727 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1728 return AUDIO_CLIENT_PA_ERR;
1729 }
1730
1731 size_t minBufferSize = 0;
1732
1733 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1734
1735 if (bufferAttr == nullptr) {
1736 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
1737 return AUDIO_CLIENT_ERR;
1738 }
1739
1740 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1741 if (renderMode_ == RENDER_MODE_CALLBACK) {
1742 minBufferSize = (size_t)bufferAttr->minreq;
1743 } else {
1744 if (setBufferSize) {
1745 minBufferSize = setBufferSize;
1746 } else {
1747 minBufferSize = (size_t)bufferAttr->minreq;
1748 }
1749 }
1750 }
1751
1752 if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1753 minBufferSize = (size_t)bufferAttr->fragsize;
1754 }
1755
1756 uint32_t bytesPerSample = pa_frame_size(&sampleSpec);
1757 if (bytesPerSample == 0) {
1758 AUDIO_ERR_LOG("GetMinimumFrameCount Failed");
1759 return AUDIO_CLIENT_ERR;
1760 }
1761
1762 frameCount = minBufferSize / bytesPerSample;
1763 AUDIO_INFO_LOG("frame count: %{private}d", frameCount);
1764 return AUDIO_CLIENT_SUCCESS;
1765 }
1766
GetSamplingRate() const1767 uint32_t AudioServiceClient::GetSamplingRate() const
1768 {
1769 return DEFAULT_SAMPLING_RATE;
1770 }
1771
GetChannelCount() const1772 uint8_t AudioServiceClient::GetChannelCount() const
1773 {
1774 return DEFAULT_CHANNEL_COUNT;
1775 }
1776
GetSampleSize() const1777 uint8_t AudioServiceClient::GetSampleSize() const
1778 {
1779 return DEFAULT_SAMPLE_SIZE;
1780 }
1781
GetAudioStreamParams(AudioStreamParams & audioParams) const1782 int32_t AudioServiceClient::GetAudioStreamParams(AudioStreamParams& audioParams) const
1783 {
1784 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1785 return AUDIO_CLIENT_PA_ERR;
1786 }
1787
1788 const pa_sample_spec *paSampleSpec = pa_stream_get_sample_spec(paStream);
1789
1790 if (!paSampleSpec) {
1791 AUDIO_ERR_LOG("GetAudioStreamParams Failed");
1792 return AUDIO_CLIENT_ERR;
1793 }
1794
1795 audioParams = ConvertFromPAAudioParams(*paSampleSpec);
1796 return AUDIO_CLIENT_SUCCESS;
1797 }
1798
GetStreamVolume(uint32_t sessionID)1799 uint32_t AudioServiceClient::GetStreamVolume(uint32_t sessionID)
1800 {
1801 return DEFAULT_STREAM_VOLUME;
1802 }
1803
GetCurrentTimeStamp(uint64_t & timeStamp)1804 int32_t AudioServiceClient::GetCurrentTimeStamp(uint64_t &timeStamp)
1805 {
1806 lock_guard<mutex> lock(dataMutex);
1807 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1808 return AUDIO_CLIENT_PA_ERR;
1809 }
1810 pa_threaded_mainloop_lock(mainLoop);
1811
1812 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1813 pa_operation *operation = pa_stream_update_timing_info(paStream, NULL, NULL);
1814 if (operation != nullptr) {
1815 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1816 pa_threaded_mainloop_wait(mainLoop);
1817 }
1818 pa_operation_unref(operation);
1819 } else {
1820 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
1821 }
1822 }
1823
1824 const pa_timing_info *info = pa_stream_get_timing_info(paStream);
1825 if (info == nullptr) {
1826 AUDIO_ERR_LOG("pa_stream_get_timing_info failed");
1827 pa_threaded_mainloop_unlock(mainLoop);
1828 return AUDIO_CLIENT_ERR;
1829 }
1830
1831 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1832 timeStamp = pa_bytes_to_usec(info->write_index, &sampleSpec);
1833 } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1834 if (pa_stream_get_time(paStream, &timeStamp)) {
1835 AUDIO_ERR_LOG("AudioServiceClient::GetCurrentTimeStamp failed for AUDIO_SERVICE_CLIENT_RECORD");
1836 pa_threaded_mainloop_unlock(mainLoop);
1837 return AUDIO_CLIENT_ERR;
1838 }
1839 int32_t uid = static_cast<int32_t>(getuid());
1840
1841 // 1013 is media_service's uid
1842 int32_t media_service = 1013;
1843 if (uid == media_service) {
1844 timeStamp = pa_bytes_to_usec(mTotalBytesRead, &sampleSpec);
1845 }
1846 }
1847
1848 pa_threaded_mainloop_unlock(mainLoop);
1849
1850 return AUDIO_CLIENT_SUCCESS;
1851 }
1852
GetAudioLatency(uint64_t & latency)1853 int32_t AudioServiceClient::GetAudioLatency(uint64_t &latency)
1854 {
1855 lock_guard<mutex> lock(dataMutex);
1856 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1857 return AUDIO_CLIENT_PA_ERR;
1858 }
1859 pa_usec_t paLatency {0};
1860 pa_usec_t cacheLatency {0};
1861 int negative {0};
1862
1863 // Get PA latency
1864 pa_threaded_mainloop_lock(mainLoop);
1865 while (true) {
1866 pa_operation *operation = pa_stream_update_timing_info(paStream, NULL, NULL);
1867 if (operation != nullptr) {
1868 pa_operation_unref(operation);
1869 } else {
1870 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
1871 }
1872 if (pa_stream_get_latency(paStream, &paLatency, &negative) >= 0) {
1873 if (negative) {
1874 latency = 0;
1875 pa_threaded_mainloop_unlock(mainLoop);
1876 return AUDIO_CLIENT_ERR;
1877 }
1878 break;
1879 }
1880 AUDIO_INFO_LOG("waiting for audio latency information");
1881 pa_threaded_mainloop_wait(mainLoop);
1882 }
1883 pa_threaded_mainloop_unlock(mainLoop);
1884
1885 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1886 // Get audio write cache latency
1887 cacheLatency = pa_bytes_to_usec((acache.totalCacheSize - acache.writeIndex), &sampleSpec);
1888
1889 // Total latency will be sum of audio write cache latency + PA latency
1890 uint64_t fwLatency = paLatency + cacheLatency;
1891 uint64_t sinkLatency = sinkLatencyInMsec_ * PA_USEC_PER_MSEC;
1892 if (fwLatency > sinkLatency) {
1893 latency = fwLatency - sinkLatency;
1894 } else {
1895 latency = fwLatency;
1896 }
1897 AUDIO_INFO_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}"
1898 PRIu64 ", cache latency: %{public}" PRIu64, latency, paLatency, cacheLatency);
1899 } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1900 // Get audio read cache latency
1901 cacheLatency = pa_bytes_to_usec(internalRdBufLen, &sampleSpec);
1902
1903 // Total latency will be sum of audio read cache latency + PA latency
1904 latency = paLatency + cacheLatency;
1905 AUDIO_INFO_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}" PRIu64, latency, paLatency);
1906 }
1907
1908 return AUDIO_CLIENT_SUCCESS;
1909 }
1910
RegisterAudioRendererCallbacks(const AudioRendererCallbacks & cb)1911 void AudioServiceClient::RegisterAudioRendererCallbacks(const AudioRendererCallbacks &cb)
1912 {
1913 AUDIO_INFO_LOG("Registering audio render callbacks");
1914 mAudioRendererCallbacks = (AudioRendererCallbacks *)&cb;
1915 }
1916
RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks & cb)1917 void AudioServiceClient::RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks &cb)
1918 {
1919 AUDIO_INFO_LOG("Registering audio record callbacks");
1920 mAudioCapturerCallbacks = (AudioCapturerCallbacks *)&cb;
1921 }
1922
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1923 void AudioServiceClient::SetRendererPositionCallback(int64_t markPosition,
1924 const std::shared_ptr<RendererPositionCallback> &callback)
1925 {
1926 std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
1927 AUDIO_INFO_LOG("Registering render frame position callback mark position: %{public}" PRIu64, markPosition);
1928 mFrameMarkPosition = markPosition;
1929 SendSetRenderMarkReachedRequestEvent(callback);
1930 mMarkReached = false;
1931 }
1932
UnsetRendererPositionCallback()1933 void AudioServiceClient::UnsetRendererPositionCallback()
1934 {
1935 AUDIO_INFO_LOG("Unregistering render frame position callback");
1936 std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
1937 SendUnsetRenderMarkReachedRequestEvent();
1938 mMarkReached = false;
1939 mFrameMarkPosition = 0;
1940 }
1941
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)1942 void AudioServiceClient::SetRendererPeriodPositionCallback(int64_t periodPosition,
1943 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
1944 {
1945 std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
1946 AUDIO_INFO_LOG("Registering render period position callback");
1947 mFramePeriodNumber = periodPosition;
1948 if ((mFrameSize != 0) && (mFramePeriodNumber != 0)) {
1949 mFramePeriodWritten = (mTotalBytesWritten / mFrameSize) % mFramePeriodNumber;
1950 } else {
1951 AUDIO_ERR_LOG("AudioServiceClient::SetRendererPeriodPositionCallback failed");
1952 return;
1953 }
1954 SendSetRenderPeriodReachedRequestEvent(callback);
1955 }
1956
UnsetRendererPeriodPositionCallback()1957 void AudioServiceClient::UnsetRendererPeriodPositionCallback()
1958 {
1959 AUDIO_INFO_LOG("Unregistering render period position callback");
1960 std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
1961 SendUnsetRenderPeriodReachedRequestEvent();
1962 mFramePeriodWritten = 0;
1963 mFramePeriodNumber = 0;
1964 }
1965
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)1966 void AudioServiceClient::SetCapturerPositionCallback(int64_t markPosition,
1967 const std::shared_ptr<CapturerPositionCallback> &callback)
1968 {
1969 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
1970 AUDIO_INFO_LOG("Registering capture frame position callback, mark position: %{public}" PRIu64, markPosition);
1971 mFrameMarkPosition = markPosition;
1972 SendSetCapturerMarkReachedRequestEvent(callback);
1973 mMarkReached = false;
1974 }
1975
UnsetCapturerPositionCallback()1976 void AudioServiceClient::UnsetCapturerPositionCallback()
1977 {
1978 AUDIO_INFO_LOG("Unregistering capture frame position callback");
1979 std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
1980 SendUnsetCapturerMarkReachedRequestEvent();
1981 mMarkReached = false;
1982 mFrameMarkPosition = 0;
1983 }
1984
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)1985 void AudioServiceClient::SetCapturerPeriodPositionCallback(int64_t periodPosition,
1986 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
1987 {
1988 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
1989 AUDIO_INFO_LOG("Registering period position callback");
1990 mFramePeriodNumber = periodPosition;
1991 if ((mFrameSize != 0) && (mFramePeriodNumber) != 0) {
1992 mFramePeriodRead = (mTotalBytesRead / mFrameSize) % mFramePeriodNumber;
1993 } else {
1994 AUDIO_INFO_LOG("AudioServiceClient::SetCapturerPeriodPositionCallback failed");
1995 return;
1996 }
1997 SendSetCapturerPeriodReachedRequestEvent(callback);
1998 }
1999
UnsetCapturerPeriodPositionCallback()2000 void AudioServiceClient::UnsetCapturerPeriodPositionCallback()
2001 {
2002 AUDIO_INFO_LOG("Unregistering period position callback");
2003 std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
2004 SendUnsetCapturerPeriodReachedRequestEvent();
2005 mFramePeriodRead = 0;
2006 mFramePeriodNumber = 0;
2007 }
2008
SetStreamType(AudioStreamType audioStreamType)2009 int32_t AudioServiceClient::SetStreamType(AudioStreamType audioStreamType)
2010 {
2011 AUDIO_INFO_LOG("SetStreamType: %{public}d", audioStreamType);
2012
2013 if (context == nullptr) {
2014 AUDIO_ERR_LOG("context is null");
2015 return AUDIO_CLIENT_ERR;
2016 }
2017
2018 pa_threaded_mainloop_lock(mainLoop);
2019
2020 mStreamType = audioStreamType;
2021 const std::string streamName = GetStreamName(audioStreamType);
2022
2023 pa_proplist *propList = pa_proplist_new();
2024 if (propList == nullptr) {
2025 AUDIO_ERR_LOG("pa_proplist_new failed");
2026 pa_threaded_mainloop_unlock(mainLoop);
2027 return AUDIO_CLIENT_ERR;
2028 }
2029
2030 pa_proplist_sets(propList, "stream.type", streamName.c_str());
2031 pa_proplist_sets(propList, "media.name", streamName.c_str());
2032 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2033 nullptr, nullptr);
2034 pa_proplist_free(propList);
2035 pa_operation_unref(updatePropOperation);
2036
2037 pa_threaded_mainloop_unlock(mainLoop);
2038
2039 return AUDIO_CLIENT_SUCCESS;
2040 }
2041
SetStreamVolume(float volume)2042 int32_t AudioServiceClient::SetStreamVolume(float volume)
2043 {
2044 lock_guard<mutex> lock(ctrlMutex);
2045 AUDIO_INFO_LOG("SetVolume volume: %{public}f", volume);
2046
2047 if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2048 AUDIO_ERR_LOG("set stream volume: invalid stream state");
2049 return AUDIO_CLIENT_PA_ERR;
2050 }
2051
2052 /* Validate and return INVALID_PARAMS error */
2053 if ((volume < MIN_STREAM_VOLUME_LEVEL) || (volume > MAX_STREAM_VOLUME_LEVEL)) {
2054 AUDIO_ERR_LOG("Invalid Volume Input!");
2055 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2056 }
2057
2058 int32_t volumeFactor = AudioSystemManager::MapVolumeFromHDI(mVolumeFactor);
2059 int32_t newVolumeFactor = AudioSystemManager::MapVolumeFromHDI(volume);
2060 if (newVolumeFactor > volumeFactor) {
2061 mUnMute_ = true;
2062 }
2063 AUDIO_INFO_LOG("mUnMute_ %{public}d", mUnMute_);
2064 pa_threaded_mainloop_lock(mainLoop);
2065
2066 mVolumeFactor = volume;
2067 pa_proplist *propList = pa_proplist_new();
2068 if (propList == nullptr) {
2069 AUDIO_ERR_LOG("pa_proplist_new failed");
2070 pa_threaded_mainloop_unlock(mainLoop);
2071 return AUDIO_CLIENT_ERR;
2072 }
2073
2074 pa_proplist_sets(propList, "stream.volumeFactor", std::to_string(mVolumeFactor).c_str());
2075 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2076 nullptr, nullptr);
2077 if (updatePropOperation == nullptr) {
2078 AUDIO_ERR_LOG("pa_stream_proplist_update returned null");
2079 pa_proplist_free(propList);
2080 pa_threaded_mainloop_unlock(mainLoop);
2081 return AUDIO_CLIENT_ERR;
2082 }
2083
2084 pa_proplist_free(propList);
2085 pa_operation_unref(updatePropOperation);
2086
2087 if (mAudioSystemMgr == nullptr) {
2088 AUDIO_ERR_LOG("System manager instance is null");
2089 pa_threaded_mainloop_unlock(mainLoop);
2090 return AUDIO_CLIENT_ERR;
2091 }
2092
2093 if (!streamInfoUpdated) {
2094 uint32_t idx = pa_stream_get_index(paStream);
2095 pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
2096 reinterpret_cast<void *>(this));
2097 if (operation == nullptr) {
2098 AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
2099 pa_threaded_mainloop_unlock(mainLoop);
2100 return AUDIO_CLIENT_ERR;
2101 }
2102
2103 pa_threaded_mainloop_accept(mainLoop);
2104
2105 pa_operation_unref(operation);
2106 } else {
2107 SetPaVolume(*this);
2108 }
2109
2110 pa_threaded_mainloop_unlock(mainLoop);
2111
2112 return AUDIO_CLIENT_SUCCESS;
2113 }
2114
GetStreamVolume()2115 float AudioServiceClient::GetStreamVolume()
2116 {
2117 return mVolumeFactor;
2118 }
2119
GetSinkInputInfoCb(pa_context * context,const pa_sink_input_info * info,int eol,void * userdata)2120 void AudioServiceClient::GetSinkInputInfoCb(pa_context *context, const pa_sink_input_info *info, int eol,
2121 void *userdata)
2122 {
2123 AUDIO_INFO_LOG("GetSinkInputInfoVolumeCb in");
2124 AudioServiceClient *thiz = reinterpret_cast<AudioServiceClient *>(userdata);
2125
2126 if (eol < 0) {
2127 AUDIO_ERR_LOG("Failed to get sink input information: %{public}s", pa_strerror(pa_context_errno(context)));
2128 return;
2129 }
2130
2131 if (eol) {
2132 pa_threaded_mainloop_signal(thiz->mainLoop, 1);
2133 return;
2134 }
2135
2136 if (info->proplist == nullptr) {
2137 AUDIO_ERR_LOG("Invalid prop list for sink input (%{public}d).", info->index);
2138 return;
2139 }
2140
2141 uint32_t sessionID = 0;
2142 const char *sessionCStr = pa_proplist_gets(info->proplist, "stream.sessionID");
2143 if (sessionCStr != nullptr) {
2144 std::stringstream sessionStr;
2145 sessionStr << sessionCStr;
2146 sessionStr >> sessionID;
2147 }
2148
2149 thiz->cvolume = info->volume;
2150 thiz->streamIndex = info->index;
2151 thiz->sessionID = sessionID;
2152 thiz->volumeChannels = info->channel_map.channels;
2153 thiz->streamInfoUpdated = true;
2154
2155 SetPaVolume(*thiz);
2156
2157 return;
2158 }
2159
SetPaVolume(const AudioServiceClient & client)2160 void AudioServiceClient::SetPaVolume(const AudioServiceClient &client)
2161 {
2162 pa_cvolume cv = client.cvolume;
2163 int32_t systemVolumeInt
2164 = client.mAudioSystemMgr->GetVolume(static_cast<AudioVolumeType>(client.mStreamType));
2165 float systemVolume = AudioSystemManager::MapVolumeToHDI(systemVolumeInt);
2166 float vol = systemVolume * client.mVolumeFactor * client.mPowerVolumeFactor;
2167
2168 AudioRingerMode ringerMode = client.mAudioSystemMgr->GetRingerMode();
2169 if ((client.mStreamType == STREAM_RING) && (ringerMode != RINGER_MODE_NORMAL)) {
2170 vol = MIN_STREAM_VOLUME_LEVEL;
2171 }
2172
2173 if (client.mAudioSystemMgr->IsStreamMute(static_cast<AudioVolumeType>(client.mStreamType))) {
2174 if (client.mUnMute_) {
2175 client.mAudioSystemMgr->SetMute(static_cast<AudioVolumeType>(client.mStreamType),
2176 false);
2177 } else {
2178 vol = MIN_STREAM_VOLUME_LEVEL;
2179 }
2180 }
2181 uint32_t volume = pa_sw_volume_from_linear(vol);
2182 pa_cvolume_set(&cv, client.volumeChannels, volume);
2183 pa_operation_unref(pa_context_set_sink_input_volume(client.context, client.streamIndex, &cv, nullptr, nullptr));
2184
2185 AUDIO_INFO_LOG("Applied volume : %{public}f, pa volume: %{public}d", vol, volume);
2186 HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_VOLUME_CHANGE", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
2187 "ISOUTPUT", 1,
2188 "STREAMID", client.sessionID,
2189 "STREAMTYPE", client.mStreamType,
2190 "VOLUME", vol);
2191 }
2192
SetStreamRenderRate(AudioRendererRate audioRendererRate)2193 int32_t AudioServiceClient::SetStreamRenderRate(AudioRendererRate audioRendererRate)
2194 {
2195 AUDIO_INFO_LOG("SetStreamRenderRate in");
2196 if (!paStream) {
2197 return AUDIO_CLIENT_SUCCESS;
2198 }
2199
2200 uint32_t rate = sampleSpec.rate;
2201 switch (audioRendererRate) {
2202 case RENDER_RATE_NORMAL:
2203 break;
2204 case RENDER_RATE_DOUBLE:
2205 rate *= DOUBLE_VALUE;
2206 break;
2207 case RENDER_RATE_HALF:
2208 rate /= DOUBLE_VALUE;
2209 break;
2210 default:
2211 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2212 }
2213 renderRate = audioRendererRate;
2214
2215 pa_threaded_mainloop_lock(mainLoop);
2216 pa_operation *operation = pa_stream_update_sample_rate(paStream, rate, nullptr, nullptr);
2217 pa_operation_unref(operation);
2218 pa_threaded_mainloop_unlock(mainLoop);
2219
2220 return AUDIO_CLIENT_SUCCESS;
2221 }
2222
GetStreamRenderRate()2223 AudioRendererRate AudioServiceClient::GetStreamRenderRate()
2224 {
2225 return renderRate;
2226 }
2227
SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> & callback)2228 void AudioServiceClient::SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> &callback)
2229 {
2230 streamCallback_ = callback;
2231
2232 if (state_ != PREPARED) {
2233 return;
2234 }
2235
2236 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
2237 if (streamCb != nullptr) {
2238 streamCb->OnStateChange(state_);
2239 }
2240 }
2241
WriteStateChangedSysEvents()2242 void AudioServiceClient::WriteStateChangedSysEvents()
2243 {
2244 uint32_t sessionID = 0;
2245 uint64_t transactionId = 0;
2246 DeviceType deviceType = DEVICE_TYPE_INVALID;
2247
2248 bool isOutput = true;
2249 if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2250 deviceType = mAudioSystemMgr->GetActiveOutputDevice();
2251 transactionId = mAudioSystemMgr->GetTransactionId(deviceType, OUTPUT_DEVICE);
2252 } else {
2253 deviceType = mAudioSystemMgr->GetActiveInputDevice();
2254 transactionId = mAudioSystemMgr->GetTransactionId(deviceType, INPUT_DEVICE);
2255 isOutput = false;
2256 }
2257
2258 GetSessionID(sessionID);
2259
2260 HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_STREAM_CHANGE",
2261 HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
2262 "ISOUTPUT", isOutput ? 1 : 0,
2263 "STREAMID", sessionID,
2264 "UID", clientUid_,
2265 "PID", clientPid_,
2266 "TRANSACTIONID", transactionId,
2267 "STREAMTYPE", mStreamType,
2268 "STATE", state_,
2269 "DEVICETYPE", deviceType);
2270 }
2271
SetStreamLowPowerVolume(float powerVolumeFactor)2272 int32_t AudioServiceClient::SetStreamLowPowerVolume(float powerVolumeFactor)
2273 {
2274 lock_guard<mutex> lock(ctrlMutex);
2275 AUDIO_INFO_LOG("SetPowerVolumeFactor volume: %{public}f", powerVolumeFactor);
2276
2277 if (context == nullptr) {
2278 AUDIO_ERR_LOG("context is null");
2279 return AUDIO_CLIENT_ERR;
2280 }
2281
2282 /* Validate and return INVALID_PARAMS error */
2283 if ((powerVolumeFactor < MIN_STREAM_VOLUME_LEVEL) || (powerVolumeFactor > MAX_STREAM_VOLUME_LEVEL)) {
2284 AUDIO_ERR_LOG("Invalid Power Volume Set!");
2285 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2286 }
2287
2288 pa_threaded_mainloop_lock(mainLoop);
2289
2290 mPowerVolumeFactor = powerVolumeFactor;
2291 pa_proplist *propList = pa_proplist_new();
2292 if (propList == nullptr) {
2293 AUDIO_ERR_LOG("pa_proplist_new failed");
2294 pa_threaded_mainloop_unlock(mainLoop);
2295 return AUDIO_CLIENT_ERR;
2296 }
2297
2298 pa_proplist_sets(propList, "stream.powerVolumeFactor", std::to_string(mPowerVolumeFactor).c_str());
2299 pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2300 nullptr, nullptr);
2301 pa_proplist_free(propList);
2302 pa_operation_unref(updatePropOperation);
2303
2304 if (mAudioSystemMgr == nullptr) {
2305 AUDIO_ERR_LOG("System manager instance is null");
2306 pa_threaded_mainloop_unlock(mainLoop);
2307 return AUDIO_CLIENT_ERR;
2308 }
2309
2310 if (!streamInfoUpdated) {
2311 uint32_t idx = pa_stream_get_index(paStream);
2312 pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
2313 reinterpret_cast<void *>(this));
2314 if (operation == nullptr) {
2315 AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
2316 pa_threaded_mainloop_unlock(mainLoop);
2317 return AUDIO_CLIENT_ERR;
2318 }
2319
2320 pa_threaded_mainloop_accept(mainLoop);
2321
2322 pa_operation_unref(operation);
2323 } else {
2324 SetPaVolume(*this);
2325 }
2326
2327 pa_threaded_mainloop_unlock(mainLoop);
2328
2329 return AUDIO_CLIENT_SUCCESS;
2330 }
2331
GetStreamLowPowerVolume()2332 float AudioServiceClient::GetStreamLowPowerVolume()
2333 {
2334 return mPowerVolumeFactor;
2335 }
2336
GetSingleStreamVol()2337 float AudioServiceClient::GetSingleStreamVol()
2338 {
2339 int32_t systemVolumeInt = mAudioSystemMgr->GetVolume(static_cast<AudioVolumeType>(mStreamType));
2340 float systemVolume = AudioSystemManager::MapVolumeToHDI(systemVolumeInt);
2341 float vol = systemVolume * mVolumeFactor * mPowerVolumeFactor;
2342
2343 AudioRingerMode ringerMode = mAudioSystemMgr->GetRingerMode();
2344 if ((mStreamType == STREAM_RING) && (ringerMode != RINGER_MODE_NORMAL)) {
2345 vol = MIN_STREAM_VOLUME_LEVEL;
2346 }
2347
2348 if (mAudioSystemMgr->IsStreamMute(static_cast<AudioVolumeType>(mStreamType))) {
2349 if (mUnMute_) {
2350 mAudioSystemMgr->SetMute(static_cast<AudioVolumeType>(mStreamType), false);
2351 } else {
2352 vol = MIN_STREAM_VOLUME_LEVEL;
2353 }
2354 }
2355
2356 return vol;
2357 }
2358
2359 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)2360 void AudioServiceClient::SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
2361 {
2362 lock_guard<mutex> runnerlock(runnerMutex_);
2363 if (runnerReleased_) {
2364 AUDIO_WARNING_LOG("AudioServiceClient::SendRenderMarkReachedRequestEvent runner released");
2365 return;
2366 }
2367 SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_MARK_REACHED_REQUEST, mFrameMarkPosition));
2368 }
2369
HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)2370 void AudioServiceClient::HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)
2371 {
2372 if (mRenderPositionCb) {
2373 mRenderPositionCb->OnMarkReached(mFrameMarkPosition);
2374 }
2375 }
2376
2377 // SetRenderMarkReached by eventHandler
SendSetRenderMarkReachedRequestEvent(const std::shared_ptr<RendererPositionCallback> & callback)2378 void AudioServiceClient::SendSetRenderMarkReachedRequestEvent(
2379 const std::shared_ptr<RendererPositionCallback> &callback)
2380 {
2381 lock_guard<mutex> runnerlock(runnerMutex_);
2382 if (runnerReleased_) {
2383 AUDIO_WARNING_LOG("AudioServiceClient::SendSetRenderMarkReachedRequestEvent runner released");
2384 return;
2385 }
2386 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_MARK_REACHED_REQUEST, callback));
2387 }
2388
HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> & callback)2389 void AudioServiceClient::HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> &callback)
2390 {
2391 mRenderPositionCb = callback;
2392 }
2393
2394 // UnsetRenderMarkReach by eventHandler
SendUnsetRenderMarkReachedRequestEvent()2395 void AudioServiceClient::SendUnsetRenderMarkReachedRequestEvent()
2396 {
2397 lock_guard<mutex> runnerlock(runnerMutex_);
2398 if (runnerReleased_) {
2399 AUDIO_WARNING_LOG("AudioServiceClient::SendUnsetRenderMarkReachedRequestEvent runner released");
2400 return;
2401 }
2402 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_MARK_REACHED_REQUEST));
2403 }
2404
HandleUnsetRenderMarkReachedEvent()2405 void AudioServiceClient::HandleUnsetRenderMarkReachedEvent()
2406 {
2407 mRenderPositionCb = nullptr;
2408 }
2409
2410 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)2411 void AudioServiceClient::SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
2412 {
2413 lock_guard<mutex> runnerlock(runnerMutex_);
2414 if (runnerReleased_) {
2415 AUDIO_WARNING_LOG("AudioServiceClient::SendRenderPeriodReachedRequestEvent runner released");
2416 return;
2417 }
2418 SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
2419 }
2420
HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)2421 void AudioServiceClient::HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)
2422 {
2423 if (mRenderPeriodPositionCb) {
2424 mRenderPeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
2425 }
2426 }
2427
2428 // SetRenderPeriodReach by eventHandler
SendSetRenderPeriodReachedRequestEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)2429 void AudioServiceClient::SendSetRenderPeriodReachedRequestEvent(
2430 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2431 {
2432 lock_guard<mutex> runnerlock(runnerMutex_);
2433 if (runnerReleased_) {
2434 AUDIO_WARNING_LOG("AudioServiceClient::SendSetRenderPeriodReachedRequestEvent runner released");
2435 return;
2436 }
2437 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_PERIOD_REACHED_REQUEST, callback));
2438 }
2439
HandleSetRenderPeriodReachedEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)2440 void AudioServiceClient::HandleSetRenderPeriodReachedEvent(
2441 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2442 {
2443 if (callback) {
2444 mRenderPeriodPositionCb = callback;
2445 }
2446 }
2447
2448 // UnsetRenderPeriodReach by eventHandler
SendUnsetRenderPeriodReachedRequestEvent()2449 void AudioServiceClient::SendUnsetRenderPeriodReachedRequestEvent()
2450 {
2451 lock_guard<mutex> runnerlock(runnerMutex_);
2452 if (runnerReleased_) {
2453 AUDIO_WARNING_LOG("AudioServiceClient::SendUnsetRenderPeriodReachedRequestEvent runner released");
2454 return;
2455 }
2456 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_PERIOD_REACHED_REQUEST));
2457 }
2458
HandleUnsetRenderPeriodReachedEvent()2459 void AudioServiceClient::HandleUnsetRenderPeriodReachedEvent()
2460 {
2461 mRenderPeriodPositionCb = nullptr;
2462 }
2463
2464 // OnCapturerMarkReach by eventHandler
SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)2465 void AudioServiceClient::SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
2466 {
2467 lock_guard<mutex> runnerlock(runnerMutex_);
2468 if (runnerReleased_) {
2469 AUDIO_WARNING_LOG("AudioServiceClient::SendCapturerMarkReachedRequestEvent runner released");
2470 return;
2471 }
2472 SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_MARK_REACHED_REQUEST, mFrameMarkPosition));
2473 }
2474
HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)2475 void AudioServiceClient::HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)
2476 {
2477 if (mCapturePositionCb) {
2478 mCapturePositionCb->OnMarkReached(mFrameMarkPosition);
2479 }
2480 }
2481
2482 // SetCapturerMarkReach by eventHandler
SendSetCapturerMarkReachedRequestEvent(const std::shared_ptr<CapturerPositionCallback> & callback)2483 void AudioServiceClient::SendSetCapturerMarkReachedRequestEvent(
2484 const std::shared_ptr<CapturerPositionCallback> &callback)
2485 {
2486 lock_guard<mutex> runnerlock(runnerMutex_);
2487 if (runnerReleased_) {
2488 AUDIO_WARNING_LOG("AudioServiceClient::SendSetCapturerMarkReachedRequestEvent runner released");
2489 return;
2490 }
2491 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_MARK_REACHED_REQUEST, callback));
2492 }
2493
HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> & callback)2494 void AudioServiceClient::HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> &callback)
2495 {
2496 mCapturePositionCb = callback;
2497 }
2498
2499 // UnsetCapturerMarkReach by eventHandler
SendUnsetCapturerMarkReachedRequestEvent()2500 void AudioServiceClient::SendUnsetCapturerMarkReachedRequestEvent()
2501 {
2502 lock_guard<mutex> runnerlock(runnerMutex_);
2503 if (runnerReleased_) {
2504 AUDIO_WARNING_LOG("AudioServiceClient::SendUnsetCapturerMarkReachedRequestEvent runner released");
2505 return;
2506 }
2507 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_MARK_REACHED_REQUEST));
2508 }
2509
HandleUnsetCapturerMarkReachedEvent()2510 void AudioServiceClient::HandleUnsetCapturerMarkReachedEvent()
2511 {
2512 mCapturePositionCb = nullptr;
2513 }
2514
2515 // OnCapturerPeriodReach by eventHandler
SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)2516 void AudioServiceClient::SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
2517 {
2518 lock_guard<mutex> runnerlock(runnerMutex_);
2519 if (runnerReleased_) {
2520 AUDIO_WARNING_LOG("AudioServiceClient::SendCapturerPeriodReachedRequestEvent runner released");
2521 return;
2522 }
2523 SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
2524 }
2525
HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)2526 void AudioServiceClient::HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)
2527 {
2528 if (mCapturePeriodPositionCb) {
2529 mCapturePeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
2530 }
2531 }
2532
2533 // SetCapturerPeriodReach by eventHandler
SendSetCapturerPeriodReachedRequestEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2534 void AudioServiceClient::SendSetCapturerPeriodReachedRequestEvent(
2535 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2536 {
2537 lock_guard<mutex> runnerlock(runnerMutex_);
2538 if (runnerReleased_) {
2539 AUDIO_WARNING_LOG("AudioServiceClient::SendSetCapturerPeriodReachedRequestEvent runner released");
2540 return;
2541 }
2542 SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_PERIOD_REACHED_REQUEST, callback));
2543 }
2544
HandleSetCapturerPeriodReachedEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2545 void AudioServiceClient::HandleSetCapturerPeriodReachedEvent(
2546 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2547 {
2548 mCapturePeriodPositionCb = callback;
2549 }
2550
2551 // UnsetCapturerPeriodReach by eventHandler
SendUnsetCapturerPeriodReachedRequestEvent()2552 void AudioServiceClient::SendUnsetCapturerPeriodReachedRequestEvent()
2553 {
2554 lock_guard<mutex> runnerlock(runnerMutex_);
2555 if (runnerReleased_) {
2556 AUDIO_WARNING_LOG("AudioServiceClient::SendUnsetCapturerPeriodReachedRequestEvent runner released");
2557 return;
2558 }
2559 SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_PERIOD_REACHED_REQUEST));
2560 }
2561
HandleUnsetCapturerPeriodReachedEvent()2562 void AudioServiceClient::HandleUnsetCapturerPeriodReachedEvent()
2563 {
2564 mCapturePeriodPositionCb = nullptr;
2565 }
2566
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)2567 int32_t AudioServiceClient::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
2568 {
2569 if (!callback) {
2570 AUDIO_ERR_LOG("AudioServiceClient::SetRendererWriteCallback callback is nullptr");
2571 return ERR_INVALID_PARAM;
2572 }
2573 writeCallback_ = callback;
2574 return SUCCESS;
2575 }
SendWriteBufferRequestEvent()2576 void AudioServiceClient::SendWriteBufferRequestEvent()
2577 {
2578 // send write event to handler
2579 lock_guard<mutex> runnerlock(runnerMutex_);
2580 if (runnerReleased_) {
2581 AUDIO_WARNING_LOG("AudioServiceClient::SendWriteBufferRequestEvent runner released");
2582 return;
2583 }
2584 SendEvent(AppExecFwk::InnerEvent::Get(WRITE_BUFFER_REQUEST));
2585 }
2586
HandleWriteRequestEvent()2587 void AudioServiceClient::HandleWriteRequestEvent()
2588 {
2589 // do callback to application
2590 if (writeCallback_) {
2591 size_t requestSize;
2592 GetMinimumBufferSize(requestSize);
2593 writeCallback_->OnWriteData(requestSize);
2594 }
2595 }
2596
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)2597 void AudioServiceClient::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
2598 {
2599 uint32_t eventId = event->GetInnerEventId();
2600 uint64_t mFrameMarkPosition;
2601 uint64_t mFramePeriodNumber;
2602 std::shared_ptr<RendererPositionCallback> renderPositionCb;
2603 std::shared_ptr<RendererPeriodPositionCallback> renderPeriodPositionCb;
2604 std::shared_ptr<CapturerPositionCallback> capturePositionCb;
2605 std::shared_ptr<CapturerPeriodPositionCallback> capturePeriodPositionCb;
2606
2607 switch (eventId) {
2608 case WRITE_BUFFER_REQUEST:
2609 HandleWriteRequestEvent();
2610 break;
2611
2612 // RenderMarkReach
2613 case RENDERER_MARK_REACHED_REQUEST:
2614 mFrameMarkPosition = event->GetParam();
2615 HandleRenderMarkReachedEvent(mFrameMarkPosition);
2616 break;
2617 case SET_RENDERER_MARK_REACHED_REQUEST:
2618 renderPositionCb = event->GetSharedObject<RendererPositionCallback>();
2619 HandleSetRenderMarkReachedEvent(renderPositionCb);
2620 break;
2621 case UNSET_RENDERER_MARK_REACHED_REQUEST:
2622 HandleUnsetRenderMarkReachedEvent();
2623 break;
2624
2625 // RenderPeriodReach
2626 case RENDERER_PERIOD_REACHED_REQUEST:
2627 mFramePeriodNumber = event->GetParam();
2628 HandleRenderPeriodReachedEvent(mFramePeriodNumber);
2629 break;
2630 case SET_RENDERER_PERIOD_REACHED_REQUEST:
2631 renderPeriodPositionCb = event->GetSharedObject<RendererPeriodPositionCallback>();
2632 HandleSetRenderPeriodReachedEvent(renderPeriodPositionCb);
2633 break;
2634 case UNSET_RENDERER_PERIOD_REACHED_REQUEST:
2635 HandleUnsetRenderPeriodReachedEvent();
2636 break;
2637
2638 // CapturerMarkReach
2639 case CAPTURER_MARK_REACHED_REQUEST:
2640 mFrameMarkPosition = event->GetParam();
2641 HandleCapturerMarkReachedEvent(mFrameMarkPosition);
2642 break;
2643 case SET_CAPTURER_MARK_REACHED_REQUEST:
2644 capturePositionCb = event->GetSharedObject<CapturerPositionCallback>();
2645 HandleSetCapturerMarkReachedEvent(capturePositionCb);
2646 break;
2647 case UNSET_CAPTURER_MARK_REACHED_REQUEST:
2648 HandleUnsetCapturerMarkReachedEvent();
2649 break;
2650
2651 // CapturerPeriodReach
2652 case CAPTURER_PERIOD_REACHED_REQUEST:
2653 mFramePeriodNumber = event->GetParam();
2654 HandleCapturerPeriodReachedEvent(mFramePeriodNumber);
2655 break;
2656 case SET_CAPTURER_PERIOD_REACHED_REQUEST:
2657 capturePeriodPositionCb = event->GetSharedObject<CapturerPeriodPositionCallback>();
2658 HandleSetCapturerPeriodReachedEvent(capturePeriodPositionCb);
2659 break;
2660 case UNSET_CAPTURER_PERIOD_REACHED_REQUEST:
2661 HandleUnsetCapturerPeriodReachedEvent();
2662 break;
2663
2664 default:
2665 break;
2666 }
2667 }
2668
2669 } // namespace AudioStandard
2670 } // namespace OHOS
2671