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