• 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 "safe_map.h"
22 #include "iservice_registry.h"
23 #include "audio_log.h"
24 #include "audio_utils.h"
25 #include "hisysevent.h"
26 #include "securec.h"
27 #include "system_ability_definition.h"
28 #include "unistd.h"
29 #include "audio_errors.h"
30 #include "audio_info.h"
31 #include "parameters.h"
32 #ifdef FEATURE_POWER_MANAGER
33 #include "power_mgr_client.h"
34 #endif
35 
36 using namespace std;
37 
38 namespace OHOS {
39 namespace AudioStandard {
40 static SafeMap<AudioServiceClient *, bool> serviceClientInstanceMap_;
41 AudioRendererCallbacks::~AudioRendererCallbacks() = default;
42 AudioCapturerCallbacks::~AudioCapturerCallbacks() = default;
43 const uint32_t CHECK_UTIL_SUCCESS = 0;
44 const uint32_t INIT_TIMEOUT_IN_SEC = 3;
45 const uint32_t CONNECT_TIMEOUT_IN_SEC = 10;
46 const uint32_t DRAIN_TIMEOUT_IN_SEC = 3;
47 const uint32_t CORK_TIMEOUT_IN_SEC = 3;
48 const uint32_t WRITE_TIMEOUT_IN_SEC = 8;
49 const uint32_t READ_TIMEOUT_IN_SEC = 5;
50 const uint32_t FLUSH_TIMEOUT_IN_SEC = 5;
51 const uint32_t MAINLOOP_WAIT_TIMEOUT_IN_SEC = 5;
52 const uint32_t DOUBLE_VALUE = 2;
53 const uint32_t MAX_LENGTH_FACTOR = 5;
54 const uint32_t T_LENGTH_FACTOR = 4;
55 const uint32_t MAX_LENGTH_OFFLOAD = 500;
56 const uint64_t MIN_BUF_DURATION_IN_USEC = 92880;
57 const uint32_t LATENCY_THRESHOLD = 35;
58 const int32_t NO_OF_PREBUF_TIMES = 6;
59 const int32_t OFFLOAD_HDI_CACHE1 = 200; // ms, should equal with val in hdi_sink.c
60 const int32_t OFFLOAD_HDI_CACHE2 = 7000; // ms, should equal with val in hdi_sink.c
61 const uint32_t OFFLOAD_BUFFER = 50;
62 const uint64_t AUDIO_US_PER_MS = 1000;
63 const uint64_t AUDIO_NS_PER_US = 1000;
64 const uint64_t AUDIO_S_TO_NS = 1000000000;
65 const uint64_t HDI_OFFLOAD_SAMPLE_RATE = 48000;
66 const int64_t SECOND_TO_MICROSECOND = 1000000;
67 const uint64_t AUDIO_FIRST_FRAME_LATENCY = 230; //ms
68 
69 const std::string FORCED_DUMP_PULSEAUDIO_STACKTRACE = "dump_pulseaudio_stacktrace";
70 const std::string RECOVERY_AUDIO_SERVER = "recovery_audio_server";
71 
72 static const std::unordered_map<AudioStreamType, std::string> STREAM_TYPE_ENUM_STRING_MAP = {
73     {STREAM_VOICE_CALL, "voice_call"},
74     {STREAM_MUSIC, "music"},
75     {STREAM_RING, "ring"},
76     {STREAM_MEDIA, "media"},
77     {STREAM_VOICE_ASSISTANT, "voice_assistant"},
78     {STREAM_SYSTEM, "system"},
79     {STREAM_ALARM, "alarm"},
80     {STREAM_NOTIFICATION, "notification"},
81     {STREAM_BLUETOOTH_SCO, "bluetooth_sco"},
82     {STREAM_ENFORCED_AUDIBLE, "enforced_audible"},
83     {STREAM_DTMF, "dtmf"},
84     {STREAM_TTS, "tts"},
85     {STREAM_ACCESSIBILITY, "accessibility"},
86     {STREAM_RECORDING, "recording"},
87     {STREAM_MOVIE, "movie"},
88     {STREAM_GAME, "game"},
89     {STREAM_SPEECH, "speech"},
90     {STREAM_SYSTEM_ENFORCED, "system_enforced"},
91     {STREAM_ULTRASONIC, "ultrasonic"},
92     {STREAM_WAKEUP, "wakeup"},
93     {STREAM_VOICE_MESSAGE, "voice_message"},
94     {STREAM_NAVIGATION, "navigation"},
95     {STREAM_SOURCE_VOICE_CALL, "source_voice_call"}
96 };
97 
CheckReturnIfinvalid(bool expr,const int32_t retVal)98 static int32_t CheckReturnIfinvalid(bool expr, const int32_t retVal)
99 {
100     do {
101         if (!(expr)) {
102             return retVal;
103         }
104     } while (false);
105     return CHECK_UTIL_SUCCESS;
106 }
107 
CheckPaStatusIfinvalid(pa_threaded_mainloop * mainLoop,pa_context * context,pa_stream * paStream,const int32_t retVal)108 static int32_t CheckPaStatusIfinvalid(pa_threaded_mainloop *mainLoop, pa_context *context,
109     pa_stream *paStream, const int32_t retVal)
110 {
111     return CheckReturnIfinvalid(mainLoop && context &&
112         paStream && PA_CONTEXT_IS_GOOD(pa_context_get_state(context)) &&
113         PA_STREAM_IS_GOOD(pa_stream_get_state(paStream)), retVal);
114 }
115 
CheckPaStatusIfinvalid(pa_threaded_mainloop * mainLoop,pa_context * context,pa_stream * paStream,const int32_t retVal,int32_t & pError)116 static int32_t CheckPaStatusIfinvalid(pa_threaded_mainloop *mainLoop, pa_context *context,
117     pa_stream *paStream, const int32_t retVal, int32_t &pError)
118 {
119     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, -1) < 0) {
120         pError = pa_context_errno(context);
121         return -1;
122     }
123     return retVal;
124 }
125 
ConvertFromPAAudioParams(pa_sample_spec paSampleSpec)126 AudioStreamParams AudioServiceClient::ConvertFromPAAudioParams(pa_sample_spec paSampleSpec)
127 {
128     AudioStreamParams audioParams;
129 
130     audioParams.channels = paSampleSpec.channels;
131     audioParams.samplingRate = paSampleSpec.rate;
132     audioParams.encoding = ENCODING_PCM;
133 
134     switch (paSampleSpec.format) {
135         case PA_SAMPLE_U8:
136             audioParams.format = SAMPLE_U8;
137             break;
138         case PA_SAMPLE_S16LE:
139             audioParams.format = SAMPLE_S16LE;
140             break;
141         case PA_SAMPLE_S24LE:
142             audioParams.format = SAMPLE_S24LE;
143             break;
144         case PA_SAMPLE_S32LE:
145             audioParams.format = SAMPLE_S32LE;
146             break;
147         default:
148             audioParams.format = INVALID_WIDTH;
149             break;
150     }
151 
152     return audioParams;
153 }
154 
ConvertToPAAudioParams(AudioStreamParams audioParams)155 pa_sample_spec AudioServiceClient::ConvertToPAAudioParams(AudioStreamParams audioParams)
156 {
157     pa_sample_spec paSampleSpec;
158 
159     paSampleSpec.channels = audioParams.channels;
160     paSampleSpec.rate     = audioParams.samplingRate;
161 
162     switch ((AudioSampleFormat)audioParams.format) {
163         case SAMPLE_U8:
164             paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_U8;
165             break;
166         case SAMPLE_S16LE:
167             paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S16LE;
168             break;
169         case SAMPLE_S24LE:
170             paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S24LE;
171             break;
172         case SAMPLE_S32LE:
173             paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_S32LE;
174             break;
175         default:
176             paSampleSpec.format = (pa_sample_format_t)PA_SAMPLE_INVALID;
177             break;
178     }
179 
180     return paSampleSpec;
181 }
182 
AlignToAudioFrameSize(size_t l,const pa_sample_spec & ss)183 static size_t AlignToAudioFrameSize(size_t l, const pa_sample_spec &ss)
184 {
185     size_t fs = pa_frame_size(&ss);
186     CHECK_AND_RETURN_RET_LOG(fs != 0, 0, "Error: pa_frame_size returned 0");
187 
188     return (l / fs) * fs;
189 }
190 
PAStreamStartSuccessCb(pa_stream * stream,int32_t success,void * userdata)191 void AudioServiceClient::PAStreamStartSuccessCb(pa_stream *stream, int32_t success, void *userdata)
192 {
193     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
194     AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
195     pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
196 
197     asClient->state_ = RUNNING;
198     asClient->breakingWritePa_ = false;
199     asClient->offloadTsLast_ = 0;
200     std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
201     if (streamCb != nullptr) {
202         streamCb->OnStateChange(RUNNING, asClient->stateChangeCmdType_);
203     }
204     asClient->stateChangeCmdType_ = CMD_FROM_CLIENT;
205     asClient->streamCmdStatus_ = success;
206     pa_threaded_mainloop_signal(mainLoop, 0);
207 }
208 
PAStreamStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)209 void AudioServiceClient::PAStreamStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
210 {
211     AUDIO_DEBUG_LOG("PAStreamStopSuccessCb in");
212     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
213 
214     AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
215     pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
216 
217     asClient->state_ = STOPPED;
218     asClient->breakingWritePa_ = false;
219     asClient->offloadTsLast_ = 0;
220     std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
221     if (streamCb != nullptr) {
222         streamCb->OnStateChange(STOPPED);
223     }
224     asClient->streamCmdStatus_ = success;
225     AUDIO_DEBUG_LOG("PAStreamStopSuccessCb: start signal");
226     pa_threaded_mainloop_signal(mainLoop, 0);
227     AUDIO_DEBUG_LOG("PAStreamStopSuccessCb out");
228 }
229 
PAStreamAsyncStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)230 void AudioServiceClient::PAStreamAsyncStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
231 {
232     AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb in");
233     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
234 
235     AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
236     pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
237     unique_lock<mutex> lockstopping(asClient->stoppingMutex_);
238 
239     if (asClient->offloadEnable_) {
240         asClient->audioSystemManager_->OffloadDrain();
241     }
242     asClient->state_ = STOPPED;
243     std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
244     if (streamCb != nullptr) {
245         streamCb->OnStateChange(STOPPED);
246     }
247     asClient->streamCmdStatus_ = success;
248     AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb: start signal");
249     lockstopping.unlock();
250     pa_threaded_mainloop_signal(mainLoop, 0);
251     asClient->dataCv_.notify_one();
252     AUDIO_DEBUG_LOG("PAStreamAsyncStopSuccessCb out");
253 }
254 
PAStreamPauseSuccessCb(pa_stream * stream,int32_t success,void * userdata)255 void AudioServiceClient::PAStreamPauseSuccessCb(pa_stream *stream, int32_t success, void *userdata)
256 {
257     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
258 
259     AudioServiceClient *asClient = static_cast<AudioServiceClient *>(userdata);
260     pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
261 
262     asClient->state_ = PAUSED;
263     asClient->breakingWritePa_ = false;
264     asClient->offloadTsLast_ = 0;
265     std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
266     if (streamCb != nullptr) {
267         streamCb->OnStateChange(PAUSED, asClient->stateChangeCmdType_);
268     }
269     asClient->stateChangeCmdType_ = CMD_FROM_CLIENT;
270     asClient->streamCmdStatus_ = success;
271     pa_threaded_mainloop_signal(mainLoop, 0);
272 }
273 
PAStreamDrainSuccessCb(pa_stream * stream,int32_t success,void * userdata)274 void AudioServiceClient::PAStreamDrainSuccessCb(pa_stream *stream, int32_t success, void *userdata)
275 {
276     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
277 
278     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
279     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
280 
281     asClient->streamDrainStatus_ = success;
282     pa_threaded_mainloop_signal(mainLoop, 0);
283 }
284 
PAStreamDrainInStopCb(pa_stream * stream,int32_t success,void * userdata)285 void AudioServiceClient::PAStreamDrainInStopCb(pa_stream *stream, int32_t success, void *userdata)
286 {
287     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
288     pa_operation *operation = pa_stream_cork(asClient->paStream, 1,
289         AudioServiceClient::PAStreamAsyncStopSuccessCb, userdata);
290     pa_operation_unref(operation);
291 
292     asClient->streamDrainStatus_ = success;
293 }
294 
PAStreamFlushSuccessCb(pa_stream * stream,int32_t success,void * userdata)295 void AudioServiceClient::PAStreamFlushSuccessCb(pa_stream *stream, int32_t success, void *userdata)
296 {
297     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
298 
299     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
300     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
301 
302     asClient->streamFlushStatus_ = success;
303     pa_threaded_mainloop_signal(mainLoop, 0);
304 }
305 
MsToAlignedSize(size_t ms,const pa_sample_spec & ss)306 static size_t MsToAlignedSize(size_t ms, const pa_sample_spec &ss)
307 {
308     return AlignToAudioFrameSize(pa_usec_to_bytes(ms * PA_USEC_PER_MSEC, &ss), ss);
309 }
310 
PAStreamSetBufAttrSuccessCb(pa_stream * stream,int32_t success,void * userdata)311 void AudioServiceClient::PAStreamSetBufAttrSuccessCb(pa_stream *stream, int32_t success, void *userdata)
312 {
313     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
314 
315     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
316     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
317 
318     AUDIO_DEBUG_LOG("SetBufAttr %{public}s", success ? "success" : "faild");
319 
320     const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(stream);
321     if (asClient->offloadEnable_ &&
322         MsToAlignedSize(OFFLOAD_BUFFER, asClient->sampleSpec) >= bufferAttr->tlength / 2) { // 2 tlength need bigger
323         asClient->acache_.totalCacheSizeTgt = MsToAlignedSize(OFFLOAD_BUFFER, asClient->sampleSpec);
324     } else {
325         asClient->acache_.totalCacheSizeTgt = bufferAttr->minreq;
326     }
327     pa_threaded_mainloop_signal(mainLoop, 0);
328 }
329 
PAStreamUpdateTimingInfoSuccessCb(pa_stream * stream,int32_t success,void * userdata)330 void AudioServiceClient::PAStreamUpdateTimingInfoSuccessCb(pa_stream *stream, int32_t success, void *userdata)
331 {
332     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
333 
334     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
335     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
336     int negative = 0;
337     asClient->paLatency_ = 0;
338     asClient->isGetLatencySuccess_ = true;
339     if (pa_stream_get_latency(stream, &asClient->paLatency_, &negative) >= 0 && negative) {
340         asClient->isGetLatencySuccess_ = false;
341     }
342     const pa_timing_info *info = pa_stream_get_timing_info(stream);
343     asClient->offloadWriteIndex_ = pa_bytes_to_usec(info->write_index, &asClient->sampleSpec);
344     asClient->offloadReadIndex_ = pa_bytes_to_usec(info->read_index, &asClient->sampleSpec);
345     asClient->offloadTimeStamp_ = info->timestamp.tv_sec * AUDIO_US_PER_SECOND + info->timestamp.tv_usec;
346 
347     pa_threaded_mainloop_signal(mainLoop, 0);
348 }
349 
SetAudioRenderMode(AudioRenderMode renderMode)350 int32_t AudioServiceClient::SetAudioRenderMode(AudioRenderMode renderMode)
351 {
352     AUDIO_DEBUG_LOG("SetAudioRenderMode begin");
353     renderMode_ = renderMode;
354 
355     CHECK_AND_RETURN_RET(renderMode_ == RENDER_MODE_CALLBACK, AUDIO_CLIENT_SUCCESS);
356 
357     int32_t ret = CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_ERR);
358     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_ERR);
359 
360     pa_threaded_mainloop_lock(mainLoop);
361     pa_buffer_attr bufferAttr;
362     bufferAttr.fragsize = static_cast<uint32_t>(-1);
363     bufferAttr.prebuf = AlignToAudioFrameSize(pa_usec_to_bytes(MIN_BUF_DURATION_IN_USEC, &sampleSpec), sampleSpec);
364     bufferAttr.maxlength = bufferAttr.prebuf * MAX_LENGTH_FACTOR;
365     bufferAttr.tlength = bufferAttr.prebuf * T_LENGTH_FACTOR;
366     bufferAttr.minreq = bufferAttr.prebuf;
367     pa_operation *operation = pa_stream_set_buffer_attr(paStream, &bufferAttr,
368         PAStreamSetBufAttrSuccessCb, (void *)this);
369         while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
370         pa_threaded_mainloop_wait(mainLoop);
371     }
372     pa_operation_unref(operation);
373     pa_threaded_mainloop_unlock(mainLoop);
374 
375     AUDIO_DEBUG_LOG("SetAudioRenderMode end");
376 
377     return AUDIO_CLIENT_SUCCESS;
378 }
379 
GetAudioRenderMode()380 AudioRenderMode AudioServiceClient::GetAudioRenderMode()
381 {
382     return renderMode_;
383 }
384 
SetAudioCaptureMode(AudioCaptureMode captureMode)385 int32_t AudioServiceClient::SetAudioCaptureMode(AudioCaptureMode captureMode)
386 {
387     AUDIO_DEBUG_LOG("SetAudioCaptureMode.");
388     captureMode_ = captureMode;
389 
390     return AUDIO_CLIENT_SUCCESS;
391 }
392 
GetAudioCaptureMode()393 AudioCaptureMode AudioServiceClient::GetAudioCaptureMode()
394 {
395     return captureMode_;
396 }
397 
PAStreamWriteCb(pa_stream * stream,size_t length,void * userdata)398 void AudioServiceClient::PAStreamWriteCb(pa_stream *stream, size_t length, void *userdata)
399 {
400     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
401 
402     auto asClient = static_cast<AudioServiceClient *>(userdata);
403     Trace trace("AudioServiceClient::PAStreamWriteCb sink-input:" + std::to_string(asClient->streamId_) + " length:" +
404         std::to_string(length));
405     int64_t now = ClockTime::GetCurNano() / AUDIO_US_PER_SECOND;
406     int64_t duration = now - asClient->writeCbStamp_;
407     if (duration > 40) { // 40 ms
408         AUDIO_INFO_LOG("Inside PA write callback cost[%{public}" PRId64 "]ms, sessionID %u", duration,
409             asClient->sessionID_);
410     }
411     asClient->writeCbStamp_ = now;
412     auto mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
413     pa_threaded_mainloop_signal(mainLoop, 0);
414 }
415 
PAStreamReadCb(pa_stream * stream,size_t length,void * userdata)416 void AudioServiceClient::PAStreamReadCb(pa_stream *stream, size_t length, void *userdata)
417 {
418     int32_t logMode = system::GetIntParameter("persist.multimedia.audiolog.switch", 0);
419     if (logMode) {
420         AUDIO_DEBUG_LOG("PAStreamReadCb Inside PA read callback");
421     }
422     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
423     auto asClient = static_cast<AudioServiceClient *>(userdata);
424     auto mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
425     pa_threaded_mainloop_signal(mainLoop, 0);
426 }
427 
PAStreamUnderFlowCb(pa_stream * stream,void * userdata)428 void AudioServiceClient::PAStreamUnderFlowCb(pa_stream *stream, void *userdata)
429 {
430     Trace trace("PAStreamUnderFlow");
431     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
432 
433     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
434     asClient->underFlowCount++;
435     AUDIO_WARNING_LOG("AudioServiceClient underrun: %{public}d!", asClient->underFlowCount);
436 }
437 
PAStreamEventCb(pa_stream * stream,const char * event,pa_proplist * pl,void * userdata)438 void AudioServiceClient::PAStreamEventCb(pa_stream *stream, const char *event, pa_proplist *pl, void *userdata)
439 {
440     Trace trace("PAStreamEvent");
441     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
442 
443     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
444     if (!strcmp(event, "signal_mainloop")) {
445         pa_threaded_mainloop_signal(asClient->mainLoop, 0);
446         AUDIO_DEBUG_LOG("receive event signal_mainloop");
447     }
448 
449     if (!strcmp(event, "state_changed")) {
450         const char *old_state = pa_proplist_gets(pl, "old_state");
451         const char *new_state = pa_proplist_gets(pl, "new_state");
452         AUDIO_INFO_LOG("old state : %{public}s, new state : %{public}s",
453             old_state, new_state);
454         if (asClient != nullptr) {
455             if (!strcmp(old_state, "RUNNING") && !strcmp(new_state, "CORKED")) {
456                 asClient->UpdateStreamPosition(UpdatePositionTimeNode::CORKED_NODE);
457             }
458             if (!strcmp(old_state, "CORKED") && !strcmp(new_state, "RUNNING")) {
459                 asClient->UpdateStreamPosition(UpdatePositionTimeNode::RUNNING_NODE);
460             }
461         }
462     }
463 }
464 
PAStreamLatencyUpdateCb(pa_stream * stream,void * userdata)465 void AudioServiceClient::PAStreamLatencyUpdateCb(pa_stream *stream, void *userdata)
466 {
467     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)userdata;
468     pa_threaded_mainloop_signal(mainLoop, 0);
469 }
470 
PAStreamMovedCb(pa_stream * stream,void * userdata)471 void AudioServiceClient::PAStreamMovedCb(pa_stream *stream, void *userdata)
472 {
473     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
474 
475     // get stream informations.
476     uint32_t deviceIndex = pa_stream_get_device_index(stream); // pa_context_get_sink_info_by_index
477 
478     // Return 1 if the sink or source this stream is connected to has been suspended.
479     // This will return 0 if not, and a negative value on error.
480     int res = pa_stream_is_suspended(stream);
481     AUDIO_DEBUG_LOG("PAstream moved to index:[%{public}d] suspended:[%{public}d]",
482         deviceIndex, res);
483 }
484 
PAStreamStateCb(pa_stream * stream,void * userdata)485 void AudioServiceClient::PAStreamStateCb(pa_stream *stream, void *userdata)
486 {
487     CHECK_AND_RETURN_LOG(userdata, "userdata is null");
488 
489     AudioServiceClient *asClient = (AudioServiceClient *)userdata;
490     bool isClientExist;
491     if (serviceClientInstanceMap_.Find(asClient, isClientExist) == false) {
492         AUDIO_ERR_LOG("asClient is null");
493         return;
494     }
495     std::lock_guard<std::mutex> lock(asClient->serviceClientLock_);
496     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)asClient->mainLoop;
497 
498     if (asClient->mAudioRendererCallbacks)
499         asClient->mAudioRendererCallbacks->OnStreamStateChangeCb();
500 
501     AUDIO_INFO_LOG("Current Stream State: %{public}d", pa_stream_get_state(stream));
502 
503     switch (pa_stream_get_state(stream)) {
504         case PA_STREAM_READY:
505         case PA_STREAM_FAILED:
506         case PA_STREAM_TERMINATED:
507             pa_threaded_mainloop_signal(mainLoop, 0);
508             break;
509 
510         case PA_STREAM_UNCONNECTED:
511         case PA_STREAM_CREATING:
512         default:
513             break;
514     }
515 }
516 
PAContextStateCb(pa_context * context,void * userdata)517 void AudioServiceClient::PAContextStateCb(pa_context *context, void *userdata)
518 {
519     pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)userdata;
520     AUDIO_INFO_LOG("Current Context State: %{public}d", pa_context_get_state(context));
521 
522     switch (pa_context_get_state(context)) {
523         case PA_CONTEXT_READY:
524             AudioSystemManager::GetInstance()->RequestThreadPriority(gettid());
525             pa_threaded_mainloop_signal(mainLoop, 0);
526             break;
527         case PA_CONTEXT_TERMINATED:
528         case PA_CONTEXT_FAILED:
529             pa_threaded_mainloop_signal(mainLoop, 0);
530             break;
531 
532         case PA_CONTEXT_UNCONNECTED:
533         case PA_CONTEXT_CONNECTING:
534         case PA_CONTEXT_AUTHORIZING:
535         case PA_CONTEXT_SETTING_NAME:
536         default:
537             break;
538     }
539 }
540 
AudioServiceClient()541 AudioServiceClient::AudioServiceClient()
542     : AppExecFwk::EventHandler(AppExecFwk::EventRunner::Create("OS_ACRunner"))
543 {
544     sinkDevices.clear();
545     sourceDevices.clear();
546     sinkInputs.clear();
547     sourceOutputs.clear();
548     clientInfo.clear();
549 
550     renderRate = RENDER_RATE_NORMAL;
551     renderMode_ = RENDER_MODE_NORMAL;
552 
553     captureMode_ = CAPTURE_MODE_NORMAL;
554 
555     eAudioClientType = AUDIO_SERVICE_CLIENT_PLAYBACK;
556     effectSceneName = "SCENE_MUSIC";
557     effectMode = EFFECT_DEFAULT;
558 
559     mFrameSize = 0;
560     mFrameMarkPosition = 0;
561     mMarkReached = false;
562     mFramePeriodNumber = 0;
563 
564     mTotalBytesWritten = 0;
565     mFramePeriodWritten = 0;
566     mTotalBytesRead = 0;
567     mFramePeriodRead = 0;
568     mRenderPositionCb = nullptr;
569     mRenderPeriodPositionCb = nullptr;
570 
571     mAudioRendererCallbacks = nullptr;
572     mAudioCapturerCallbacks = nullptr;
573     internalReadBuffer_ = nullptr;
574     mainLoop = nullptr;
575     paStream = nullptr;
576     context  = nullptr;
577     api = nullptr;
578 
579     internalRdBufIndex_ = 0;
580     internalRdBufLen_ = 0;
581     streamCmdStatus_ = 0;
582     streamDrainStatus_ = 0;
583     streamFlushStatus_ = 0;
584     underFlowCount = 0;
585 
586     acache_.readIndex = 0;
587     acache_.writeIndex = 0;
588     acache_.isFull = false;
589     acache_.totalCacheSize = 0;
590     acache_.totalCacheSizeTgt = 0;
591     acache_.buffer = nullptr;
592 
593     setBufferSize_ = 0;
594     PAStreamCorkSuccessCb = PAStreamStopSuccessCb;
595     rendererSampleRate = 0;
596 
597     mPrivacyType = PRIVACY_TYPE_PUBLIC;
598     mStreamUsage = STREAM_USAGE_UNKNOWN;
599     streamClass_ = IAudioStream::StreamClass::PA_STREAM;
600     serviceClientInstanceMap_.Insert(this, true);
601 }
602 
ResetPAAudioClient()603 void AudioServiceClient::ResetPAAudioClient()
604 {
605     AUDIO_INFO_LOG("In");
606     lock_guard<mutex> lock(ctrlMutex_);
607     if (mainLoop && (isMainLoopStarted_ == true))
608         pa_threaded_mainloop_stop(mainLoop);
609 
610     if (paStream) {
611         pa_stream_set_state_callback(paStream, nullptr, nullptr);
612         pa_stream_set_write_callback(paStream, nullptr, nullptr);
613         pa_stream_set_read_callback(paStream, nullptr, nullptr);
614         pa_stream_set_latency_update_callback(paStream, nullptr, nullptr);
615         pa_stream_set_underflow_callback(paStream, nullptr, nullptr);
616 
617         if (isStreamConnected_ == true) {
618             pa_stream_disconnect(paStream);
619             pa_stream_unref(paStream);
620             isStreamConnected_  = false;
621             paStream = nullptr;
622         }
623     }
624 
625     if (context) {
626         pa_context_set_state_callback(context, nullptr, nullptr);
627         if (isContextConnected_ == true) {
628             pa_threaded_mainloop_lock(mainLoop);
629             pa_context_disconnect(context);
630             pa_context_unref(context);
631             pa_threaded_mainloop_unlock(mainLoop);
632             isContextConnected_ = false;
633             context = nullptr;
634         }
635     }
636 
637     if (mainLoop) {
638         pa_threaded_mainloop_free(mainLoop);
639         isMainLoopStarted_  = false;
640         mainLoop = nullptr;
641     }
642 
643     for (auto &thread : mPositionCBThreads) {
644         if (thread && thread->joinable()) {
645             thread->join();
646         }
647     }
648 
649     for (auto &thread : mPeriodPositionCBThreads) {
650         if (thread && thread->joinable()) {
651             thread->join();
652         }
653     }
654 
655     if (appCookiePath.compare("")) {
656         remove(appCookiePath.c_str());
657         appCookiePath = "";
658     }
659 
660     sinkDevices.clear();
661     sourceDevices.clear();
662     sinkInputs.clear();
663     sourceOutputs.clear();
664     clientInfo.clear();
665 
666     mAudioRendererCallbacks = nullptr;
667     mAudioCapturerCallbacks = nullptr;
668     internalReadBuffer_      = nullptr;
669 
670     api      = nullptr;
671 
672     internalRdBufIndex_ = 0;
673     internalRdBufLen_   = 0;
674     underFlowCount     = 0;
675 
676     acache_.buffer = nullptr;
677     acache_.readIndex = 0;
678     acache_.writeIndex = 0;
679     acache_.isFull = false;
680     acache_.totalCacheSize = 0;
681     acache_.totalCacheSizeTgt = 0;
682 
683     setBufferSize_ = 0;
684     PAStreamCorkSuccessCb = nullptr;
685 }
686 
~AudioServiceClient()687 AudioServiceClient::~AudioServiceClient()
688 {
689     lock_guard<mutex> lockdata(dataMutex_);
690     AUDIO_INFO_LOG("start ~AudioServiceClient");
691     UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
692     ResetPAAudioClient();
693     StopTimer();
694     std::lock_guard<std::mutex> lock(serviceClientLock_);
695     serviceClientInstanceMap_.Erase(this);
696 }
697 
SetEnv()698 void AudioServiceClient::SetEnv()
699 {
700     AUDIO_DEBUG_LOG("SetEnv called");
701 
702     int ret = setenv("HOME", PA_HOME_DIR, 1);
703     AUDIO_DEBUG_LOG("set env HOME: %{public}d", ret);
704 
705     ret = setenv("PULSE_RUNTIME_PATH", PA_RUNTIME_DIR, 1);
706     AUDIO_DEBUG_LOG("set env PULSE_RUNTIME_DIR: %{public}d", ret);
707 
708     ret = setenv("PULSE_STATE_PATH", PA_STATE_DIR, 1);
709     AUDIO_DEBUG_LOG("set env PULSE_STATE_PATH: %{public}d", ret);
710 }
711 
SetApplicationCachePath(const std::string cachePath)712 void AudioServiceClient::SetApplicationCachePath(const std::string cachePath)
713 {
714     AUDIO_DEBUG_LOG("SetApplicationCachePath in");
715 
716     char realPath[PATH_MAX] = {0x00};
717 
718     CHECK_AND_RETURN_LOG((strlen(cachePath.c_str()) < PATH_MAX) && (realpath(cachePath.c_str(), realPath) != nullptr),
719         "Invalid cache path. err = %{public}d", errno);
720 
721     cachePath_ = realPath;
722 }
723 
CheckRecordingCreate(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,SourceType sourceType)724 bool AudioServiceClient::CheckRecordingCreate(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
725     SourceType sourceType)
726 {
727     return AudioPolicyManager::GetInstance().CheckRecordingCreate(appTokenId, appFullTokenId, appUid, sourceType);
728 }
729 
CheckRecordingStateChange(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,AudioPermissionState state)730 bool AudioServiceClient::CheckRecordingStateChange(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
731     AudioPermissionState state)
732 {
733     return AudioPolicyManager::GetInstance().CheckRecordingStateChange(appTokenId, appFullTokenId, appUid, state);
734 }
735 
Initialize(ASClientType eClientType)736 int32_t AudioServiceClient::Initialize(ASClientType eClientType)
737 {
738     int error = PA_ERR_INTERNAL;
739     eAudioClientType = eClientType;
740 
741     mMarkReached = false;
742     mTotalBytesWritten = 0;
743     mFramePeriodWritten = 0;
744     mTotalBytesRead = 0;
745     mFramePeriodRead = 0;
746 
747     SetEnv();
748 
749     audioSystemManager_ = AudioSystemManager::GetInstance();
750     lock_guard<mutex> lockdata(dataMutex_);
751     mainLoop = pa_threaded_mainloop_new();
752     if (mainLoop == nullptr)
753         return AUDIO_CLIENT_INIT_ERR;
754     api = pa_threaded_mainloop_get_api(mainLoop);
755     pa_threaded_mainloop_set_name(mainLoop, "OS_AudioML");
756     if (api == nullptr) {
757         ResetPAAudioClient();
758         return AUDIO_CLIENT_INIT_ERR;
759     }
760     stringstream ss;
761     string packageName = "";
762     ss << "app-pid<" << getpid() << ">-uid<" << getuid() << ">";
763     ss >> packageName;
764     AUDIO_DEBUG_LOG("AudioServiceClient:Initialize [%{public}s]", packageName.c_str());
765     context = pa_context_new(api, packageName.c_str());
766     if (context == nullptr) {
767         ResetPAAudioClient();
768         return AUDIO_CLIENT_INIT_ERR;
769     }
770 
771     pa_context_set_state_callback(context, PAContextStateCb, mainLoop);
772 
773     if (pa_context_connect(context, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
774         error = pa_context_errno(context);
775         AUDIO_ERR_LOG("context connect error: %{public}s", pa_strerror(error));
776         ResetPAAudioClient();
777         return AUDIO_CLIENT_INIT_ERR;
778     }
779     isContextConnected_ = true;
780     CHECK_AND_RETURN_RET_LOG(HandleMainLoopStart() == AUDIO_CLIENT_SUCCESS, AUDIO_CLIENT_INIT_ERR,
781         "Start main loop failed");
782 
783     if (appCookiePath.compare("")) {
784         remove(appCookiePath.c_str());
785         appCookiePath = "";
786     }
787 
788     pa_threaded_mainloop_unlock(mainLoop);
789     return AUDIO_CLIENT_SUCCESS;
790 }
791 
HandleMainLoopStart()792 int32_t AudioServiceClient::HandleMainLoopStart()
793 {
794     int error = PA_ERR_INTERNAL;
795     pa_threaded_mainloop_lock(mainLoop);
796 
797     if (pa_threaded_mainloop_start(mainLoop) < 0) {
798         pa_threaded_mainloop_unlock(mainLoop);
799         ResetPAAudioClient();
800         return AUDIO_CLIENT_INIT_ERR;
801     }
802 
803     isMainLoopStarted_ = true;
804     while (true) {
805         pa_context_state_t state = pa_context_get_state(context);
806         if (state == PA_CONTEXT_READY)
807             break;
808 
809         if (!PA_CONTEXT_IS_GOOD(state)) {
810             error = pa_context_errno(context);
811             AUDIO_ERR_LOG("context bad state error: %{public}s", pa_strerror(error));
812             pa_threaded_mainloop_unlock(mainLoop);
813             ResetPAAudioClient();
814             return AUDIO_CLIENT_INIT_ERR;
815         }
816 
817         static bool triggerDumpStacktraceAndKill = true;
818         if (triggerDumpStacktraceAndKill == true) {
819             AudioXCollie audioXCollie("AudioServiceClient::InitDumpTrace", INIT_TIMEOUT_IN_SEC, [this](void *) {
820                 audioSystemManager_->GetAudioParameter(RECOVERY_AUDIO_SERVER);
821                 triggerDumpStacktraceAndKill = false;
822                 pa_threaded_mainloop_signal(this->mainLoop, 0);
823             }, nullptr, 0);
824             pa_threaded_mainloop_wait(mainLoop);
825         } else {
826             StartTimer(INIT_TIMEOUT_IN_SEC);
827             pa_threaded_mainloop_wait(mainLoop);
828             StopTimer();
829             if (IsTimeOut()) {
830                 AUDIO_ERR_LOG("Initialize timeout");
831                 pa_threaded_mainloop_unlock(mainLoop);
832                 return AUDIO_CLIENT_INIT_ERR;
833             }
834         }
835     }
836     return AUDIO_CLIENT_SUCCESS;
837 }
838 
GetStreamName(AudioStreamType audioType)839 const std::string AudioServiceClient::GetStreamName(AudioStreamType audioType)
840 {
841     std::string name = "unknown";
842     if (STREAM_TYPE_ENUM_STRING_MAP.find(audioType) != STREAM_TYPE_ENUM_STRING_MAP.end()) {
843         name = STREAM_TYPE_ENUM_STRING_MAP.at(audioType);
844     } else {
845         AUDIO_WARNING_LOG("GetStreamName: Invalid stream type [%{public}d], return unknown", audioType);
846     }
847     const std::string streamName = name;
848     return streamName;
849 }
850 
GetDeviceNameForConnect()851 std::pair<const int32_t, const std::string> AudioServiceClient::GetDeviceNameForConnect()
852 {
853     string deviceName;
854     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
855         const std::string selectDevice =  AudioSystemManager::GetInstance()->GetSelectedDeviceInfo(clientUid_,
856             clientPid_, streamType_);
857         deviceName = (selectDevice.empty() ? "" : selectDevice);
858         return {AUDIO_CLIENT_SUCCESS, deviceName};
859     }
860 
861     if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
862         if (isInnerCapturerStream_) {
863             return {AUDIO_CLIENT_SUCCESS, INNER_CAPTURER_SOURCE};
864         }
865 
866         if (isWakeupCapturerStream_) {
867             AUDIO_ERR_LOG("non-IPC channels will no longer support voice wakeup");
868             return {AUDIO_CLIENT_ERR, deviceName};
869         }
870         NotifyCapturerAdded(sessionID_);
871     }
872     return {AUDIO_CLIENT_SUCCESS, deviceName};
873 }
874 
ConnectStreamToPA()875 int32_t AudioServiceClient::ConnectStreamToPA()
876 {
877     AUDIO_DEBUG_LOG("AudioServiceClient::ConnectStreamToPA");
878 
879     int32_t ret = CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_ERR);
880     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_ERR);
881     int32_t latency_in_msec = AudioSystemManager::GetInstance()->GetAudioLatencyFromXml();
882     CHECK_AND_RETURN_RET_LOG(latency_in_msec >= 0, AUDIO_CLIENT_CREATE_STREAM_ERR,
883         "Get audio latency failed.");
884     sinkLatencyInMsec_ = AudioSystemManager::GetInstance()->GetSinkLatencyFromXml();
885 
886     auto [errorCode, deviceNameS] = GetDeviceNameForConnect();
887     CHECK_AND_RETURN_RET(errorCode == AUDIO_CLIENT_SUCCESS, errorCode);
888 
889     pa_threaded_mainloop_lock(mainLoop);
890 
891     if (HandlePAStreamConnect(deviceNameS, latency_in_msec) != SUCCESS || WaitStreamReady() != SUCCESS) {
892         pa_threaded_mainloop_unlock(mainLoop);
893         return AUDIO_CLIENT_CREATE_STREAM_ERR;
894     }
895 
896     isStreamConnected_ = true;
897     streamId_ = pa_stream_get_index(paStream);
898     pa_threaded_mainloop_unlock(mainLoop);
899     return AUDIO_CLIENT_SUCCESS;
900 }
901 
HandlePAStreamConnect(const std::string & deviceNameS,int32_t latencyInMSec)902 int32_t AudioServiceClient::HandlePAStreamConnect(const std::string &deviceNameS, int32_t latencyInMSec)
903 {
904     const char *deviceName = deviceNameS.empty() ? nullptr : deviceNameS.c_str();
905     pa_buffer_attr bufferAttr;
906     bufferAttr.fragsize = static_cast<uint32_t>(-1);
907     if (latencyInMSec <= LATENCY_THRESHOLD) {
908         bufferAttr.prebuf = AlignToAudioFrameSize(pa_usec_to_bytes(latencyInMSec * PA_USEC_PER_MSEC, &sampleSpec),
909             sampleSpec);
910         bufferAttr.maxlength =  NO_OF_PREBUF_TIMES * bufferAttr.prebuf;
911         bufferAttr.tlength = static_cast<uint32_t>(-1);
912     } else {
913         bufferAttr.prebuf = pa_usec_to_bytes(latencyInMSec * PA_USEC_PER_MSEC, &sampleSpec);
914         bufferAttr.maxlength = pa_usec_to_bytes(latencyInMSec * PA_USEC_PER_MSEC * MAX_LENGTH_FACTOR, &sampleSpec);
915         bufferAttr.tlength = pa_usec_to_bytes(latencyInMSec * PA_USEC_PER_MSEC * T_LENGTH_FACTOR, &sampleSpec);
916     }
917     bufferAttr.minreq = bufferAttr.prebuf;
918     int32_t result = 0;
919     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
920         result = pa_stream_connect_playback(paStream, deviceName, &bufferAttr,
921             (pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_START_CORKED |
922             PA_STREAM_VARIABLE_RATE), nullptr, nullptr);
923         preBuf_ = make_unique<uint8_t[]>(bufferAttr.maxlength);
924         if (preBuf_ == nullptr) {
925             AUDIO_ERR_LOG("Allocate memory for buffer failed.");
926             return AUDIO_CLIENT_INIT_ERR;
927         }
928         if (memset_s(preBuf_.get(), bufferAttr.maxlength, 0, bufferAttr.maxlength) != 0) {
929             AUDIO_ERR_LOG("memset_s for buffer failed.");
930             return AUDIO_CLIENT_INIT_ERR;
931         }
932     } else {
933         AUDIO_DEBUG_LOG("pa_stream_connect_record connect to:%{public}s", deviceName ? deviceName : "nullptr");
934         result = pa_stream_connect_record(paStream, deviceName, nullptr,
935             (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY
936             | PA_STREAM_START_CORKED | PA_STREAM_AUTO_TIMING_UPDATE));
937     }
938     if (result < 0) {
939         int error = pa_context_errno(context);
940         AUDIO_ERR_LOG("connection to stream error: %{public}d", error);
941         ResetPAAudioClient();
942         return AUDIO_CLIENT_CREATE_STREAM_ERR;
943     }
944     return SUCCESS;
945 }
946 
WaitStreamReady()947 int32_t AudioServiceClient::WaitStreamReady()
948 {
949     while (true) {
950         pa_stream_state_t state = pa_stream_get_state(paStream);
951         if (state == PA_STREAM_READY)
952             break;
953 
954         if (!PA_STREAM_IS_GOOD(state)) {
955             int error = pa_context_errno(context);
956             AUDIO_ERR_LOG("connection to stream error: %{public}d", error);
957             ResetPAAudioClient();
958             return AUDIO_CLIENT_CREATE_STREAM_ERR;
959         }
960 
961         static bool recoveryAudioServer = true;
962         if (recoveryAudioServer == true) {
963             AudioXCollie audioXCollie("AudioServiceClient::RecoveryConnect", CONNECT_TIMEOUT_IN_SEC, [this](void *) {
964                 audioSystemManager_->GetAudioParameter(RECOVERY_AUDIO_SERVER);
965                 recoveryAudioServer = false;
966                 pa_threaded_mainloop_signal(this->mainLoop, 0);
967             }, nullptr, 0);
968             pa_threaded_mainloop_wait(mainLoop);
969         } else {
970             StartTimer(CONNECT_TIMEOUT_IN_SEC);
971             pa_threaded_mainloop_wait(mainLoop);
972             StopTimer();
973             if (IsTimeOut()) {
974                 AUDIO_ERR_LOG("Initialize timeout");
975                 return AUDIO_CLIENT_CREATE_STREAM_ERR;
976             }
977         }
978     }
979     return SUCCESS;
980 }
981 
InitializeAudioCache()982 int32_t AudioServiceClient::InitializeAudioCache()
983 {
984     AUDIO_DEBUG_LOG("Initializing internal audio cache");
985 
986     int32_t ret = CheckReturnIfinvalid(mainLoop && context && paStream, AUDIO_CLIENT_PA_ERR);
987     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
988 
989     const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
990     CHECK_AND_RETURN_RET_LOG(bufferAttr != nullptr, AUDIO_CLIENT_INIT_ERR,
991         "pa stream get buffer attribute returned null");
992 
993     acache_.buffer = make_unique<uint8_t[]>(max((uint32_t)bufferAttr->minreq,
994         static_cast<uint32_t>(pa_usec_to_bytes(200 * PA_USEC_PER_MSEC, &sampleSpec)))); // 200 is init size
995 
996     CHECK_AND_RETURN_RET_LOG(acache_.buffer != nullptr, AUDIO_CLIENT_INIT_ERR,
997         "Allocate memory for buffer failed");
998 
999     acache_.readIndex = 0;
1000     acache_.writeIndex = 0;
1001     acache_.totalCacheSize = bufferAttr->minreq;
1002     acache_.totalCacheSizeTgt = bufferAttr->minreq;
1003     acache_.isFull = false;
1004     return AUDIO_CLIENT_SUCCESS;
1005 }
1006 
SetPaProplist(pa_proplist * propList,pa_channel_map & map,AudioStreamParams & audioParams,const std::string & streamName,const std::string & streamStartTime)1007 int32_t AudioServiceClient::SetPaProplist(pa_proplist *propList, pa_channel_map &map,
1008     AudioStreamParams &audioParams, const std::string &streamName, const std::string &streamStartTime)
1009 {
1010     if (propList == nullptr) {
1011         AUDIO_ERR_LOG("pa_proplist_new failed");
1012         pa_threaded_mainloop_unlock(mainLoop);
1013         ResetPAAudioClient();
1014         return AUDIO_CLIENT_CREATE_STREAM_ERR;
1015     }
1016 
1017     // for remote audio device router filter.
1018     pa_proplist_sets(propList, "stream.client.uid", std::to_string(clientUid_).c_str());
1019     pa_proplist_sets(propList, "stream.client.pid", std::to_string(clientPid_).c_str());
1020 
1021     pa_proplist_sets(propList, "stream.type", streamName.c_str());
1022     pa_proplist_sets(propList, "stream.volumeFactor", std::to_string(volumeFactor_).c_str());
1023     pa_proplist_sets(propList, "stream.powerVolumeFactor", std::to_string(powerVolumeFactor_).c_str());
1024     sessionID_ = pa_context_get_index(context);
1025     pa_proplist_sets(propList, "stream.sessionID", std::to_string(sessionID_).c_str());
1026     pa_proplist_sets(propList, "stream.startTime", streamStartTime.c_str());
1027 
1028     if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
1029         pa_proplist_sets(propList, "stream.isInnerCapturer", std::to_string(isInnerCapturerStream_).c_str());
1030         pa_proplist_sets(propList, "stream.isWakeupCapturer", std::to_string(isWakeupCapturerStream_).c_str());
1031         pa_proplist_sets(propList, "stream.isIpcCapturer", std::to_string(false).c_str());
1032         pa_proplist_sets(propList, "stream.capturerSource", std::to_string(capturerSource_).c_str());
1033     } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1034         pa_proplist_sets(propList, "stream.privacyType", std::to_string(mPrivacyType).c_str());
1035         pa_proplist_sets(propList, "stream.usage", std::to_string(mStreamUsage).c_str());
1036     }
1037 
1038     AUDIO_DEBUG_LOG("Creating stream of channels %{public}d", audioParams.channels);
1039     if (audioParams.channelLayout == 0) {
1040         audioParams.channelLayout = defaultChCountToLayoutMap[audioParams.channels];
1041     }
1042     pa_proplist_sets(propList, "stream.channelLayout", std::to_string(audioParams.channelLayout).c_str());
1043     pa_proplist_sets(propList, "spatialization.enabled", spatializationEnabled_.c_str());
1044     pa_proplist_sets(propList, "headtracking.enabled", headTrackingEnabled_.c_str());
1045     pa_channel_map_init(&map);
1046     map.channels = audioParams.channels;
1047     uint32_t channelsInLayout = ConvertChLayoutToPaChMap(audioParams.channelLayout, map);
1048     if (channelsInLayout != audioParams.channels || !channelsInLayout) {
1049         AUDIO_ERR_LOG("Invalid channel Layout");
1050         pa_proplist_free(propList);
1051         pa_threaded_mainloop_unlock(mainLoop);
1052         ResetPAAudioClient();
1053         return AUDIO_CLIENT_CREATE_STREAM_ERR;
1054     }
1055 
1056     ResetOffload();
1057     return AUDIO_CLIENT_SUCCESS;
1058 }
1059 
CreateStreamWithPa(AudioStreamParams audioParams,AudioStreamType audioType)1060 int32_t AudioServiceClient::CreateStreamWithPa(AudioStreamParams audioParams, AudioStreamType audioType)
1061 {
1062     int error;
1063     pa_threaded_mainloop_lock(mainLoop);
1064     streamType_ = audioType;
1065     const std::string streamName = GetStreamName(audioType);
1066 
1067     auto timenow = chrono::system_clock::to_time_t(chrono::system_clock::now());
1068     const std::string streamStartTime = ctime(&timenow);
1069 
1070     sampleSpec = ConvertToPAAudioParams(audioParams);
1071     mFrameSize = pa_frame_size(&sampleSpec);
1072     channelLayout_ = audioParams.channelLayout;
1073     AudioSpatializationState spatializationState =
1074         AudioPolicyManager::GetInstance().GetSpatializationState(mStreamUsage);
1075     spatializationEnabled_ = std::to_string(spatializationState.spatializationEnabled);
1076     headTrackingEnabled_ = std::to_string(spatializationState.headTrackingEnabled);
1077     if (mStreamUsage == STREAM_USAGE_SYSTEM || mStreamUsage == STREAM_USAGE_DTMF ||
1078         mStreamUsage == STREAM_USAGE_ENFORCED_TONE || mStreamUsage == STREAM_USAGE_ULTRASONIC ||
1079         mStreamUsage == STREAM_USAGE_NAVIGATION || mStreamUsage == STREAM_USAGE_NOTIFICATION) {
1080         effectMode = EFFECT_NONE;
1081     }
1082 
1083     pa_proplist *propList = pa_proplist_new();
1084     pa_channel_map map;
1085     int32_t res = SetPaProplist(propList, map, audioParams, streamName, streamStartTime);
1086     CHECK_AND_RETURN_RET(res == AUDIO_CLIENT_SUCCESS, res);
1087 
1088     paStream = pa_stream_new_with_proplist(context, streamName.c_str(), &sampleSpec, &map, propList);
1089     if (!paStream) {
1090         error = pa_context_errno(context);
1091         AUDIO_ERR_LOG("create stream Failed, error: %{public}d", error);
1092         pa_proplist_free(propList);
1093         pa_threaded_mainloop_unlock(mainLoop);
1094         ResetPAAudioClient();
1095         AUDIO_ERR_LOG("pa_stream_new_with_proplist failed, error: %{public}d", error);
1096         return AUDIO_CLIENT_CREATE_STREAM_ERR;
1097     }
1098 
1099     pa_proplist_free(propList);
1100     pa_stream_set_state_callback(paStream, PAStreamStateCb, (void *)this);
1101     pa_stream_set_moved_callback(paStream, PAStreamMovedCb, (void *)this); // used to notify sink/source moved
1102     pa_stream_set_write_callback(paStream, PAStreamWriteCb, (void *)this);
1103     pa_stream_set_read_callback(paStream, PAStreamReadCb, (void *)this);
1104     pa_stream_set_latency_update_callback(paStream, PAStreamLatencyUpdateCb, mainLoop);
1105     pa_stream_set_underflow_callback(paStream, PAStreamUnderFlowCb, (void *)this);
1106     pa_stream_set_event_callback(paStream, PAStreamEventCb, (void *)this);
1107 
1108     pa_threaded_mainloop_unlock(mainLoop);
1109     return AUDIO_CLIENT_SUCCESS;
1110 }
1111 
CreateStream(AudioStreamParams audioParams,AudioStreamType audioType)1112 int32_t AudioServiceClient::CreateStream(AudioStreamParams audioParams, AudioStreamType audioType)
1113 {
1114     AUDIO_INFO_LOG("AudioServiceClient::CreateStream");
1115     int error;
1116     lock_guard<mutex> lockdata(dataMutex_);
1117     int32_t ret = CheckReturnIfinvalid(mainLoop && context, AUDIO_CLIENT_ERR);
1118     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_ERR);
1119 
1120     CHECK_AND_RETURN_RET(eAudioClientType != AUDIO_SERVICE_CLIENT_CONTROLLER, AUDIO_CLIENT_INVALID_PARAMS_ERR);
1121 
1122     error = CreateStreamWithPa(audioParams, audioType);
1123     if (error < 0) {
1124         AUDIO_ERR_LOG("Create Stream With Pa Failed");
1125         return AUDIO_CLIENT_CREATE_STREAM_ERR;
1126     }
1127     error = ConnectStreamToPA();
1128     streamInfoUpdated_ = false;
1129     if (error < 0) {
1130         AUDIO_ERR_LOG("Create Stream Failed");
1131         ResetPAAudioClient();
1132         return AUDIO_CLIENT_CREATE_STREAM_ERR;
1133     }
1134     RegisterSpatializationStateEventListener();
1135 
1136     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1137         error = InitializeAudioCache();
1138         if (error < 0) {
1139             AUDIO_ERR_LOG("Initialize audio cache failed");
1140             ResetPAAudioClient();
1141             return AUDIO_CLIENT_CREATE_STREAM_ERR;
1142         }
1143 
1144         if (SetStreamRenderRate(renderRate) != AUDIO_CLIENT_SUCCESS) {
1145             AUDIO_ERR_LOG("Set render rate failed");
1146         }
1147 
1148         effectSceneName = IAudioStream::GetEffectSceneName(audioType);
1149         if (SetStreamAudioEffectMode(effectMode) != AUDIO_CLIENT_SUCCESS) {
1150             AUDIO_ERR_LOG("Set audio effect mode failed");
1151         }
1152     }
1153 
1154     state_ = PREPARED;
1155     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1156     if (streamCb != nullptr) {
1157         streamCb->OnStateChange(PREPARED);
1158     }
1159     return AUDIO_CLIENT_SUCCESS;
1160 }
1161 
GetUnderflowCount()1162 uint32_t AudioServiceClient::GetUnderflowCount()
1163 {
1164     return underFlowCount;
1165 }
1166 
GetSessionID(uint32_t & sessionID) const1167 int32_t AudioServiceClient::GetSessionID(uint32_t &sessionID) const
1168 {
1169     AUDIO_DEBUG_LOG("GetSessionID sessionID: %{public}d", sessionID_);
1170     CHECK_AND_RETURN_RET(sessionID_ != PA_INVALID_INDEX && sessionID_ != 0, AUDIO_CLIENT_ERR);
1171     sessionID = sessionID_;
1172     return AUDIO_CLIENT_SUCCESS;
1173 }
1174 
StartStream(StateChangeCmdType cmdType)1175 int32_t AudioServiceClient::StartStream(StateChangeCmdType cmdType)
1176 {
1177     AUDIO_INFO_LOG("AudioServiceClient::StartStream");
1178     writeCbStamp_ = ClockTime::GetCurNano() / AUDIO_US_PER_SECOND;
1179     Trace trace("AudioServiceClient::StartStream " + std::to_string(sessionID_));
1180     int error;
1181     lock_guard<mutex> lockdata(dataMutex_);
1182     unique_lock<mutex> stoppinglock(stoppingMutex_);
1183 
1184     // wait 1 second, timeout return error
1185     CHECK_AND_RETURN_RET_LOG(dataCv_.wait_for(stoppinglock, 1s, [this] {return state_ != STOPPING;}),
1186         AUDIO_CLIENT_START_STREAM_ERR, "StartStream: wait stopping timeout");
1187     stoppinglock.unlock();
1188     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1189     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
1190     pa_operation *operation = nullptr;
1191 
1192     pa_threaded_mainloop_lock(mainLoop);
1193 
1194     pa_stream_state_t state = pa_stream_get_state(paStream);
1195     if (state != PA_STREAM_READY) {
1196         error = pa_context_errno(context);
1197         pa_threaded_mainloop_unlock(mainLoop);
1198         AUDIO_ERR_LOG("Stream Start Failed, error: %{public}d", error);
1199         ResetPAAudioClient();
1200         return AUDIO_CLIENT_START_STREAM_ERR;
1201     }
1202 
1203     hasFirstFrameWrited_ = false;
1204 
1205     streamCmdStatus_ = 0;
1206     stateChangeCmdType_ = cmdType;
1207     operation = pa_stream_cork(paStream, 0, PAStreamStartSuccessCb, (void *)this);
1208 
1209     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1210         pa_threaded_mainloop_wait(mainLoop);
1211     }
1212     pa_operation_unref(operation);
1213     pa_threaded_mainloop_unlock(mainLoop);
1214 
1215     if (!streamCmdStatus_) {
1216         AUDIO_ERR_LOG("Stream Start Failed");
1217         ResetPAAudioClient();
1218         return AUDIO_CLIENT_START_STREAM_ERR;
1219     } else {
1220         return AUDIO_CLIENT_SUCCESS;
1221     }
1222 }
1223 
PauseStream(StateChangeCmdType cmdType)1224 int32_t AudioServiceClient::PauseStream(StateChangeCmdType cmdType)
1225 {
1226     AUDIO_INFO_LOG("AudioServiceClient::PauseStream");
1227     CheckOffloadBreakWaitWrite();
1228     lock_guard<mutex> lockdata(dataMutex_);
1229     lock_guard<mutex> lockctrl(ctrlMutex_);
1230     PAStreamCorkSuccessCb = PAStreamPauseSuccessCb;
1231     stateChangeCmdType_ = cmdType;
1232 
1233     int32_t ret = CorkStream();
1234     breakingWritePa_ = false;
1235     if (ret) {
1236         return ret;
1237     }
1238 
1239     if (!streamCmdStatus_) {
1240         AUDIO_ERR_LOG("Stream Pause Failed");
1241         return AUDIO_CLIENT_ERR;
1242     } else {
1243         return AUDIO_CLIENT_SUCCESS;
1244     }
1245 }
1246 
StopStreamPlayback()1247 int32_t AudioServiceClient::StopStreamPlayback()
1248 {
1249     if (state_ != PAUSED) {
1250         state_ = STOPPING;
1251         DrainAudioCache();
1252 
1253         int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1254         CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
1255 
1256         pa_threaded_mainloop_lock(mainLoop);
1257 
1258         streamDrainStatus_ = 0;
1259         pa_operation *operation = pa_stream_drain(paStream, PAStreamDrainInStopCb, (void *)this);
1260 
1261         if (operation == nullptr) {
1262             pa_threaded_mainloop_unlock(mainLoop);
1263             AUDIO_ERR_LOG("pa_stream_drain operation is null");
1264             return AUDIO_CLIENT_ERR;
1265         }
1266 
1267         pa_operation_unref(operation);
1268         pa_threaded_mainloop_unlock(mainLoop);
1269     } else {
1270         state_ = STOPPED;
1271         std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1272         if (streamCb != nullptr) {
1273             streamCb->OnStateChange(STOPPED);
1274         }
1275     }
1276     return AUDIO_CLIENT_SUCCESS;
1277 }
1278 
StopStream()1279 int32_t AudioServiceClient::StopStream()
1280 {
1281     AUDIO_INFO_LOG("AudioServiceClient::StopStream");
1282     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK && offloadEnable_) {
1283         return OffloadStopStream();
1284     }
1285     lock_guard<mutex> lockdata(dataMutex_);
1286     lock_guard<mutex> lockctrl(ctrlMutex_);
1287     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
1288         return StopStreamPlayback();
1289     } else {
1290         PAStreamCorkSuccessCb = PAStreamStopSuccessCb;
1291         int32_t ret = CorkStream();
1292         if (ret) {
1293             return ret;
1294         }
1295 
1296         if (!streamCmdStatus_) {
1297             AUDIO_ERR_LOG("Stream Stop Failed");
1298             return AUDIO_CLIENT_ERR;
1299         } else {
1300             if (internalRdBufLen_) {
1301                 (void)pa_stream_drop(paStream);
1302                 internalReadBuffer_ = nullptr;
1303                 internalRdBufLen_ = 0;
1304                 internalRdBufIndex_ = 0;
1305             }
1306             return AUDIO_CLIENT_SUCCESS;
1307         }
1308     }
1309 }
1310 
OffloadStopStream()1311 int32_t AudioServiceClient::OffloadStopStream()
1312 {
1313     AUDIO_INFO_LOG("AudioServiceClient::OffloadStopStream");
1314     CheckOffloadBreakWaitWrite();
1315     lock_guard<mutex> lockdata(dataMutex_);
1316     lock_guard<mutex> lockctrl(ctrlMutex_);
1317     state_ = STOPPING;
1318     DrainAudioCache();
1319 
1320     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1321     CHECK_AND_RETURN_RET(res >= 0, AUDIO_CLIENT_PA_ERR);
1322 
1323     PAStreamCorkSuccessCb = PAStreamStopSuccessCb;
1324     int32_t ret = CorkStream();
1325     breakingWritePa_ = false;
1326     if (ret) {
1327         return ret;
1328     }
1329     return AUDIO_CLIENT_SUCCESS;
1330 }
1331 
CorkStream()1332 int32_t AudioServiceClient::CorkStream()
1333 {
1334     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1335     CHECK_AND_RETURN_RET(res >= 0, AUDIO_CLIENT_PA_ERR);
1336 
1337     pa_operation *operation = nullptr;
1338 
1339     pa_threaded_mainloop_lock(mainLoop);
1340     pa_stream_state_t state = pa_stream_get_state(paStream);
1341     if (state != PA_STREAM_READY) {
1342         int32_t error = pa_context_errno(context);
1343         pa_threaded_mainloop_unlock(mainLoop);
1344         AUDIO_ERR_LOG("Stream Stop Failed : %{public}d", error);
1345         return AUDIO_CLIENT_ERR;
1346     }
1347 
1348     streamCmdStatus_ = 0;
1349     operation = pa_stream_cork(paStream, 1, PAStreamCorkSuccessCb, (void *)this);
1350 
1351     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1352         StartTimer(CORK_TIMEOUT_IN_SEC);
1353         pa_threaded_mainloop_wait(mainLoop);
1354         StopTimer();
1355         if (IsTimeOut()) {
1356             pa_threaded_mainloop_unlock(mainLoop);
1357             AUDIO_ERR_LOG("CorkStream timeout");
1358             return AUDIO_CLIENT_ERR;
1359         }
1360     }
1361     pa_operation_unref(operation);
1362     if (InitializePAProbListOffload() != AUDIO_CLIENT_SUCCESS) {
1363         pa_threaded_mainloop_unlock(mainLoop);
1364         return AUDIO_CLIENT_ERR;
1365     }
1366     pa_threaded_mainloop_unlock(mainLoop);
1367 
1368     return AUDIO_CLIENT_SUCCESS;
1369 }
1370 
FlushStream()1371 int32_t AudioServiceClient::FlushStream()
1372 {
1373     AUDIO_INFO_LOG("In");
1374     lock_guard<mutex> lock(dataMutex_);
1375     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1376     CHECK_AND_RETURN_RET(res >= 0, AUDIO_CLIENT_PA_ERR);
1377 
1378     pa_operation *operation = nullptr;
1379     pa_threaded_mainloop_lock(mainLoop);
1380 
1381     pa_stream_state_t state = pa_stream_get_state(paStream);
1382     if (state != PA_STREAM_READY) {
1383         int error = pa_context_errno(context);
1384         pa_threaded_mainloop_unlock(mainLoop);
1385         AUDIO_ERR_LOG("Stream Flush Failed, error: %{public}d", error);
1386         return AUDIO_CLIENT_ERR;
1387     }
1388 
1389     streamFlushStatus_ = 0;
1390     operation = pa_stream_flush(paStream, PAStreamFlushSuccessCb, (void *)this);
1391     if (operation == nullptr) {
1392         AUDIO_ERR_LOG("Stream Flush Operation Failed");
1393         pa_threaded_mainloop_unlock(mainLoop);
1394         return AUDIO_CLIENT_ERR;
1395     }
1396 
1397     UpdatePropListForFlush();
1398 
1399     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1400         static bool triggerDumpStacktrace_ = true;
1401         if (triggerDumpStacktrace_ == true) {
1402             AudioXCollie audioXCollie("AudioServiceClient::DumpTrace", MAINLOOP_WAIT_TIMEOUT_IN_SEC, [this](void *) {
1403                 audioSystemManager_->GetAudioParameter(FORCED_DUMP_PULSEAUDIO_STACKTRACE);
1404                 triggerDumpStacktrace_ = false;
1405                 pa_threaded_mainloop_signal(this->mainLoop, 0);
1406             }, nullptr, 0);
1407             pa_threaded_mainloop_wait(mainLoop);
1408         } else {
1409             StartTimer(FLUSH_TIMEOUT_IN_SEC);
1410             pa_threaded_mainloop_wait(mainLoop);
1411             StopTimer();
1412             if (IsTimeOut()) {
1413                 pa_threaded_mainloop_unlock(mainLoop);
1414                 AUDIO_ERR_LOG("FlushStream timeout");
1415                 return AUDIO_CLIENT_ERR;
1416             }
1417         }
1418     }
1419     pa_operation_unref(operation);
1420     pa_threaded_mainloop_unlock(mainLoop);
1421 
1422     CHECK_AND_RETURN_RET_LOG(streamFlushStatus_ == 1, AUDIO_CLIENT_ERR, "Stream Flush failed");
1423     acache_.readIndex = 0;
1424     acache_.writeIndex = 0;
1425     acache_.isFull = false;
1426     return AUDIO_CLIENT_SUCCESS;
1427 }
1428 
UpdatePropListForFlush()1429 void AudioServiceClient::UpdatePropListForFlush()
1430 {
1431     pa_proplist *propListFlushTrue = pa_proplist_new();
1432     pa_proplist_sets(propListFlushTrue, "stream.flush", "true");
1433     pa_operation *updatePropOperationTrue = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propListFlushTrue,
1434         nullptr, nullptr);
1435     pa_proplist_free(propListFlushTrue);
1436     pa_operation_unref(updatePropOperationTrue);
1437 
1438     pa_proplist *propListFlushFalse = pa_proplist_new();
1439     pa_proplist_sets(propListFlushFalse, "stream.flush", "false");
1440     pa_operation *updatePropOperationFalse = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE,
1441         propListFlushFalse, nullptr, nullptr);
1442     pa_proplist_free(propListFlushFalse);
1443     pa_operation_unref(updatePropOperationFalse);
1444 }
1445 
DrainStream()1446 int32_t AudioServiceClient::DrainStream()
1447 {
1448     AUDIO_INFO_LOG("AudioServiceClient::DrainStream");
1449     int32_t error;
1450 
1451     CHECK_AND_RETURN_RET_LOG(eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK,
1452         AUDIO_CLIENT_ERR, "Drain is not supported");
1453 
1454     lock_guard<mutex> lock(dataMutex_);
1455 
1456     error = DrainAudioCache();
1457     CHECK_AND_RETURN_RET_LOG(error == AUDIO_CLIENT_SUCCESS, AUDIO_CLIENT_ERR,
1458         "Audio cache drain failed");
1459     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1460     CHECK_AND_RETURN_RET(res >= 0, AUDIO_CLIENT_PA_ERR);
1461 
1462     pa_operation *operation = nullptr;
1463 
1464     pa_threaded_mainloop_lock(mainLoop);
1465 
1466     pa_stream_state_t state = pa_stream_get_state(paStream);
1467     if (state != PA_STREAM_READY) {
1468         error = pa_context_errno(context);
1469         pa_threaded_mainloop_unlock(mainLoop);
1470         AUDIO_ERR_LOG("Stream Drain Failed");
1471         return AUDIO_CLIENT_ERR;
1472     }
1473 
1474     streamDrainStatus_ = 0;
1475     operation = pa_stream_drain(paStream, PAStreamDrainSuccessCb, (void *)this);
1476 
1477     while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
1478         StartTimer(DRAIN_TIMEOUT_IN_SEC);
1479         pa_threaded_mainloop_wait(mainLoop);
1480         StopTimer();
1481         if (IsTimeOut()) {
1482             pa_threaded_mainloop_unlock(mainLoop);
1483             AUDIO_ERR_LOG("Drain timeout");
1484             return AUDIO_CLIENT_ERR;
1485         }
1486     }
1487     pa_operation_unref(operation);
1488     pa_threaded_mainloop_unlock(mainLoop);
1489 
1490     if (!streamDrainStatus_) {
1491         AUDIO_ERR_LOG("Stream Drain Failed");
1492         return AUDIO_CLIENT_ERR;
1493     } else {
1494         return AUDIO_CLIENT_SUCCESS;
1495     }
1496 }
1497 
PaWriteStream(const uint8_t * buffer,size_t & length)1498 int32_t AudioServiceClient::PaWriteStream(const uint8_t *buffer, size_t &length)
1499 {
1500     int error = 0;
1501     if (firstFrame_) {
1502         AudioSystemManager::GetInstance()->RequestThreadPriority(gettid());
1503         firstFrame_ = false;
1504     }
1505     if (!hasFirstFrameWrited_) { OnFirstFrameWriting(); }
1506 
1507     if ((lastOffloadUpdateFinishTime_ != 0) &&
1508         (chrono::system_clock::to_time_t(chrono::system_clock::now()) > lastOffloadUpdateFinishTime_)) {
1509         AUDIO_INFO_LOG("PaWriteStream switching curTime %{public}" PRIu64 ", switchTime %{public}" PRIu64,
1510             chrono::system_clock::to_time_t(chrono::system_clock::now()), lastOffloadUpdateFinishTime_);
1511         error = UpdatePolicyOffload(offloadNextStateTargetPolicy_);
1512         lastOffloadUpdateFinishTime_ = 0;
1513     }
1514     CHECK_AND_RETURN_RET(error == AUDIO_CLIENT_SUCCESS, error);
1515 
1516     while (length > 0) {
1517         size_t writableSize = 0;
1518         size_t origWritableSize = 0;
1519 
1520         error = WaitWriteable(length, writableSize);
1521         if (error != 0) {
1522             return error;
1523         }
1524 
1525         AUDIO_DEBUG_LOG("Write stream: writable size = %{public}zu, length = %{public}zu", writableSize, length);
1526         origWritableSize = writableSize;
1527         if (writableSize > length) {
1528             writableSize = length;
1529         }
1530 
1531         writableSize = AlignToAudioFrameSize(writableSize, sampleSpec);
1532         if (writableSize == 0) {
1533             AUDIO_ERR_LOG("Align to frame size failed");
1534             error = AUDIO_CLIENT_WRITE_STREAM_ERR;
1535             break;
1536         }
1537 
1538         Trace trace2("PaWriteStream Write:" + std::to_string(writableSize) + "/" + std::to_string(origWritableSize));
1539         error = pa_stream_write(paStream, (void *)buffer, writableSize, nullptr, 0LL,
1540                                 PA_SEEK_RELATIVE);
1541         if (error < 0) {
1542             AUDIO_ERR_LOG("Write stream failed");
1543             error = AUDIO_CLIENT_WRITE_STREAM_ERR;
1544             break;
1545         }
1546 
1547         AUDIO_DEBUG_LOG("Writable size: %{public}zu, bytes to write: %{public}zu, return val: %{public}d",
1548                         writableSize, length, error);
1549         buffer = buffer + writableSize;
1550         length -= writableSize;
1551 
1552         HandleRenderPositionCallbacks(writableSize * speed_);
1553     }
1554 
1555     return error;
1556 }
1557 
WaitWriteable(size_t length,size_t & writableSize)1558 int32_t AudioServiceClient::WaitWriteable(size_t length, size_t& writableSize)
1559 {
1560     Trace trace1("PaWriteStream WaitWriteable");
1561     while (true) {
1562         writableSize = pa_stream_writable_size(paStream);
1563         if (writableSize != 0) {
1564             if (!offloadEnable_) {
1565                 break;
1566             }
1567             uint32_t tgt = acache_.totalCacheSizeTgt != 0 ? acache_.totalCacheSizeTgt : acache_.totalCacheSize;
1568             if (writableSize < tgt) {
1569                 AUDIO_DEBUG_LOG("PaWriteStream: WaitWriteable writableSize %zu < %u wait for more",
1570                     writableSize, tgt);
1571             } else {
1572                 writableSize = writableSize / tgt * tgt;
1573                 break;
1574             }
1575         }
1576         AUDIO_DEBUG_LOG("PaWriteStream: WaitWriteable");
1577         StartTimer(WRITE_TIMEOUT_IN_SEC);
1578         if (!breakingWritePa_ && state_ == RUNNING) {
1579             pa_threaded_mainloop_wait(mainLoop);
1580         }
1581         StopTimer();
1582         if (IsTimeOut()) {
1583             AUDIO_ERR_LOG("Write timeout");
1584             return AUDIO_CLIENT_WRITE_STREAM_ERR;
1585         }
1586         if (breakingWritePa_ || state_ != RUNNING) {
1587             AUDIO_WARNING_LOG("PaWriteStream: WaitWriteable breakingWritePa(%d) or state_(%d) "
1588                 "not running, Writable size: %{public}zu, bytes to write: %{public}zu",
1589                 breakingWritePa_, state_, writableSize, length);
1590             return AUDIO_CLIENT_WRITE_STREAM_ERR;
1591         }
1592     }
1593     return 0;
1594 }
1595 
HandleRenderPositionCallbacks(size_t bytesWritten)1596 void AudioServiceClient::HandleRenderPositionCallbacks(size_t bytesWritten)
1597 {
1598     mTotalBytesWritten += bytesWritten;
1599     CHECK_AND_RETURN_LOG(mFrameSize != 0, "capturePeriodPositionCb not set");
1600 
1601     uint64_t writtenFrameNumber = mTotalBytesWritten / mFrameSize;
1602     AUDIO_DEBUG_LOG("frame size: %{public}d", mFrameSize);
1603 
1604     {
1605         std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
1606         if (!mMarkReached) {
1607             AUDIO_DEBUG_LOG("frame mark position: %{public}" PRIu64 ", Total frames written: %{public}" PRIu64,
1608                 static_cast<uint64_t>(mFrameMarkPosition), static_cast<uint64_t>(writtenFrameNumber));
1609             if (writtenFrameNumber >= mFrameMarkPosition) {
1610                 AUDIO_DEBUG_LOG("audio service client OnMarkReached");
1611                 SendRenderMarkReachedRequestEvent(mFrameMarkPosition);
1612                 mMarkReached = true;
1613             }
1614         }
1615     }
1616 
1617     {
1618         std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
1619         mFramePeriodWritten += (bytesWritten / mFrameSize);
1620         AUDIO_DEBUG_LOG("frame period number: %{public}" PRIu64 ", Total frames written: %{public}" PRIu64,
1621             static_cast<uint64_t>(mFramePeriodNumber), static_cast<uint64_t>(writtenFrameNumber));
1622         if (mFramePeriodWritten >= mFramePeriodNumber && mFramePeriodNumber > 0) {
1623             mFramePeriodWritten %= mFramePeriodNumber;
1624             AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRIu64,
1625                 static_cast<uint64_t>(mFramePeriodWritten));
1626             SendRenderPeriodReachedRequestEvent(mFramePeriodNumber);
1627         }
1628     }
1629 }
1630 
DrainAudioCache()1631 int32_t AudioServiceClient::DrainAudioCache()
1632 {
1633     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1634     CHECK_AND_RETURN_RET(res >= 0, AUDIO_CLIENT_PA_ERR);
1635 
1636     pa_threaded_mainloop_lock(mainLoop);
1637 
1638     int32_t error = 0;
1639     if (acache_.buffer == nullptr) {
1640         AUDIO_ERR_LOG("Drain cache failed");
1641         pa_threaded_mainloop_unlock(mainLoop);
1642         return AUDIO_CLIENT_ERR;
1643     }
1644 
1645     size_t length = acache_.writeIndex - acache_.readIndex;
1646     const uint8_t *buffer = acache_.buffer.get();
1647 
1648     error = PaWriteStream(buffer, length);
1649 
1650     acache_.readIndex = 0;
1651     acache_.writeIndex = 0;
1652 
1653     pa_threaded_mainloop_unlock(mainLoop);
1654     return error;
1655 }
1656 
WriteToAudioCache(const StreamBuffer & stream)1657 size_t AudioServiceClient::WriteToAudioCache(const StreamBuffer &stream)
1658 {
1659     if (stream.buffer == nullptr) {
1660         return 0;
1661     }
1662 
1663     const uint8_t *inputBuffer = stream.buffer;
1664     uint8_t *cacheBuffer = acache_.buffer.get() + acache_.writeIndex;
1665 
1666     size_t inputLen = stream.bufferLen;
1667     if (acache_.totalCacheSize != acache_.totalCacheSizeTgt && acache_.totalCacheSizeTgt != 0) {
1668         uint32_t tgt = acache_.totalCacheSizeTgt;
1669         if (tgt < acache_.totalCacheSize && tgt < acache_.writeIndex) {
1670             tgt = acache_.writeIndex;
1671         }
1672         acache_.totalCacheSize = tgt;
1673     }
1674     while (inputLen > 0) {
1675         size_t writableSize = acache_.totalCacheSize - acache_.writeIndex;
1676 
1677         if (writableSize > inputLen) {
1678             writableSize = inputLen;
1679         }
1680 
1681         if (writableSize == 0) {
1682             break;
1683         }
1684 
1685         if (memcpy_s(cacheBuffer, acache_.totalCacheSize, inputBuffer, writableSize)) {
1686             break;
1687         }
1688 
1689         inputBuffer = inputBuffer + writableSize;
1690         cacheBuffer = cacheBuffer + writableSize;
1691         inputLen -= writableSize;
1692         acache_.writeIndex += writableSize;
1693     }
1694 
1695     if ((acache_.writeIndex - acache_.readIndex) == acache_.totalCacheSize) {
1696         acache_.isFull = true;
1697     }
1698 
1699     return (stream.bufferLen - inputLen);
1700 }
1701 
WriteStreamInCb(const StreamBuffer & stream,int32_t & pError)1702 size_t AudioServiceClient::WriteStreamInCb(const StreamBuffer &stream, int32_t &pError)
1703 {
1704     lock_guard<mutex> lock(dataMutex_);
1705     int error = 0;
1706     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, 0, pError) < 0) {
1707         return 0;
1708     }
1709 
1710     pa_threaded_mainloop_lock(mainLoop);
1711 
1712     const uint8_t *buffer = stream.buffer;
1713     size_t length = stream.bufferLen;
1714     error = PaWriteStream(buffer, length);
1715     pa_threaded_mainloop_unlock(mainLoop);
1716     pError = error;
1717     return (stream.bufferLen - length);
1718 }
1719 
WriteStream(const StreamBuffer & stream,int32_t & pError)1720 size_t AudioServiceClient::WriteStream(const StreamBuffer &stream, int32_t &pError)
1721 {
1722     lock_guard<timed_mutex> lockoffload(offloadWaitWriteableMutex_);
1723     lock_guard<mutex> lock(dataMutex_);
1724     int error = 0;
1725     size_t cachedLen = WriteToAudioCache(stream);
1726 
1727     if (!acache_.isFull) {
1728         pError = error;
1729         return cachedLen;
1730     }
1731     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, 0, pError) < 0) {
1732         return 0;
1733     }
1734     pa_threaded_mainloop_lock(mainLoop);
1735 
1736     if (acache_.buffer == nullptr) {
1737         AUDIO_ERR_LOG("Buffer is null");
1738         pa_threaded_mainloop_unlock(mainLoop);
1739         pError = AUDIO_CLIENT_WRITE_STREAM_ERR;
1740         return cachedLen;
1741     }
1742 
1743     const uint8_t *buffer = acache_.buffer.get();
1744     size_t length = acache_.totalCacheSize;
1745 
1746     error = PaWriteStream(buffer, length);
1747     const size_t written = acache_.totalCacheSize - length;
1748     if (!error && written > 0) {
1749         acache_.readIndex += written;
1750         acache_.isFull = false;
1751     }
1752     if (acache_.totalCacheSize < length) {
1753         AUDIO_ERR_LOG("WriteStream totalCacheSize(%u) < length(%zu)", acache_.totalCacheSize, length);
1754     }
1755 
1756     if (!error && (length >= 0) && !acache_.isFull) {
1757         error = AdjustAcache(stream, cachedLen);
1758     }
1759 
1760     pa_threaded_mainloop_unlock(mainLoop);
1761     pError = error;
1762     return cachedLen;
1763 }
1764 
AdjustAcache(const StreamBuffer & stream,size_t & cachedLen)1765 int32_t AudioServiceClient::AdjustAcache(const StreamBuffer& stream, size_t& cachedLen)
1766 {
1767     if (acache_.isFull) {
1768         return 0;
1769     }
1770     uint8_t *cacheBuffer = acache_.buffer.get();
1771     uint32_t offset = acache_.readIndex;
1772     if (acache_.writeIndex > acache_.readIndex) {
1773         uint32_t size = (acache_.writeIndex - acache_.readIndex);
1774         auto* func = memcpy_s;
1775         if (offset < size) { // overlop
1776             func = memmove_s;
1777         }
1778         CHECK_AND_RETURN_RET_LOG(!func(cacheBuffer, acache_.totalCacheSize, cacheBuffer + offset, size),
1779             AUDIO_CLIENT_WRITE_STREAM_ERR, "Update cache failed, offset %u, size %u", offset, size);
1780         acache_.readIndex = 0;
1781         acache_.writeIndex = size;
1782     } else {
1783         acache_.readIndex = 0;
1784         acache_.writeIndex = 0;
1785     }
1786 
1787     if (cachedLen < stream.bufferLen) {
1788         StreamBuffer str;
1789         str.buffer = stream.buffer + cachedLen;
1790         str.bufferLen = stream.bufferLen - cachedLen;
1791         AUDIO_DEBUG_LOG("writing pending data to audio cache: %{public}d", str.bufferLen);
1792         cachedLen += WriteToAudioCache(str);
1793     }
1794     return 0;
1795 }
1796 
1797 
UpdateReadBuffer(uint8_t * buffer,size_t & length,size_t & readSize)1798 int32_t AudioServiceClient::UpdateReadBuffer(uint8_t *buffer, size_t &length, size_t &readSize)
1799 {
1800     size_t l = (internalRdBufLen_ < length) ? internalRdBufLen_ : length;
1801     CHECK_AND_RETURN_RET_LOG(!(memcpy_s(buffer, length, (const uint8_t*)internalReadBuffer_ + internalRdBufIndex_, l)),
1802         AUDIO_CLIENT_READ_STREAM_ERR, "Update read buffer failed");
1803 
1804     length -= l;
1805     internalRdBufIndex_ += l;
1806     internalRdBufLen_ -= l;
1807     readSize += l;
1808 
1809     if (!internalRdBufLen_) {
1810         int retVal = pa_stream_drop(paStream);
1811         internalReadBuffer_ = nullptr;
1812         internalRdBufLen_ = 0;
1813         internalRdBufIndex_ = 0;
1814         CHECK_AND_RETURN_RET_LOG(retVal >= 0, AUDIO_CLIENT_READ_STREAM_ERR,
1815             "pa_stream_drop failed, retVal: %{public}d", retVal);
1816     }
1817 
1818     return 0;
1819 }
1820 
RenderPrebuf(uint32_t writeLen)1821 int32_t AudioServiceClient::RenderPrebuf(uint32_t writeLen)
1822 {
1823     Trace trace("RenderPrebuf");
1824     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
1825         return AUDIO_CLIENT_PA_ERR;
1826     }
1827     const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
1828     CHECK_AND_RETURN_RET_LOG(bufferAttr != nullptr, AUDIO_CLIENT_ERR,
1829         "pa_stream_get_buffer_attr returned nullptr");
1830 
1831     CHECK_AND_RETURN_RET(bufferAttr->maxlength > writeLen, AUDIO_CLIENT_SUCCESS);
1832     size_t diff = bufferAttr->maxlength - writeLen;
1833 
1834     int32_t writeError;
1835     StreamBuffer prebufStream;
1836     prebufStream.buffer = preBuf_.get();
1837     if (writeLen == 0) {
1838         return AUDIO_CLIENT_SUCCESS;
1839     } else if (writeLen > diff) {
1840         prebufStream.bufferLen = diff;
1841     } else {
1842         prebufStream.bufferLen = writeLen;
1843     }
1844 
1845     preFrameNum_ = prebufStream.bufferLen / mFrameSize;
1846 
1847     size_t bytesWritten {0};
1848     AUDIO_INFO_LOG("RenderPrebuf start");
1849     while (true) {
1850         bytesWritten += WriteStream(prebufStream, writeError);
1851         CHECK_AND_RETURN_RET_LOG(!writeError, AUDIO_CLIENT_ERR,
1852             "RenderPrebuf failed: %{public}d", writeError);
1853 
1854         if (diff <= bytesWritten) {
1855             break;
1856         }
1857 
1858         if ((diff - bytesWritten) < writeLen) {
1859             prebufStream.bufferLen = diff - bytesWritten;
1860         }
1861     }
1862 
1863     return AUDIO_CLIENT_SUCCESS;
1864 }
1865 
OnTimeOut()1866 void AudioServiceClient::OnTimeOut()
1867 {
1868     AUDIO_ERR_LOG("Inside timeout callback with pid:%{public}d uid:%{public}d", clientPid_, clientUid_);
1869 
1870     CHECK_AND_RETURN_LOG(mainLoop != nullptr, "OnTimeOut failed: mainLoop == nullptr");
1871     pa_threaded_mainloop_signal(mainLoop, 0);
1872 }
1873 
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId)1874 void AudioServiceClient::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId)
1875 {
1876     AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid);
1877     clientPid_ = clientPid;
1878     clientUid_ = clientUid;
1879     appTokenId_ = appTokenId;
1880 }
1881 
GetStreamClass()1882 IAudioStream::StreamClass AudioServiceClient::GetStreamClass()
1883 {
1884     return streamClass_;
1885 }
1886 
GetStreamSwitchInfo(SwitchInfo & info)1887 void AudioServiceClient::GetStreamSwitchInfo(SwitchInfo& info)
1888 {
1889     info.cachePath = cachePath_;
1890     info.rendererSampleRate = rendererSampleRate;
1891     info.underFlowCount = underFlowCount;
1892     info.effectMode = effectMode;
1893     info.renderMode = renderMode_;
1894     info.captureMode = captureMode_;
1895     info.renderRate = renderRate;
1896     info.clientPid = clientPid_;
1897     info.clientUid = clientUid_;
1898     info.volume = volumeFactor_;
1899 
1900     info.frameMarkPosition = mFrameMarkPosition;
1901     info.renderPositionCb = mRenderPositionCb;
1902     info.capturePositionCb = mCapturePositionCb;
1903 
1904     info.framePeriodNumber = mFramePeriodNumber;
1905     info.renderPeriodPositionCb = mRenderPeriodPositionCb;
1906     info.capturePeriodPositionCb = mCapturePeriodPositionCb;
1907 
1908     info.rendererWriteCallback = writeCallback_;
1909 }
1910 
HandleCapturePositionCallbacks(size_t bytesRead)1911 void AudioServiceClient::HandleCapturePositionCallbacks(size_t bytesRead)
1912 {
1913     mTotalBytesRead += bytesRead;
1914     CHECK_AND_RETURN_LOG(mFrameSize != 0, "HandleCapturePositionCallbacks: capturePeriodPositionCb not set");
1915 
1916     uint64_t readFrameNumber = mTotalBytesRead / mFrameSize;
1917     AUDIO_DEBUG_LOG("frame size: %{public}d", mFrameSize);
1918     {
1919         std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
1920         if (!mMarkReached) {
1921             AUDIO_DEBUG_LOG("frame mark position: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1922                 static_cast<uint64_t>(mFrameMarkPosition), static_cast<uint64_t>(readFrameNumber));
1923             if (readFrameNumber >= mFrameMarkPosition) {
1924                 AUDIO_DEBUG_LOG("audio service client capturer OnMarkReached");
1925                 SendCapturerMarkReachedRequestEvent(mFrameMarkPosition);
1926                 mMarkReached = true;
1927             }
1928         }
1929     }
1930 
1931     {
1932         std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
1933         mFramePeriodRead += (bytesRead / mFrameSize);
1934         AUDIO_DEBUG_LOG("frame period number: %{public}" PRIu64 ", Total frames read: %{public}" PRIu64,
1935             static_cast<uint64_t>(mFramePeriodNumber), static_cast<uint64_t>(readFrameNumber));
1936         if (mFramePeriodRead >= mFramePeriodNumber && mFramePeriodNumber > 0) {
1937             mFramePeriodRead %= mFramePeriodNumber;
1938             AUDIO_DEBUG_LOG("audio service client OnPeriodReached, remaining frames: %{public}" PRIu64,
1939                 static_cast<uint64_t>(mFramePeriodRead));
1940             SendCapturerPeriodReachedRequestEvent(mFramePeriodNumber);
1941         }
1942     }
1943 }
1944 
ReadStream(StreamBuffer & stream,bool isBlocking)1945 int32_t AudioServiceClient::ReadStream(StreamBuffer &stream, bool isBlocking)
1946 {
1947     uint8_t *buffer = stream.buffer;
1948     size_t length = stream.bufferLen;
1949     size_t readSize = 0;
1950     lock_guard<mutex> lock(dataMutex_);
1951     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
1952     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
1953 
1954     pa_threaded_mainloop_lock(mainLoop);
1955     while (length > 0) {
1956         while (!internalReadBuffer_) {
1957             int retVal = pa_stream_peek(paStream, &internalReadBuffer_, &internalRdBufLen_);
1958             if (retVal < 0) {
1959                 AUDIO_ERR_LOG("pa_stream_peek failed, retVal: %{public}d", retVal);
1960                 pa_threaded_mainloop_unlock(mainLoop);
1961                 return AUDIO_CLIENT_READ_STREAM_ERR;
1962             }
1963 
1964             if (internalRdBufLen_ <= 0) {
1965                 if (isBlocking) {
1966                     StartTimer(READ_TIMEOUT_IN_SEC);
1967                     pa_threaded_mainloop_wait(mainLoop);
1968                     StopTimer();
1969                     if (IsTimeOut()) {
1970                         AUDIO_ERR_LOG("Read timeout");
1971                         pa_threaded_mainloop_unlock(mainLoop);
1972                         return AUDIO_CLIENT_READ_STREAM_ERR;
1973                     }
1974                 } else {
1975                     pa_threaded_mainloop_unlock(mainLoop);
1976                     HandleCapturePositionCallbacks(readSize);
1977                     return readSize;
1978                 }
1979             } else if (!internalReadBuffer_) {
1980                 retVal = pa_stream_drop(paStream);
1981                 if (retVal < 0) {
1982                     AUDIO_ERR_LOG("pa_stream_drop failed, retVal: %{public}d", retVal);
1983                     pa_threaded_mainloop_unlock(mainLoop);
1984                     return AUDIO_CLIENT_READ_STREAM_ERR;
1985                 }
1986             } else {
1987                 internalRdBufIndex_ = 0;
1988                 AUDIO_DEBUG_LOG("buffer size from PA: %{public}zu", internalRdBufLen_);
1989             }
1990         }
1991 
1992         if (UpdateReadBuffer(buffer, length, readSize) != 0) {
1993             pa_threaded_mainloop_unlock(mainLoop);
1994             return AUDIO_CLIENT_READ_STREAM_ERR;
1995         }
1996         buffer = stream.buffer + readSize;
1997     }
1998     pa_threaded_mainloop_unlock(mainLoop);
1999     HandleCapturePositionCallbacks(readSize);
2000 
2001     return readSize;
2002 }
2003 
ReleaseStream(bool releaseRunner)2004 int32_t AudioServiceClient::ReleaseStream(bool releaseRunner)
2005 {
2006     state_ = RELEASED;
2007     lock_guard<mutex> lockdata(dataMutex_);
2008     ResetPAAudioClient();
2009 
2010     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
2011     if (streamCb != nullptr) {
2012         streamCb->OnStateChange(RELEASED);
2013     }
2014 
2015     {
2016         lock_guard<mutex> runnerlock(runnerMutex_);
2017         if (releaseRunner) {
2018             AUDIO_INFO_LOG("runner remove");
2019             SetEventRunner(nullptr);
2020             runnerReleased_ = true;
2021         }
2022     }
2023 
2024     return AUDIO_CLIENT_SUCCESS;
2025 }
2026 
SetBufferSizeInMsec(int32_t bufferSizeInMsec)2027 int32_t AudioServiceClient::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
2028 {
2029     size_t bufferSize =  pa_usec_to_bytes(bufferSizeInMsec * PA_USEC_PER_MSEC, &sampleSpec);
2030     setBufferSize_ = bufferSize;
2031     return AUDIO_CLIENT_SUCCESS;
2032 }
2033 
GetMinimumBufferSize(size_t & minBufferSize) const2034 int32_t AudioServiceClient::GetMinimumBufferSize(size_t &minBufferSize) const
2035 {
2036     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2037         return AUDIO_CLIENT_PA_ERR;
2038     }
2039 
2040     const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
2041 
2042     CHECK_AND_RETURN_RET_LOG(bufferAttr != nullptr, AUDIO_CLIENT_ERR,
2043         "pa_stream_get_buffer_attr returned nullptr");
2044 
2045     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2046         if (renderMode_ == RENDER_MODE_CALLBACK) {
2047             minBufferSize = (size_t)bufferAttr->minreq;
2048         } else {
2049             if (setBufferSize_) {
2050                 minBufferSize = setBufferSize_;
2051             } else {
2052                 minBufferSize = (size_t)bufferAttr->minreq;
2053             }
2054         }
2055     }
2056 
2057     if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
2058         minBufferSize = (size_t)bufferAttr->fragsize;
2059     }
2060 
2061     return AUDIO_CLIENT_SUCCESS;
2062 }
2063 
GetMinimumFrameCount(uint32_t & frameCount) const2064 int32_t AudioServiceClient::GetMinimumFrameCount(uint32_t &frameCount) const
2065 {
2066     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
2067     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
2068 
2069     size_t minBufferSize = 0;
2070 
2071     const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
2072 
2073     CHECK_AND_RETURN_RET_LOG(bufferAttr != nullptr, AUDIO_CLIENT_ERR,
2074         "pa_stream_get_buffer_attr returned nullptr");
2075 
2076     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2077         if (renderMode_ == RENDER_MODE_CALLBACK) {
2078             minBufferSize = (size_t)bufferAttr->minreq;
2079         } else {
2080             if (setBufferSize_) {
2081                 minBufferSize = setBufferSize_;
2082             } else {
2083                 minBufferSize = (size_t)bufferAttr->minreq;
2084             }
2085         }
2086     }
2087 
2088     if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
2089         minBufferSize = (size_t)bufferAttr->fragsize;
2090     }
2091 
2092     uint32_t bytesPerSample = pa_frame_size(&sampleSpec);
2093     CHECK_AND_RETURN_RET_LOG(bytesPerSample != 0, AUDIO_CLIENT_ERR,
2094         "GetMinimumFrameCount Failed");
2095 
2096     frameCount = minBufferSize / bytesPerSample;
2097     AUDIO_INFO_LOG("frame count: %{public}d", frameCount);
2098     return AUDIO_CLIENT_SUCCESS;
2099 }
2100 
GetBufferSizeForCapturer(size_t & bufferSize)2101 int32_t AudioServiceClient::GetBufferSizeForCapturer(size_t &bufferSize)
2102 {
2103     bufferSize = pa_usec_to_bytes(DEFAULT_BUFFER_TIME_MS * PA_USEC_PER_MSEC, &sampleSpec);
2104     return AUDIO_CLIENT_SUCCESS;
2105 }
2106 
GetFrameCountForCapturer(uint32_t & frameCount)2107 int32_t AudioServiceClient::GetFrameCountForCapturer(uint32_t &frameCount)
2108 {
2109     size_t bufferSize;
2110     GetBufferSizeForCapturer(bufferSize);
2111     size_t sampleSize = pa_sample_size_of_format(sampleSpec.format);
2112     frameCount = bufferSize / (sampleSize * sampleSpec.channels);
2113     return AUDIO_CLIENT_SUCCESS;
2114 }
2115 
GetClientPid()2116 int32_t AudioServiceClient::GetClientPid()
2117 {
2118     return clientPid_;
2119 }
2120 
GetSamplingRate() const2121 uint32_t AudioServiceClient::GetSamplingRate() const
2122 {
2123     return DEFAULT_SAMPLING_RATE;
2124 }
2125 
GetChannelCount() const2126 uint8_t AudioServiceClient::GetChannelCount() const
2127 {
2128     return DEFAULT_CHANNEL_COUNT;
2129 }
2130 
GetSampleSize() const2131 uint8_t AudioServiceClient::GetSampleSize() const
2132 {
2133     return DEFAULT_SAMPLE_SIZE;
2134 }
2135 
GetAudioStreamParams(AudioStreamParams & audioParams) const2136 int32_t AudioServiceClient::GetAudioStreamParams(AudioStreamParams& audioParams) const
2137 {
2138     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
2139     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
2140 
2141     const pa_sample_spec *paSampleSpec = pa_stream_get_sample_spec(paStream);
2142 
2143     if (!paSampleSpec) {
2144         AUDIO_ERR_LOG("GetAudioStreamParams Failed");
2145         return AUDIO_CLIENT_ERR;
2146     }
2147 
2148     audioParams = ConvertFromPAAudioParams(*paSampleSpec);
2149     audioParams.channelLayout = channelLayout_;
2150     return AUDIO_CLIENT_SUCCESS;
2151 }
2152 
GetOffloadCurrentTimeStamp(uint64_t paTimeStamp,uint64_t paWriteIndex,uint64_t & outTimeStamp)2153 void AudioServiceClient::GetOffloadCurrentTimeStamp(uint64_t paTimeStamp, uint64_t paWriteIndex, uint64_t &outTimeStamp)
2154 {
2155     if (!offloadEnable_ || eAudioClientType != AUDIO_SERVICE_CLIENT_PLAYBACK) {
2156         return;
2157     }
2158 
2159     uint64_t cacheTime = 0;
2160     GetOffloadApproximatelyCacheTime(paTimeStamp, paWriteIndex, cacheTime);
2161     outTimeStamp = paWriteIndex + cacheTime;
2162 }
2163 
GetCurrentTimeStamp(uint64_t & timeStamp)2164 int32_t AudioServiceClient::GetCurrentTimeStamp(uint64_t &timeStamp)
2165 {
2166     if (offloadWaitWriteableMutex_.try_lock_for(chrono::milliseconds(OFFLOAD_HDI_CACHE1))) {
2167         lock_guard<timed_mutex> lockoffload(offloadWaitWriteableMutex_, adopt_lock);
2168     } else if (offloadEnable_ && eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK && offloadTsLast_ != 0) {
2169         GetOffloadCurrentTimeStamp(0, 0, timeStamp);
2170         return AUDIO_CLIENT_SUCCESS;
2171     }
2172     lock_guard<mutex> lock(dataMutex_);
2173     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
2174     CHECK_AND_RETURN_RET(ret >= 0, AUDIO_CLIENT_PA_ERR);
2175     pa_threaded_mainloop_lock(mainLoop);
2176 
2177     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2178         pa_operation *operation = pa_stream_update_timing_info(paStream, NULL, NULL);
2179         if (operation != nullptr) {
2180             while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
2181                 pa_threaded_mainloop_wait(mainLoop);
2182             }
2183             pa_operation_unref(operation);
2184         } else {
2185             AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
2186         }
2187     }
2188 
2189     const pa_timing_info *info = pa_stream_get_timing_info(paStream);
2190     if (info == nullptr) {
2191         AUDIO_ERR_LOG("pa_stream_get_timing_info failed");
2192         pa_threaded_mainloop_unlock(mainLoop);
2193         return AUDIO_CLIENT_ERR;
2194     }
2195 
2196     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2197         timeStamp = pa_bytes_to_usec(info->write_index, &sampleSpec);
2198         uint64_t paTimeStamp = info->timestamp.tv_sec * AUDIO_US_PER_SECOND + info->timestamp.tv_usec;
2199         GetOffloadCurrentTimeStamp(paTimeStamp, timeStamp, timeStamp);
2200     } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
2201         if (pa_stream_get_time(paStream, &timeStamp)) {
2202             AUDIO_ERR_LOG("failed for AUDIO_SERVICE_CLIENT_RECORD");
2203             pa_threaded_mainloop_unlock(mainLoop);
2204             return AUDIO_CLIENT_ERR;
2205         }
2206         int32_t uid = static_cast<int32_t>(getuid());
2207 
2208         // 1013 is media_service's uid
2209         int32_t media_service = 1013;
2210         if (uid == media_service) {
2211             timeStamp = pa_bytes_to_usec(mTotalBytesRead, &sampleSpec);
2212         }
2213     }
2214 
2215     pa_threaded_mainloop_unlock(mainLoop);
2216 
2217     return AUDIO_CLIENT_SUCCESS;
2218 }
2219 
GetOffloadApproximatelyCacheTime(uint64_t paTimeStamp,uint64_t paWriteIndex,uint64_t & cacheTimePaDsp)2220 void AudioServiceClient::GetOffloadApproximatelyCacheTime(uint64_t paTimeStamp, uint64_t paWriteIndex,
2221     uint64_t &cacheTimePaDsp)
2222 {
2223     if (!offloadEnable_ || eAudioClientType != AUDIO_SERVICE_CLIENT_PLAYBACK) {
2224         return;
2225     }
2226 
2227     if (paTimeStamp == 0 && paWriteIndex == 0) {
2228         paTimeStamp = offloadTimeStamp_;
2229         paWriteIndex = offloadWriteIndex_;
2230     }
2231 
2232     bool first = offloadTsLast_ == 0;
2233     offloadTsLast_ = paWriteIndex;
2234 
2235     uint64_t ppTimeStamp = 0;
2236     uint64_t frames = 0;
2237     int64_t timeNowSteady = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
2238         std::chrono::steady_clock::now().time_since_epoch()).count());
2239     bool offloadPwrActive = offloadStatePolicy_ != OFFLOAD_INACTIVE_BACKGROUND;
2240     if (offloadPwrActive ||
2241         timeNowSteady >
2242         static_cast<int64_t>(offloadLastHdiPosTs_ + AUDIO_US_PER_SECOND / 20)) { // 20 times per sec is max
2243         int64_t timeSec;
2244         int64_t timeNanoSec;
2245         int32_t ret = audioSystemManager_->OffloadGetPresentationPosition(frames, timeSec, timeNanoSec);
2246         if (ret) {
2247             return;
2248         }
2249         ppTimeStamp = timeSec * AUDIO_US_PER_SECOND + timeNanoSec / AUDIO_NS_PER_US;
2250         offloadLastHdiPosTs_ = ppTimeStamp;
2251         offloadLastHdiPosFrames_ = frames;
2252     } else {
2253         ppTimeStamp = timeNowSteady;
2254         int64_t timeDelta = static_cast<int64_t>(timeNowSteady) - static_cast<int64_t>(offloadLastHdiPosTs_);
2255         timeDelta = timeDelta > 0 ? timeDelta : 0;
2256         frames = offloadLastHdiPosFrames_ + timeDelta;
2257     }
2258 
2259     int64_t timeDelta = static_cast<int64_t>(paTimeStamp) - static_cast<int64_t>(ppTimeStamp);
2260     int64_t framesInt = static_cast<int64_t>(frames) + timeDelta;
2261     framesInt = framesInt > 0 ? framesInt : 0;
2262     int64_t writeIndexInt = static_cast<int64_t>(paWriteIndex);
2263     if (framesInt + offloadTsOffset_ < writeIndexInt - static_cast<int64_t>(
2264         (OFFLOAD_HDI_CACHE2 + MAX_LENGTH_OFFLOAD + OFFLOAD_BUFFER) * AUDIO_US_PER_MS) ||
2265         framesInt + offloadTsOffset_ > writeIndexInt || first) {
2266         offloadTsOffset_ = writeIndexInt - framesInt;
2267     }
2268     cacheTimePaDsp = static_cast<uint64_t>(writeIndexInt - (framesInt + offloadTsOffset_));
2269 }
2270 
UpdateOffloadStreamPosition(UpdatePositionTimeNode node,uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)2271 int32_t AudioServiceClient::UpdateOffloadStreamPosition(UpdatePositionTimeNode node, uint64_t& frames,
2272     int64_t& timeSec, int64_t& timeNanoSec)
2273 {
2274     if (node == UpdatePositionTimeNode::CORKED_NODE) {
2275         lastOffloadStreamCorkedPosition_ = mTotalBytesWritten / mFrameSize;
2276         return AUDIO_CLIENT_SUCCESS;
2277     }
2278     frames = frames * HDI_OFFLOAD_SAMPLE_RATE / SECOND_TO_MICROSECOND;
2279     lastStreamPosition_ = lastOffloadStreamCorkedPosition_ + frames;
2280     lastPositionTimestamp_ = timeSec * AUDIO_S_TO_NS + timeNanoSec;
2281     return AUDIO_CLIENT_SUCCESS;
2282 }
2283 
UpdateStreamPosition(UpdatePositionTimeNode node)2284 int32_t AudioServiceClient::UpdateStreamPosition(UpdatePositionTimeNode node)
2285 {
2286     uint64_t frames;
2287     int64_t timeSec;
2288     int64_t timeNanoSec;
2289     unique_lock<mutex> positionLock(streamPositionMutex_);
2290     std::string deviceClass = offloadEnable_ ? "offload" : "primary";
2291     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK &&
2292         audioSystemManager_->GetRenderPresentationPosition(deviceClass, frames, timeSec, timeNanoSec) == 0) {
2293         if (offloadEnable_) {
2294             return UpdateOffloadStreamPosition(node, frames, timeSec, timeNanoSec);
2295         }
2296         frames = frames * sampleSpec.rate / HDI_OFFLOAD_SAMPLE_RATE; // revert hdi frame size to client size
2297         if (frames < lastHdiPosition_) {
2298             AUDIO_ERR_LOG("The frame position should be continuously increasing");
2299             return AUDIO_CLIENT_ERR;
2300         }
2301         if (firstUpdatePosition_) {
2302             lastHdiPosition_ = frames;
2303             firstUpdatePosition_ = false;
2304         }
2305         if (node == UpdatePositionTimeNode::USER_NODE && state_ == RUNNING) {
2306             lastStreamPosition_ = lastStreamPosition_ + frames - lastHdiPosition_;
2307             lastPositionTimestamp_ = timeSec * AUDIO_S_TO_NS + timeNanoSec;
2308         } else if (node == UpdatePositionTimeNode::CORKED_NODE) {
2309             // In the current paused state, all data will be flushed
2310             lastStreamPosition_ = mTotalBytesWritten / mFrameSize;
2311         } else {
2312             AUDIO_INFO_LOG("other node value %{public}d!", node);
2313         }
2314         lastHdiPosition_ = frames;
2315         return AUDIO_CLIENT_SUCCESS;
2316     } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD &&
2317         audioSystemManager_->GetCapturePresentationPosition("primary", frames, timeSec, timeNanoSec) == 0) {
2318         lastStreamPosition_ = frames;
2319         lastPositionTimestamp_ = timeSec * AUDIO_S_TO_NS + timeNanoSec;
2320         return AUDIO_CLIENT_SUCCESS;
2321     } else {
2322         AUDIO_ERR_LOG("UpdateStreamPosition from hdi failed!");
2323         return AUDIO_CLIENT_ERR;
2324     }
2325 }
2326 
GetCurrentPosition(uint64_t & framePosition,uint64_t & timeStamp)2327 int32_t AudioServiceClient::GetCurrentPosition(uint64_t &framePosition, uint64_t &timeStamp)
2328 {
2329     // Since the START processing between the framework service and hdf service is asynchronous, the application
2330     // may get the frame information without the hdf service completing the stream initialization.
2331     // This time will get an exception value, here will not return the exception to the application.Return the
2332     // last frame information instead
2333     UpdateStreamPosition(UpdatePositionTimeNode::USER_NODE);
2334     if (lastStreamPosition_ > preFrameNum_) {
2335         framePosition = lastStreamPosition_ - preFrameNum_;
2336     } else {
2337         framePosition = 0;
2338     }
2339     uint64_t latency = 0;
2340     GetAudioLatency(latency);
2341     latency = latency * sampleSpec.rate / SECOND_TO_MICROSECOND;
2342     if (framePosition > latency) {
2343         framePosition -= latency;
2344     } else {
2345         framePosition = 0;
2346     }
2347     timeStamp = lastPositionTimestamp_;
2348     return AUDIO_CLIENT_SUCCESS;
2349 }
2350 
GetAudioLatencyOffload(uint64_t & latency)2351 void AudioServiceClient::GetAudioLatencyOffload(uint64_t &latency)
2352 {
2353     int64_t timeNow = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
2354         std::chrono::system_clock::now().time_since_epoch()).count());
2355     bool offloadPwrActive = offloadStatePolicy_ != OFFLOAD_INACTIVE_BACKGROUND;
2356     if (offloadPwrActive ||
2357         timeNow >
2358         static_cast<int64_t>(offloadLastUpdatePaInfoTs_ + AUDIO_US_PER_SECOND / 20)) { // 20 times per sec is max
2359         pa_threaded_mainloop_lock(mainLoop);
2360         pa_operation *operation = pa_stream_update_timing_info(
2361             paStream, PAStreamUpdateTimingInfoSuccessCb, (void *)this);
2362         if (operation != nullptr) {
2363             pa_operation_unref(operation);
2364         } else {
2365             AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
2366         }
2367         pa_threaded_mainloop_unlock(mainLoop);
2368         offloadLastUpdatePaInfoTs_ = timeNow;
2369     }
2370 
2371     uint64_t paTimeStamp = offloadTimeStamp_;
2372     uint64_t paWriteIndex = offloadWriteIndex_;
2373     uint64_t paReadIndex = offloadReadIndex_;
2374 
2375     uint64_t cacheTime = 0;
2376     GetOffloadApproximatelyCacheTime(paTimeStamp, paWriteIndex, cacheTime);
2377 
2378     pa_usec_t cacheLatency = pa_bytes_to_usec((acache_.totalCacheSize - acache_.writeIndex), &sampleSpec);
2379 
2380     // Total latency will be sum of audio write cache latency + PA latency
2381     uint64_t paLatency = paWriteIndex > paReadIndex ? paWriteIndex - paReadIndex : 0;
2382     uint64_t fwLatency = paLatency + cacheLatency + cacheTime;
2383     uint64_t sinkLatency = sinkLatencyInMsec_ * PA_USEC_PER_MSEC;
2384     latency = fwLatency > sinkLatency ? fwLatency - sinkLatency : fwLatency;
2385     AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}" PRIu64
2386         ", cache latency: %{public}" PRIu64 ", dsp latency: %{public}" PRIu64,
2387         latency, paLatency, cacheLatency, cacheTime);
2388 }
2389 
GetAudioLatency(uint64_t & latency)2390 int32_t AudioServiceClient::GetAudioLatency(uint64_t &latency)
2391 {
2392     if (offloadEnable_ && eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2393         GetAudioLatencyOffload(paLatency_);
2394         return AUDIO_CLIENT_SUCCESS;
2395     }
2396 
2397     lock_guard<mutex> lock(dataMutex_);
2398     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2399         return AUDIO_CLIENT_PA_ERR;
2400     }
2401     pa_usec_t cacheLatency {0};
2402 
2403     // Get PA latency
2404     pa_threaded_mainloop_lock(mainLoop);
2405     pa_operation *operation = pa_stream_update_timing_info(paStream, PAStreamUpdateTimingInfoSuccessCb, (void *)this);
2406     if (operation != nullptr) {
2407         pa_operation_unref(operation);
2408     } else {
2409         AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
2410     }
2411     AUDIO_DEBUG_LOG("waiting for audio latency information");
2412     StartTimer(INIT_TIMEOUT_IN_SEC);
2413     pa_threaded_mainloop_wait(mainLoop);
2414     StopTimer();
2415     if (IsTimeOut()) {
2416         AUDIO_ERR_LOG("Get audio latency timeout");
2417         pa_threaded_mainloop_unlock(mainLoop);
2418         return AUDIO_CLIENT_ERR;
2419     }
2420     pa_threaded_mainloop_unlock(mainLoop);
2421     CHECK_AND_RETURN_RET_LOG(isGetLatencySuccess_ != false, AUDIO_CLIENT_ERR, "Get audio latency failed");
2422 
2423     if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
2424         // Get audio write cache latency
2425         cacheLatency = pa_bytes_to_usec((acache_.totalCacheSize - acache_.writeIndex), &sampleSpec);
2426 
2427         // Total latency will be sum of audio write cache latency + PA latency
2428         uint64_t fwLatency = paLatency_ + cacheLatency;
2429         uint64_t sinkLatency = sinkLatencyInMsec_ * PA_USEC_PER_MSEC;
2430         latency = fwLatency > sinkLatency ? fwLatency - sinkLatency : fwLatency;
2431         AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}"
2432             PRIu64 ", cache latency: %{public}" PRIu64, latency, paLatency_, cacheLatency);
2433     } else if (eAudioClientType == AUDIO_SERVICE_CLIENT_RECORD) {
2434         // Get audio read cache latency
2435         cacheLatency = pa_bytes_to_usec(internalRdBufLen_, &sampleSpec);
2436 
2437         // Total latency will be sum of audio read cache latency + PA latency
2438         latency = paLatency_ + cacheLatency;
2439         AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}" PRIu64, latency, paLatency_);
2440     }
2441 
2442     return AUDIO_CLIENT_SUCCESS;
2443 }
2444 
RegisterAudioRendererCallbacks(const AudioRendererCallbacks & cb)2445 void AudioServiceClient::RegisterAudioRendererCallbacks(const AudioRendererCallbacks &cb)
2446 {
2447     AUDIO_DEBUG_LOG("Registering audio render callbacks");
2448     mAudioRendererCallbacks = (AudioRendererCallbacks *)&cb;
2449 }
2450 
RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks & cb)2451 void AudioServiceClient::RegisterAudioCapturerCallbacks(const AudioCapturerCallbacks &cb)
2452 {
2453     AUDIO_DEBUG_LOG("Registering audio record callbacks");
2454     mAudioCapturerCallbacks = (AudioCapturerCallbacks *)&cb;
2455 }
2456 
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)2457 void AudioServiceClient::SetRendererPositionCallback(int64_t markPosition,
2458     const std::shared_ptr<RendererPositionCallback> &callback)
2459 {
2460     std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
2461     AUDIO_INFO_LOG("Registering render frame position callback mark position: %{public}" PRIu64, markPosition);
2462     mFrameMarkPosition = markPosition;
2463     SendSetRenderMarkReachedRequestEvent(callback);
2464     mMarkReached = false;
2465 }
2466 
UnsetRendererPositionCallback()2467 void AudioServiceClient::UnsetRendererPositionCallback()
2468 {
2469     AUDIO_INFO_LOG("Unregistering render frame position callback");
2470     std::lock_guard<std::mutex> lock(rendererMarkReachedMutex_);
2471     SendUnsetRenderMarkReachedRequestEvent();
2472     mMarkReached = false;
2473     mFrameMarkPosition = 0;
2474 }
2475 
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)2476 int32_t AudioServiceClient::SetRendererFirstFrameWritingCallback(
2477     const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
2478 {
2479     AUDIO_INFO_LOG("SetRendererFirstFrameWritingCallback in.");
2480     CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "callback is nullptr");
2481     firstFrameWritingCb_ = callback;
2482     return SUCCESS;
2483 }
2484 
OnFirstFrameWriting()2485 void AudioServiceClient::OnFirstFrameWriting()
2486 {
2487     UpdateStreamPosition(UpdatePositionTimeNode::START_NODE);
2488     hasFirstFrameWrited_ = true;
2489     CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null.");
2490     uint64_t latency = AUDIO_FIRST_FRAME_LATENCY;
2491     AUDIO_DEBUG_LOG("OnFirstFrameWriting: latency %{public}" PRIu64 "", latency);
2492     firstFrameWritingCb_->OnFirstFrameWriting(latency);
2493 }
2494 
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)2495 void AudioServiceClient::SetRendererPeriodPositionCallback(int64_t periodPosition,
2496     const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2497 {
2498     std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
2499     AUDIO_INFO_LOG("Registering render period position callback");
2500     mFramePeriodNumber = periodPosition;
2501     if ((mFrameSize != 0) && (mFramePeriodNumber != 0)) {
2502         mFramePeriodWritten = (mTotalBytesWritten / mFrameSize) % mFramePeriodNumber;
2503     } else {
2504         AUDIO_ERR_LOG("SetRendererPeriodPositionCallback failed");
2505         return;
2506     }
2507     SendSetRenderPeriodReachedRequestEvent(callback);
2508 }
2509 
UnsetRendererPeriodPositionCallback()2510 void AudioServiceClient::UnsetRendererPeriodPositionCallback()
2511 {
2512     AUDIO_INFO_LOG("Unregistering render period position callback");
2513     std::lock_guard<std::mutex> lock(rendererPeriodReachedMutex_);
2514     SendUnsetRenderPeriodReachedRequestEvent();
2515     mFramePeriodWritten = 0;
2516     mFramePeriodNumber = 0;
2517 }
2518 
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)2519 void AudioServiceClient::SetCapturerPositionCallback(int64_t markPosition,
2520     const std::shared_ptr<CapturerPositionCallback> &callback)
2521 {
2522     std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
2523     AUDIO_INFO_LOG("Registering capture frame position callback, mark position: %{public}" PRIu64, markPosition);
2524     mFrameMarkPosition = markPosition;
2525     SendSetCapturerMarkReachedRequestEvent(callback);
2526     mMarkReached = false;
2527 }
2528 
UnsetCapturerPositionCallback()2529 void AudioServiceClient::UnsetCapturerPositionCallback()
2530 {
2531     AUDIO_INFO_LOG("Unregistering capture frame position callback");
2532     std::lock_guard<std::mutex> lock(capturerMarkReachedMutex_);
2533     SendUnsetCapturerMarkReachedRequestEvent();
2534     mMarkReached = false;
2535     mFrameMarkPosition = 0;
2536 }
2537 
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2538 void AudioServiceClient::SetCapturerPeriodPositionCallback(int64_t periodPosition,
2539     const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2540 {
2541     std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
2542     AUDIO_INFO_LOG("Registering period position callback");
2543     mFramePeriodNumber = periodPosition;
2544     if ((mFrameSize != 0) && (mFramePeriodNumber != 0)) {
2545         mFramePeriodRead = (mTotalBytesRead / mFrameSize) % mFramePeriodNumber;
2546     } else {
2547         AUDIO_ERR_LOG("SetCapturerPeriodPositionCallback failed");
2548         return;
2549     }
2550     SendSetCapturerPeriodReachedRequestEvent(callback);
2551 }
2552 
UnsetCapturerPeriodPositionCallback()2553 void AudioServiceClient::UnsetCapturerPeriodPositionCallback()
2554 {
2555     AUDIO_INFO_LOG("Unregistering period position callback");
2556     std::lock_guard<std::mutex> lock(capturerPeriodReachedMutex_);
2557     SendUnsetCapturerPeriodReachedRequestEvent();
2558     mFramePeriodRead = 0;
2559     mFramePeriodNumber = 0;
2560 }
2561 
SetStreamType(AudioStreamType audioStreamType)2562 int32_t AudioServiceClient::SetStreamType(AudioStreamType audioStreamType)
2563 {
2564     AUDIO_INFO_LOG("SetStreamType: %{public}d", audioStreamType);
2565 
2566     CHECK_AND_RETURN_RET_LOG(context != nullptr, AUDIO_CLIENT_ERR,
2567         "context is null");
2568 
2569     pa_threaded_mainloop_lock(mainLoop);
2570 
2571     streamType_ = audioStreamType;
2572     const std::string streamName = GetStreamName(audioStreamType);
2573     effectSceneName = IAudioStream::GetEffectSceneName(audioStreamType);
2574 
2575     pa_proplist *propList = pa_proplist_new();
2576     if (propList == nullptr) {
2577         AUDIO_ERR_LOG("pa_proplist_new failed");
2578         pa_threaded_mainloop_unlock(mainLoop);
2579         return AUDIO_CLIENT_ERR;
2580     }
2581 
2582     pa_proplist_sets(propList, "stream.type", streamName.c_str());
2583     pa_proplist_sets(propList, "media.name", streamName.c_str());
2584     pa_proplist_sets(propList, "scene.type", effectSceneName.c_str());
2585     pa_proplist_sets(propList, "stream.flush", "false");
2586     pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2587         nullptr, nullptr);
2588     pa_proplist_free(propList);
2589     pa_operation_unref(updatePropOperation);
2590 
2591     pa_threaded_mainloop_unlock(mainLoop);
2592 
2593     return AUDIO_CLIENT_SUCCESS;
2594 }
2595 
SetStreamVolume(float volume)2596 int32_t AudioServiceClient::SetStreamVolume(float volume)
2597 {
2598     Trace trace("AudioServiceClient::SetStreamVolume " +std::to_string(volume));
2599     lock_guard<mutex> lock(ctrlMutex_);
2600     AUDIO_INFO_LOG("SetVolume volume: %{public}f", volume);
2601 
2602     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
2603     CHECK_AND_RETURN_RET_LOG(res >= 0, AUDIO_CLIENT_PA_ERR, "set stream volume: invalid stream state");
2604 
2605     /* Validate and return INVALID_PARAMS error */
2606     CHECK_AND_RETURN_RET_LOG((volume >= MIN_STREAM_VOLUME_LEVEL) && (volume <= MAX_STREAM_VOLUME_LEVEL),
2607         AUDIO_CLIENT_INVALID_PARAMS_ERR, "Invalid Volume Input!");
2608 
2609     pa_threaded_mainloop_lock(mainLoop);
2610     int32_t ret = SetStreamVolumeInML(volume);
2611     pa_threaded_mainloop_unlock(mainLoop);
2612 
2613     if (offloadEnable_) {
2614         audioSystemManager_->OffloadSetVolume(GetSingleStreamVol() * duckVolumeFactor_);
2615     }
2616 
2617     return ret;
2618 }
2619 
SetStreamVolumeInML(float volume)2620 int32_t AudioServiceClient::SetStreamVolumeInML(float volume)
2621 {
2622     volumeFactor_ = volume;
2623     pa_proplist *propList = pa_proplist_new();
2624     if (propList == nullptr) {
2625         AUDIO_ERR_LOG("pa_proplist_new failed");
2626         return AUDIO_CLIENT_ERR;
2627     }
2628 
2629     pa_proplist_sets(propList, "stream.volumeFactor", std::to_string(volumeFactor_).c_str());
2630     pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
2631         nullptr, nullptr);
2632     if (updatePropOperation == nullptr) {
2633         AUDIO_ERR_LOG("pa_stream_proplist_update returned null");
2634         pa_proplist_free(propList);
2635         return AUDIO_CLIENT_ERR;
2636     }
2637 
2638     pa_proplist_free(propList);
2639     pa_operation_unref(updatePropOperation);
2640 
2641     if (audioSystemManager_ == nullptr) {
2642         AUDIO_ERR_LOG("System manager instance is null");
2643         return AUDIO_CLIENT_ERR;
2644     }
2645 
2646     if (!streamInfoUpdated_) {
2647         uint32_t idx = pa_stream_get_index(paStream);
2648         pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
2649             reinterpret_cast<void *>(this));
2650         if (operation == nullptr) {
2651             AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
2652             return AUDIO_CLIENT_ERR;
2653         }
2654 
2655         while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
2656             pa_threaded_mainloop_wait(mainLoop);
2657         }
2658 
2659         pa_operation_unref(operation);
2660     } else {
2661         SetPaVolume(*this);
2662     }
2663 
2664     return AUDIO_CLIENT_SUCCESS;
2665 }
2666 
GetStreamVolume()2667 float AudioServiceClient::GetStreamVolume()
2668 {
2669     return volumeFactor_;
2670 }
2671 
InitializePAProbListOffload()2672 int32_t AudioServiceClient::InitializePAProbListOffload()
2673 {
2674     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2675         AUDIO_ERR_LOG("set offload mode: invalid stream state");
2676         return AUDIO_CLIENT_PA_ERR;
2677     }
2678 
2679     pa_proplist *propList = pa_proplist_new();
2680     if (propList == nullptr) {
2681         pa_threaded_mainloop_unlock(mainLoop);
2682         return AUDIO_CLIENT_ERR;
2683     }
2684 
2685     pa_proplist_sets(propList, "stream.offload.statePolicy", "0");
2686 
2687     pa_operation *updatePropOperation =
2688         pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList, nullptr, nullptr);
2689     if (updatePropOperation == nullptr) {
2690         pa_proplist_free(propList);
2691         pa_threaded_mainloop_unlock(mainLoop);
2692         return AUDIO_CLIENT_ERR;
2693     }
2694 
2695     pa_proplist_free(propList);
2696     pa_operation_unref(updatePropOperation);
2697     return AUDIO_CLIENT_SUCCESS;
2698 }
2699 
UpdatePAProbListOffload(AudioOffloadType statePolicy)2700 int32_t AudioServiceClient::UpdatePAProbListOffload(AudioOffloadType statePolicy)
2701 {
2702     if (CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR) < 0) {
2703         AUDIO_ERR_LOG("Set offload mode: invalid stream state, quit SetStreamOffloadMode due err");
2704         return AUDIO_CLIENT_PA_ERR;
2705     }
2706 
2707     // if possible turn on the buffer immediately(long buffer -> short buffer), turn it at once.
2708     if ((statePolicy < offloadStatePolicy_) || (offloadStatePolicy_ == OFFLOAD_DEFAULT)) {
2709         AUDIO_DEBUG_LOG("Update statePolicy immediately: %{public}d -> %{public}d", offloadStatePolicy_, statePolicy);
2710         lastOffloadUpdateFinishTime_ = 0;
2711         pa_threaded_mainloop_lock(mainLoop);
2712         int32_t ret = UpdatePolicyOffload(statePolicy);
2713         pa_threaded_mainloop_unlock(mainLoop);
2714         offloadNextStateTargetPolicy_ = statePolicy; // Fix here if sometimes can't cut into state 3
2715         return ret;
2716     } else {
2717         // Otherwise, hdi_sink.c's times detects the stateTarget change and switches later
2718         // this time is checked the PaWriteStream to check if the switch has been made
2719         AUDIO_DEBUG_LOG("Update statePolicy in 3 seconds: %{public}d -> %{public}d", offloadStatePolicy_, statePolicy);
2720         lastOffloadUpdateFinishTime_ = chrono::system_clock::to_time_t(
2721             chrono::system_clock::now() + std::chrono::seconds(3)); // add 3s latency to change offload state
2722         offloadNextStateTargetPolicy_ = statePolicy;
2723     }
2724 
2725     return AUDIO_CLIENT_SUCCESS;
2726 }
2727 
UpdatePolicyOffload(AudioOffloadType statePolicy)2728 int32_t AudioServiceClient::UpdatePolicyOffload(AudioOffloadType statePolicy)
2729 {
2730     pa_proplist *propList = pa_proplist_new();
2731     CHECK_AND_RETURN_RET_LOG(propList != nullptr, AUDIO_CLIENT_ERR,
2732         "pa_proplist_new failed");
2733     if (offloadEnable_) {
2734         pa_proplist_sets(propList, "stream.offload.enable", "1");
2735     } else {
2736         pa_proplist_sets(propList, "stream.offload.enable", "0");
2737     }
2738     pa_proplist_sets(propList, "stream.offload.statePolicy", std::to_string(statePolicy).c_str());
2739 
2740     pa_operation *updatePropOperation =
2741         pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList, nullptr, nullptr);
2742     if (updatePropOperation == nullptr) {
2743         AUDIO_ERR_LOG("pa_stream_proplist_update failed!");
2744         pa_proplist_free(propList);
2745         return AUDIO_CLIENT_ERR;
2746     }
2747     pa_proplist_free(propList);
2748     pa_operation_unref(updatePropOperation);
2749 
2750     const uint32_t bufLenMs = statePolicy > 1 ? OFFLOAD_HDI_CACHE2 : OFFLOAD_HDI_CACHE1;
2751     audioSystemManager_->OffloadSetBufferSize(bufLenMs);
2752 
2753     offloadStatePolicy_ = statePolicy;
2754 
2755     return AUDIO_CLIENT_SUCCESS;
2756 }
2757 
ResetOffload()2758 void AudioServiceClient::ResetOffload()
2759 {
2760     offloadEnable_ = false;
2761     offloadTsOffset_ = 0;
2762     offloadTsLast_ = 0;
2763     offloadStatePolicy_ = OFFLOAD_DEFAULT;
2764     offloadNextStateTargetPolicy_ = OFFLOAD_DEFAULT;
2765     lastOffloadUpdateFinishTime_ = 0;
2766     acache_.totalCacheSizeTgt = 0;
2767     if (paStream != nullptr) {
2768         const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream);
2769         if (bufferAttr != nullptr) {
2770             acache_.totalCacheSizeTgt = bufferAttr->minreq;
2771         }
2772     }
2773 }
2774 
SetStreamOffloadMode(int32_t state,bool isAppBack)2775 int32_t AudioServiceClient::SetStreamOffloadMode(int32_t state, bool isAppBack)
2776 {
2777 #ifdef FEATURE_POWER_MANAGER
2778     AudioOffloadType statePolicy = OFFLOAD_DEFAULT;
2779     auto powerState = static_cast<PowerMgr::PowerState>(state);
2780     if ((powerState != PowerMgr::PowerState::AWAKE) && (powerState != PowerMgr::PowerState::FREEZE)) {
2781         statePolicy = OFFLOAD_INACTIVE_BACKGROUND;
2782     } else if (isAppBack) {
2783         statePolicy = OFFLOAD_ACTIVE_FOREGROUND;
2784     } else if (!isAppBack) {
2785         statePolicy = OFFLOAD_ACTIVE_FOREGROUND;
2786     }
2787 
2788     if (statePolicy == OFFLOAD_DEFAULT) {
2789         AUDIO_ERR_LOG("impossible INPUT branch error");
2790         return AUDIO_CLIENT_ERR;
2791     }
2792 
2793     AUDIO_INFO_LOG("calling set stream offloadMode PowerState: %{public}d, isAppBack: %{public}d", state, isAppBack);
2794 
2795     if (offloadNextStateTargetPolicy_ == statePolicy) {
2796         return AUDIO_CLIENT_SUCCESS;
2797     }
2798 
2799     if ((offloadStatePolicy_ == offloadNextStateTargetPolicy_) && (offloadStatePolicy_ == statePolicy)) {
2800         return AUDIO_CLIENT_SUCCESS;
2801     }
2802 
2803     lock_guard<mutex> lock(ctrlMutex_);
2804 
2805     offloadEnable_ = true;
2806     if (UpdatePAProbListOffload(statePolicy) != AUDIO_CLIENT_SUCCESS) {
2807         return AUDIO_CLIENT_ERR;
2808     }
2809     if (statePolicy == OFFLOAD_ACTIVE_FOREGROUND) {
2810         pa_threaded_mainloop_signal(mainLoop, 0);
2811     }
2812 #else
2813     AUDIO_INFO_LOG("SetStreamOffloadMode not available, FEATURE_POWER_MANAGER no define");
2814 #endif
2815     return AUDIO_CLIENT_SUCCESS;
2816 }
2817 
UnsetStreamOffloadMode()2818 int32_t AudioServiceClient::UnsetStreamOffloadMode()
2819 {
2820     lastOffloadUpdateFinishTime_ = 0;
2821     offloadEnable_ = false;
2822     pa_threaded_mainloop_lock(mainLoop);
2823     int32_t ret = UpdatePolicyOffload(OFFLOAD_ACTIVE_FOREGROUND);
2824     pa_threaded_mainloop_unlock(mainLoop);
2825     offloadNextStateTargetPolicy_ = OFFLOAD_DEFAULT;
2826     offloadStatePolicy_ = OFFLOAD_DEFAULT;
2827     return ret;
2828 }
2829 
GetSinkInputInfoCb(pa_context * context,const pa_sink_input_info * info,int eol,void * userdata)2830 void AudioServiceClient::GetSinkInputInfoCb(pa_context *context, const pa_sink_input_info *info, int eol,
2831     void *userdata)
2832 {
2833     AUDIO_INFO_LOG("GetSinkInputInfoVolumeCb in");
2834     AudioServiceClient *thiz = reinterpret_cast<AudioServiceClient *>(userdata);
2835 
2836     CHECK_AND_RETURN_LOG(eol >= 0, "Failed to get sink input information: %{public}s",
2837         pa_strerror(pa_context_errno(context)));
2838 
2839     if (eol) {
2840         pa_threaded_mainloop_signal(thiz->mainLoop, 0);
2841         return;
2842     }
2843 
2844     CHECK_AND_RETURN_LOG(info->proplist != nullptr, "Invalid prop list for sink input (%{public}d).", info->index);
2845 
2846     uint32_t sessionID = 0;
2847     const char *sessionCStr = pa_proplist_gets(info->proplist, "stream.sessionID");
2848     if (sessionCStr != nullptr) {
2849         std::stringstream sessionStr;
2850         sessionStr << sessionCStr;
2851         sessionStr >> sessionID;
2852     }
2853 
2854     thiz->cvolume = info->volume;
2855     thiz->streamIndex_ = info->index;
2856     thiz->sessionID_ = sessionID;
2857     thiz->volumeChannels_ = info->channel_map.channels;
2858     thiz->streamInfoUpdated_ = true;
2859 
2860     SetPaVolume(*thiz);
2861 
2862     return;
2863 }
2864 
SetPaVolume(const AudioServiceClient & client)2865 void AudioServiceClient::SetPaVolume(const AudioServiceClient &client)
2866 {
2867     pa_cvolume cv = client.cvolume;
2868     AudioVolumeType volumeType = GetVolumeTypeFromStreamType(client.streamType_);
2869     int32_t systemVolumeLevel = AudioSystemManager::GetInstance()->GetVolume(volumeType);
2870     DeviceType deviceType = AudioSystemManager::GetInstance()->GetActiveOutputDevice();
2871     bool isAbsVolumeScene = AudioPolicyManager::GetInstance().IsAbsVolumeScene();
2872     float systemVolumeDb = AudioPolicyManager::GetInstance().GetSystemVolumeInDb(volumeType,
2873         systemVolumeLevel, deviceType);
2874     if (isAbsVolumeScene && (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP || deviceType == DEVICE_TYPE_BLUETOOTH_SCO)) {
2875         systemVolumeDb = 1.0f; // Transfer raw pcm data to bluetooth device
2876     }
2877     float vol = systemVolumeDb * client.volumeFactor_ * client.powerVolumeFactor_ * client.duckVolumeFactor_;
2878 
2879     uint32_t volume = pa_sw_volume_from_linear(vol);
2880     pa_cvolume_set(&cv, client.volumeChannels_, volume);
2881     pa_operation_unref(pa_context_set_sink_input_volume(client.context, client.streamIndex_, &cv, nullptr, nullptr));
2882 
2883     AUDIO_INFO_LOG("Applied volume %{public}f, systemVolume %{public}f, volumeFactor %{public}f", vol, systemVolumeDb,
2884         client.volumeFactor_);
2885     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO,
2886         "VOLUME_CHANGE", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
2887         "ISOUTPUT", 1,
2888         "STREAMID", client.sessionID_,
2889         "APP_UID", client.clientUid_,
2890         "APP_PID", client.clientPid_,
2891         "STREAMTYPE", client.streamType_,
2892         "VOLUME", vol,
2893         "SYSVOLUME", systemVolumeLevel,
2894         "VOLUMEFACTOR", client.volumeFactor_,
2895         "POWERVOLUMEFACTOR", client.powerVolumeFactor_);
2896 }
2897 
GetVolumeTypeFromStreamType(AudioStreamType streamType)2898 AudioVolumeType AudioServiceClient::GetVolumeTypeFromStreamType(AudioStreamType streamType)
2899 {
2900     switch (streamType) {
2901         case STREAM_VOICE_CALL:
2902         case STREAM_VOICE_MESSAGE:
2903             return STREAM_VOICE_CALL;
2904         case STREAM_RING:
2905         case STREAM_SYSTEM:
2906         case STREAM_NOTIFICATION:
2907         case STREAM_SYSTEM_ENFORCED:
2908         case STREAM_DTMF:
2909             return STREAM_RING;
2910         case STREAM_MUSIC:
2911         case STREAM_MEDIA:
2912         case STREAM_MOVIE:
2913         case STREAM_GAME:
2914         case STREAM_SPEECH:
2915         case STREAM_NAVIGATION:
2916             return STREAM_MUSIC;
2917         case STREAM_VOICE_ASSISTANT:
2918             return STREAM_VOICE_ASSISTANT;
2919         case STREAM_ALARM:
2920             return STREAM_ALARM;
2921         case STREAM_ACCESSIBILITY:
2922             return STREAM_ACCESSIBILITY;
2923         case STREAM_ULTRASONIC:
2924             return STREAM_ULTRASONIC;
2925         default:
2926             AUDIO_ERR_LOG("GetVolumeTypeFromStreamType streamType = %{public}d not supported", streamType);
2927             return streamType;
2928     }
2929 }
2930 
SetStreamRenderRate(AudioRendererRate audioRendererRate)2931 int32_t AudioServiceClient::SetStreamRenderRate(AudioRendererRate audioRendererRate)
2932 {
2933     AUDIO_INFO_LOG("SetStreamRenderRate in");
2934     CHECK_AND_RETURN_RET(paStream, AUDIO_CLIENT_SUCCESS);
2935 
2936     uint32_t rate = sampleSpec.rate;
2937     switch (audioRendererRate) {
2938         case RENDER_RATE_NORMAL:
2939             break;
2940         case RENDER_RATE_DOUBLE:
2941             rate *= DOUBLE_VALUE;
2942             break;
2943         case RENDER_RATE_HALF:
2944             rate /= DOUBLE_VALUE;
2945             break;
2946         default:
2947             return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2948     }
2949     renderRate = audioRendererRate;
2950 
2951     pa_threaded_mainloop_lock(mainLoop);
2952     pa_operation *operation = pa_stream_update_sample_rate(paStream, rate, nullptr, nullptr);
2953     if (operation != nullptr) {
2954         pa_operation_unref(operation);
2955     } else {
2956         AUDIO_WARNING_LOG("SetStreamRenderRate: operation is nullptr");
2957     }
2958     pa_threaded_mainloop_unlock(mainLoop);
2959 
2960     return AUDIO_CLIENT_SUCCESS;
2961 }
2962 
SetRendererSamplingRate(uint32_t sampleRate)2963 int32_t AudioServiceClient::SetRendererSamplingRate(uint32_t sampleRate)
2964 {
2965     AUDIO_INFO_LOG("SetStreamRendererSamplingRate %{public}d", sampleRate);
2966     CHECK_AND_RETURN_RET(paStream, AUDIO_CLIENT_SUCCESS);
2967 
2968     if (sampleRate <= 0) {
2969         return AUDIO_CLIENT_INVALID_PARAMS_ERR;
2970     }
2971     rendererSampleRate = sampleRate;
2972 
2973     pa_threaded_mainloop_lock(mainLoop);
2974     pa_operation *operation = pa_stream_update_sample_rate(paStream, sampleRate, nullptr, nullptr);
2975     pa_operation_unref(operation);
2976     pa_threaded_mainloop_unlock(mainLoop);
2977 
2978     return AUDIO_CLIENT_SUCCESS;
2979 }
2980 
GetRendererSamplingRate()2981 uint32_t AudioServiceClient::GetRendererSamplingRate()
2982 {
2983     if (rendererSampleRate == 0) {
2984         return sampleSpec.rate;
2985     }
2986     return rendererSampleRate;
2987 }
2988 
GetStreamRenderRate()2989 AudioRendererRate AudioServiceClient::GetStreamRenderRate()
2990 {
2991     return renderRate;
2992 }
2993 
SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> & callback)2994 void AudioServiceClient::SaveStreamCallback(const std::weak_ptr<AudioStreamCallback> &callback)
2995 {
2996     streamCallback_ = callback;
2997 
2998     if (state_ != PREPARED) {
2999         return;
3000     }
3001 
3002     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
3003     if (streamCb != nullptr) {
3004         streamCb->OnStateChange(PREPARED);
3005     }
3006 }
3007 
SetStreamLowPowerVolume(float powerVolumeFactor)3008 int32_t AudioServiceClient::SetStreamLowPowerVolume(float powerVolumeFactor)
3009 {
3010     lock_guard<mutex> lock(ctrlMutex_);
3011     AUDIO_INFO_LOG("SetPowerVolumeFactor volume: %{public}f", powerVolumeFactor);
3012 
3013     CHECK_AND_RETURN_RET_LOG(context != nullptr, AUDIO_CLIENT_ERR, "context is null");
3014 
3015     /* Validate and return INVALID_PARAMS error */
3016     CHECK_AND_RETURN_RET_LOG((powerVolumeFactor >= MIN_STREAM_VOLUME_LEVEL) &&
3017         (powerVolumeFactor <= MAX_STREAM_VOLUME_LEVEL),
3018         AUDIO_CLIENT_INVALID_PARAMS_ERR, "Invalid Power Volume Set!");
3019 
3020     pa_threaded_mainloop_lock(mainLoop);
3021 
3022     powerVolumeFactor_ = powerVolumeFactor;
3023     pa_proplist *propList = pa_proplist_new();
3024     if (propList == nullptr) {
3025         AUDIO_ERR_LOG("pa_proplist_new failed");
3026         pa_threaded_mainloop_unlock(mainLoop);
3027         return AUDIO_CLIENT_ERR;
3028     }
3029 
3030     pa_proplist_sets(propList, "stream.powerVolumeFactor", std::to_string(powerVolumeFactor_).c_str());
3031     pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
3032         nullptr, nullptr);
3033     pa_proplist_free(propList);
3034     pa_operation_unref(updatePropOperation);
3035 
3036     if (audioSystemManager_ == nullptr) {
3037         AUDIO_ERR_LOG("System manager instance is null");
3038         pa_threaded_mainloop_unlock(mainLoop);
3039         return AUDIO_CLIENT_ERR;
3040     }
3041 
3042     if (!streamInfoUpdated_) {
3043         uint32_t idx = pa_stream_get_index(paStream);
3044         pa_operation *operation = pa_context_get_sink_input_info(context, idx, AudioServiceClient::GetSinkInputInfoCb,
3045             reinterpret_cast<void *>(this));
3046         if (operation == nullptr) {
3047             AUDIO_ERR_LOG("pa_context_get_sink_input_info_list returned null");
3048             pa_threaded_mainloop_unlock(mainLoop);
3049             return AUDIO_CLIENT_ERR;
3050         }
3051 
3052         while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
3053             pa_threaded_mainloop_wait(mainLoop);
3054         }
3055 
3056         pa_operation_unref(operation);
3057     } else {
3058         SetPaVolume(*this);
3059     }
3060 
3061     pa_threaded_mainloop_unlock(mainLoop);
3062 
3063     return AUDIO_CLIENT_SUCCESS;
3064 }
3065 
GetStreamLowPowerVolume()3066 float AudioServiceClient::GetStreamLowPowerVolume()
3067 {
3068     return powerVolumeFactor_;
3069 }
3070 
GetSingleStreamVol()3071 float AudioServiceClient::GetSingleStreamVol()
3072 {
3073     int32_t systemVolumeLevel = audioSystemManager_->GetVolume(static_cast<AudioVolumeType>(streamType_));
3074     DeviceType deviceType = audioSystemManager_->GetActiveOutputDevice();
3075     float systemVolumeDb = AudioPolicyManager::GetInstance().GetSystemVolumeInDb(streamType_,
3076         systemVolumeLevel, deviceType);
3077     return systemVolumeDb * volumeFactor_ * powerVolumeFactor_;
3078 }
3079 
3080 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)3081 void AudioServiceClient::SendRenderMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
3082 {
3083     lock_guard<mutex> runnerlock(runnerMutex_);
3084     if (runnerReleased_) {
3085         AUDIO_WARNING_LOG("SendRenderMarkReachedRequestEvent runner released");
3086         return;
3087     }
3088     SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_MARK_REACHED_REQUEST, mFrameMarkPosition));
3089 }
3090 
HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)3091 void AudioServiceClient::HandleRenderMarkReachedEvent(uint64_t mFrameMarkPosition)
3092 {
3093     if (mRenderPositionCb) {
3094         mRenderPositionCb->OnMarkReached(mFrameMarkPosition);
3095     }
3096 }
3097 
3098 // SetRenderMarkReached by eventHandler
SendSetRenderMarkReachedRequestEvent(const std::shared_ptr<RendererPositionCallback> & callback)3099 void AudioServiceClient::SendSetRenderMarkReachedRequestEvent(
3100     const std::shared_ptr<RendererPositionCallback> &callback)
3101 {
3102     lock_guard<mutex> runnerlock(runnerMutex_);
3103     if (runnerReleased_) {
3104         AUDIO_WARNING_LOG("SendSetRenderMarkReachedRequestEvent runner released");
3105         return;
3106     }
3107     SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_MARK_REACHED_REQUEST, callback));
3108 }
3109 
HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> & callback)3110 void AudioServiceClient::HandleSetRenderMarkReachedEvent(const std::shared_ptr<RendererPositionCallback> &callback)
3111 {
3112     mRenderPositionCb = callback;
3113 }
3114 
3115 // UnsetRenderMarkReach by eventHandler
SendUnsetRenderMarkReachedRequestEvent()3116 void AudioServiceClient::SendUnsetRenderMarkReachedRequestEvent()
3117 {
3118     lock_guard<mutex> runnerlock(runnerMutex_);
3119     if (runnerReleased_) {
3120         AUDIO_WARNING_LOG("SendUnsetRenderMarkReachedRequestEvent runner released");
3121         return;
3122     }
3123     SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_MARK_REACHED_REQUEST));
3124 }
3125 
HandleUnsetRenderMarkReachedEvent()3126 void AudioServiceClient::HandleUnsetRenderMarkReachedEvent()
3127 {
3128     mRenderPositionCb = nullptr;
3129 }
3130 
3131 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)3132 void AudioServiceClient::SendRenderPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
3133 {
3134     lock_guard<mutex> runnerlock(runnerMutex_);
3135     if (runnerReleased_) {
3136         AUDIO_WARNING_LOG("SendRenderPeriodReachedRequestEvent runner released");
3137         return;
3138     }
3139     SendEvent(AppExecFwk::InnerEvent::Get(RENDERER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
3140 }
3141 
HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)3142 void AudioServiceClient::HandleRenderPeriodReachedEvent(uint64_t mFramePeriodNumber)
3143 {
3144     if (mRenderPeriodPositionCb) {
3145         mRenderPeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
3146     }
3147 }
3148 
3149 // SetRenderPeriodReach by eventHandler
SendSetRenderPeriodReachedRequestEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)3150 void AudioServiceClient::SendSetRenderPeriodReachedRequestEvent(
3151     const std::shared_ptr<RendererPeriodPositionCallback> &callback)
3152 {
3153     lock_guard<mutex> runnerlock(runnerMutex_);
3154     if (runnerReleased_) {
3155         AUDIO_WARNING_LOG("SendSetRenderPeriodReachedRequestEvent runner released");
3156         return;
3157     }
3158     SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_RENDERER_PERIOD_REACHED_REQUEST, callback));
3159 }
3160 
HandleSetRenderPeriodReachedEvent(const std::shared_ptr<RendererPeriodPositionCallback> & callback)3161 void AudioServiceClient::HandleSetRenderPeriodReachedEvent(
3162     const std::shared_ptr<RendererPeriodPositionCallback> &callback)
3163 {
3164     if (callback) {
3165         mRenderPeriodPositionCb = callback;
3166     }
3167 }
3168 
3169 // UnsetRenderPeriodReach by eventHandler
SendUnsetRenderPeriodReachedRequestEvent()3170 void AudioServiceClient::SendUnsetRenderPeriodReachedRequestEvent()
3171 {
3172     lock_guard<mutex> runnerlock(runnerMutex_);
3173     if (runnerReleased_) {
3174         AUDIO_WARNING_LOG("SendUnsetRenderPeriodReachedRequestEvent runner released");
3175         return;
3176     }
3177     SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_RENDERER_PERIOD_REACHED_REQUEST));
3178 }
3179 
HandleUnsetRenderPeriodReachedEvent()3180 void AudioServiceClient::HandleUnsetRenderPeriodReachedEvent()
3181 {
3182     mRenderPeriodPositionCb = nullptr;
3183 }
3184 
3185 // OnCapturerMarkReach by eventHandler
SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)3186 void AudioServiceClient::SendCapturerMarkReachedRequestEvent(uint64_t mFrameMarkPosition)
3187 {
3188     lock_guard<mutex> runnerlock(runnerMutex_);
3189     if (runnerReleased_) {
3190         AUDIO_WARNING_LOG("SendCapturerMarkReachedRequestEvent runner released");
3191         return;
3192     }
3193     SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_MARK_REACHED_REQUEST, mFrameMarkPosition));
3194 }
3195 
HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)3196 void AudioServiceClient::HandleCapturerMarkReachedEvent(uint64_t mFrameMarkPosition)
3197 {
3198     if (mCapturePositionCb) {
3199         mCapturePositionCb->OnMarkReached(mFrameMarkPosition);
3200     }
3201 }
3202 
3203 // SetCapturerMarkReach by eventHandler
SendSetCapturerMarkReachedRequestEvent(const std::shared_ptr<CapturerPositionCallback> & callback)3204 void AudioServiceClient::SendSetCapturerMarkReachedRequestEvent(
3205     const std::shared_ptr<CapturerPositionCallback> &callback)
3206 {
3207     lock_guard<mutex> runnerlock(runnerMutex_);
3208     if (runnerReleased_) {
3209         AUDIO_WARNING_LOG("SendSetCapturerMarkReachedRequestEvent runner released");
3210         return;
3211     }
3212     SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_MARK_REACHED_REQUEST, callback));
3213 }
3214 
HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> & callback)3215 void AudioServiceClient::HandleSetCapturerMarkReachedEvent(const std::shared_ptr<CapturerPositionCallback> &callback)
3216 {
3217     mCapturePositionCb = callback;
3218 }
3219 
3220 // UnsetCapturerMarkReach by eventHandler
SendUnsetCapturerMarkReachedRequestEvent()3221 void AudioServiceClient::SendUnsetCapturerMarkReachedRequestEvent()
3222 {
3223     lock_guard<mutex> runnerlock(runnerMutex_);
3224     if (runnerReleased_) {
3225         AUDIO_WARNING_LOG("runner released");
3226         return;
3227     }
3228     SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_MARK_REACHED_REQUEST));
3229 }
3230 
HandleUnsetCapturerMarkReachedEvent()3231 void AudioServiceClient::HandleUnsetCapturerMarkReachedEvent()
3232 {
3233     mCapturePositionCb = nullptr;
3234 }
3235 
3236 // OnCapturerPeriodReach by eventHandler
SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)3237 void AudioServiceClient::SendCapturerPeriodReachedRequestEvent(uint64_t mFramePeriodNumber)
3238 {
3239     lock_guard<mutex> runnerlock(runnerMutex_);
3240     if (runnerReleased_) {
3241         AUDIO_WARNING_LOG("runner released");
3242         return;
3243     }
3244     SendEvent(AppExecFwk::InnerEvent::Get(CAPTURER_PERIOD_REACHED_REQUEST, mFramePeriodNumber));
3245 }
3246 
HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)3247 void AudioServiceClient::HandleCapturerPeriodReachedEvent(uint64_t mFramePeriodNumber)
3248 {
3249     if (mCapturePeriodPositionCb) {
3250         mCapturePeriodPositionCb->OnPeriodReached(mFramePeriodNumber);
3251     }
3252 }
3253 
3254 // SetCapturerPeriodReach by eventHandler
SendSetCapturerPeriodReachedRequestEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)3255 void AudioServiceClient::SendSetCapturerPeriodReachedRequestEvent(
3256     const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
3257 {
3258     lock_guard<mutex> runnerlock(runnerMutex_);
3259     if (runnerReleased_) {
3260         AUDIO_WARNING_LOG("runner released");
3261         return;
3262     }
3263     SendSyncEvent(AppExecFwk::InnerEvent::Get(SET_CAPTURER_PERIOD_REACHED_REQUEST, callback));
3264 }
3265 
HandleSetCapturerPeriodReachedEvent(const std::shared_ptr<CapturerPeriodPositionCallback> & callback)3266 void AudioServiceClient::HandleSetCapturerPeriodReachedEvent(
3267     const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
3268 {
3269     mCapturePeriodPositionCb = callback;
3270 }
3271 
3272 // UnsetCapturerPeriodReach by eventHandler
SendUnsetCapturerPeriodReachedRequestEvent()3273 void AudioServiceClient::SendUnsetCapturerPeriodReachedRequestEvent()
3274 {
3275     lock_guard<mutex> runnerlock(runnerMutex_);
3276     if (runnerReleased_) {
3277         AUDIO_WARNING_LOG("runner released");
3278         return;
3279     }
3280     SendSyncEvent(AppExecFwk::InnerEvent::Get(UNSET_CAPTURER_PERIOD_REACHED_REQUEST));
3281 }
3282 
HandleUnsetCapturerPeriodReachedEvent()3283 void AudioServiceClient::HandleUnsetCapturerPeriodReachedEvent()
3284 {
3285     mCapturePeriodPositionCb = nullptr;
3286 }
3287 
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)3288 int32_t AudioServiceClient::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
3289 {
3290     std::lock_guard<std::mutex> lockSet(writeCallbackMutex_);
3291     CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "SetRendererWriteCallback callback is nullptr");
3292     writeCallback_ = callback;
3293     return SUCCESS;
3294 }
3295 
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)3296 int32_t AudioServiceClient::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
3297 {
3298     CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "SetCapturerReadCallback callback is nullptr");
3299     readCallback_ = callback;
3300     return SUCCESS;
3301 }
3302 
CheckOffloadBreakWaitWrite()3303 void AudioServiceClient::CheckOffloadBreakWaitWrite()
3304 {
3305     if (offloadEnable_) {
3306         breakingWritePa_ = true;
3307         pa_threaded_mainloop_signal(mainLoop, 0);
3308     }
3309 }
3310 
SendWriteBufferRequestEvent()3311 void AudioServiceClient::SendWriteBufferRequestEvent()
3312 {
3313     // send write event to handler
3314     lock_guard<mutex> runnerlock(runnerMutex_);
3315     if (runnerReleased_) {
3316         AUDIO_WARNING_LOG("SendWriteBufferRequestEvent after runner released");
3317         return;
3318     }
3319     SendEvent(AppExecFwk::InnerEvent::Get(WRITE_BUFFER_REQUEST));
3320 }
3321 
SendReadBufferRequestEvent()3322 void AudioServiceClient::SendReadBufferRequestEvent()
3323 {
3324     // send write event to handler
3325     lock_guard<mutex> runnerlock(runnerMutex_);
3326     if (runnerReleased_) {
3327         AUDIO_WARNING_LOG("SendReadBufferRequestEvent after runner released");
3328         return;
3329     }
3330     SendEvent(AppExecFwk::InnerEvent::Get(READ_BUFFER_REQUEST));
3331 }
3332 
HandleWriteRequestEvent()3333 void AudioServiceClient::HandleWriteRequestEvent()
3334 {
3335     std::lock_guard<std::mutex> lockSet(writeCallbackMutex_);
3336     // do callback to application
3337     if (writeCallback_) {
3338         size_t requestSize;
3339         GetMinimumBufferSize(requestSize);
3340         writeCallback_->OnWriteData(requestSize);
3341     }
3342 }
3343 
HandleReadRequestEvent()3344 void AudioServiceClient::HandleReadRequestEvent()
3345 {
3346     // do callback to application
3347     if (readCallback_) {
3348         size_t requestSize;
3349         GetMinimumBufferSize(requestSize);
3350         readCallback_->OnReadData(requestSize);
3351     }
3352 }
3353 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)3354 void AudioServiceClient::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
3355 {
3356     uint32_t eventId = event->GetInnerEventId();
3357     uint64_t mFrameMarkPosition;
3358     uint64_t mFramePeriodNumber;
3359     std::shared_ptr<RendererPositionCallback> renderPositionCb;
3360     std::shared_ptr<RendererPeriodPositionCallback> renderPeriodPositionCb;
3361     std::shared_ptr<CapturerPositionCallback> capturePositionCb;
3362     std::shared_ptr<CapturerPeriodPositionCallback> capturePeriodPositionCb;
3363 
3364     switch (eventId) {
3365         case WRITE_BUFFER_REQUEST:
3366             HandleWriteRequestEvent();
3367             break;
3368         case READ_BUFFER_REQUEST:
3369             HandleReadRequestEvent();
3370             break;
3371 
3372         // RenderMarkReach
3373         case RENDERER_MARK_REACHED_REQUEST:
3374             mFrameMarkPosition = event->GetParam();
3375             HandleRenderMarkReachedEvent(mFrameMarkPosition);
3376             break;
3377         case SET_RENDERER_MARK_REACHED_REQUEST:
3378             renderPositionCb = event->GetSharedObject<RendererPositionCallback>();
3379             HandleSetRenderMarkReachedEvent(renderPositionCb);
3380             break;
3381         case UNSET_RENDERER_MARK_REACHED_REQUEST:
3382             HandleUnsetRenderMarkReachedEvent();
3383             break;
3384 
3385         // RenderPeriodReach
3386         case RENDERER_PERIOD_REACHED_REQUEST:
3387             mFramePeriodNumber = event->GetParam();
3388             HandleRenderPeriodReachedEvent(mFramePeriodNumber);
3389             break;
3390         case SET_RENDERER_PERIOD_REACHED_REQUEST:
3391             renderPeriodPositionCb = event->GetSharedObject<RendererPeriodPositionCallback>();
3392             HandleSetRenderPeriodReachedEvent(renderPeriodPositionCb);
3393             break;
3394         case UNSET_RENDERER_PERIOD_REACHED_REQUEST:
3395             HandleUnsetRenderPeriodReachedEvent();
3396             break;
3397 
3398         // CapturerMarkReach
3399         case CAPTURER_MARK_REACHED_REQUEST:
3400             mFrameMarkPosition = event->GetParam();
3401             HandleCapturerMarkReachedEvent(mFrameMarkPosition);
3402             break;
3403         case SET_CAPTURER_MARK_REACHED_REQUEST:
3404             capturePositionCb = event->GetSharedObject<CapturerPositionCallback>();
3405             HandleSetCapturerMarkReachedEvent(capturePositionCb);
3406             break;
3407         case UNSET_CAPTURER_MARK_REACHED_REQUEST:
3408             HandleUnsetCapturerMarkReachedEvent();
3409             break;
3410 
3411         // CapturerPeriodReach
3412         case CAPTURER_PERIOD_REACHED_REQUEST:
3413             mFramePeriodNumber = event->GetParam();
3414             HandleCapturerPeriodReachedEvent(mFramePeriodNumber);
3415             break;
3416         case SET_CAPTURER_PERIOD_REACHED_REQUEST:
3417             capturePeriodPositionCb = event->GetSharedObject<CapturerPeriodPositionCallback>();
3418             HandleSetCapturerPeriodReachedEvent(capturePeriodPositionCb);
3419             break;
3420         case UNSET_CAPTURER_PERIOD_REACHED_REQUEST:
3421             HandleUnsetCapturerPeriodReachedEvent();
3422             break;
3423 
3424         default:
3425             break;
3426     }
3427 }
3428 
GetEffectModeName(AudioEffectMode effectMode)3429 const std::string AudioServiceClient::GetEffectModeName(AudioEffectMode effectMode)
3430 {
3431     std::string name;
3432     switch (effectMode) {
3433         case EFFECT_NONE:
3434             name = "EFFECT_NONE";
3435             break;
3436         default:
3437             name = "EFFECT_DEFAULT";
3438     }
3439 
3440     const std::string modeName = name;
3441     return modeName;
3442 }
3443 
GetStreamAudioEffectMode()3444 AudioEffectMode AudioServiceClient::GetStreamAudioEffectMode()
3445 {
3446     return effectMode;
3447 }
3448 
GetStreamFramesWritten()3449 int64_t AudioServiceClient::GetStreamFramesWritten()
3450 {
3451     CHECK_AND_RETURN_RET_LOG(mFrameSize != 0, ERROR, "Error frame size");
3452     return mTotalBytesWritten / mFrameSize;
3453 }
3454 
GetStreamFramesRead()3455 int64_t AudioServiceClient::GetStreamFramesRead()
3456 {
3457     CHECK_AND_RETURN_RET_LOG(mFrameSize != 0, ERROR, "Error frame size");
3458     return mTotalBytesRead / mFrameSize;
3459 }
3460 
SetStreamAudioEffectMode(AudioEffectMode audioEffectMode)3461 int32_t AudioServiceClient::SetStreamAudioEffectMode(AudioEffectMode audioEffectMode)
3462 {
3463     AUDIO_INFO_LOG("Mode: %{public}d", audioEffectMode);
3464 
3465     int32_t ret = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
3466     CHECK_AND_RETURN_RET_LOG(ret >= 0, AUDIO_CLIENT_PA_ERR,
3467         "set stream audio effect mode: invalid stream state");
3468 
3469     pa_threaded_mainloop_lock(mainLoop);
3470 
3471     effectMode = audioEffectMode;
3472 
3473     const std::string effectModeName = GetEffectModeName(audioEffectMode);
3474 
3475     pa_proplist *propList = pa_proplist_new();
3476     if (propList == nullptr) {
3477         AUDIO_ERR_LOG("pa_proplist_new failed");
3478         pa_threaded_mainloop_unlock(mainLoop);
3479         return AUDIO_CLIENT_ERR;
3480     }
3481 
3482     pa_proplist_sets(propList, "scene.type", effectSceneName.c_str());
3483     pa_proplist_sets(propList, "scene.mode", effectModeName.c_str());
3484     pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
3485         nullptr, nullptr);
3486     pa_proplist_free(propList);
3487     pa_operation_unref(updatePropOperation);
3488 
3489     pa_threaded_mainloop_unlock(mainLoop);
3490 
3491     return AUDIO_CLIENT_SUCCESS;
3492 }
3493 
SetStreamInnerCapturerState(bool isInnerCapturer)3494 void AudioServiceClient::SetStreamInnerCapturerState(bool isInnerCapturer)
3495 {
3496     AUDIO_DEBUG_LOG("SetInnerCapturerState: %{public}d", isInnerCapturer);
3497     isInnerCapturerStream_ = isInnerCapturer;
3498 }
3499 
SetStreamPrivacyType(AudioPrivacyType privacyType)3500 void AudioServiceClient::SetStreamPrivacyType(AudioPrivacyType privacyType)
3501 {
3502     AUDIO_DEBUG_LOG("SetInnerCapturerState: %{public}d", privacyType);
3503     mPrivacyType = privacyType;
3504 }
3505 
SetStreamUsage(StreamUsage usage)3506 void AudioServiceClient::SetStreamUsage(StreamUsage usage)
3507 {
3508     AUDIO_DEBUG_LOG("SetStreamUsage: %{public}d", usage);
3509     mStreamUsage = usage;
3510 }
3511 
SetWakeupCapturerState(bool isWakeupCapturer)3512 void AudioServiceClient::SetWakeupCapturerState(bool isWakeupCapturer)
3513 {
3514     AUDIO_DEBUG_LOG("SetWakeupCapturerState: %{public}d", isWakeupCapturer);
3515     isWakeupCapturerStream_ = isWakeupCapturer;
3516 }
3517 
SetCapturerSource(int capturerSource)3518 void AudioServiceClient::SetCapturerSource(int capturerSource)
3519 {
3520     AUDIO_DEBUG_LOG("SetCapturerSource: %{public}d", capturerSource);
3521     capturerSource_ = capturerSource;
3522 }
3523 
ConvertChLayoutToPaChMap(const uint64_t & channelLayout,pa_channel_map & paMap)3524 uint32_t AudioServiceClient::ConvertChLayoutToPaChMap(const uint64_t &channelLayout, pa_channel_map &paMap)
3525 {
3526     uint32_t channelNum = 0;
3527     uint64_t mode = (channelLayout & CH_MODE_MASK) >> CH_MODE_OFFSET;
3528     switch (mode) {
3529         case 0: {
3530             for (auto bit = chSetToPaPositionMap.begin(); bit != chSetToPaPositionMap.end(); ++bit) {
3531                 if ((channelLayout & (bit->first)) != 0) {
3532                     paMap.map[channelNum++] = bit->second;
3533                 }
3534             }
3535             break;
3536         }
3537         case 1: {
3538             uint64_t order = (channelLayout & CH_HOA_ORDNUM_MASK) >> CH_HOA_ORDNUM_OFFSET;
3539             channelNum = (order + 1) * (order + 1);
3540             for (uint32_t i = 0; i < channelNum; ++i) {
3541                 paMap.map[i] = chSetToPaPositionMap[FRONT_LEFT];
3542             }
3543             break;
3544         }
3545         default:
3546             channelNum = 0;
3547             break;
3548     }
3549     return channelNum;
3550 }
3551 
RegisterSpatializationStateEventListener()3552 int32_t AudioServiceClient::RegisterSpatializationStateEventListener()
3553 {
3554     if (firstSpatializationRegistered_) {
3555         firstSpatializationRegistered_ = false;
3556     } else {
3557         UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
3558     }
3559 
3560     if (!spatializationStateChangeCallback_) {
3561         spatializationStateChangeCallback_ = std::make_shared<AudioSpatializationStateChangeCallbackImpl>();
3562         CHECK_AND_RETURN_RET_LOG(spatializationStateChangeCallback_, ERROR, "Memory Allocation Failed !!");
3563     }
3564     spatializationStateChangeCallback_->setAudioServiceClientObj(this);
3565 
3566     int32_t ret = AudioPolicyManager::GetInstance().RegisterSpatializationStateEventListener(
3567         sessionID_, mStreamUsage, spatializationStateChangeCallback_);
3568     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "RegisterSpatializationStateEventListener failed");
3569     spatializationRegisteredSessionID_ = sessionID_;
3570 
3571     return SUCCESS;
3572 }
3573 
UnregisterSpatializationStateEventListener(uint32_t sessionID)3574 int32_t AudioServiceClient::UnregisterSpatializationStateEventListener(uint32_t sessionID)
3575 {
3576     int32_t ret = AudioPolicyManager::GetInstance().UnregisterSpatializationStateEventListener(sessionID);
3577     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "UnregisterSpatializationStateEventListener failed");
3578     return SUCCESS;
3579 }
3580 
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)3581 void AudioServiceClient::OnSpatializationStateChange(const AudioSpatializationState &spatializationState)
3582 {
3583     int32_t res = CheckPaStatusIfinvalid(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR);
3584     CHECK_AND_RETURN_LOG(res >= 0, "OnSpatializationStateChange: invalid stream state");
3585     spatializationEnabled_ = std::to_string(spatializationState.spatializationEnabled);
3586     headTrackingEnabled_ = std::to_string(spatializationState.headTrackingEnabled);
3587     CHECK_AND_RETURN_LOG(context != nullptr, "context is null");
3588 
3589     pa_threaded_mainloop_lock(mainLoop);
3590 
3591     pa_proplist *propList = pa_proplist_new();
3592     if (propList == nullptr) {
3593         AUDIO_ERR_LOG("pa_proplist_new failed");
3594         pa_threaded_mainloop_unlock(mainLoop);
3595         return;
3596     }
3597 
3598     pa_proplist_sets(propList, "spatialization.enabled", spatializationEnabled_.c_str());
3599     pa_proplist_sets(propList, "headtracking.enabled", headTrackingEnabled_.c_str());
3600     pa_operation *updatePropOperation = pa_stream_proplist_update(paStream, PA_UPDATE_REPLACE, propList,
3601         nullptr, nullptr);
3602     pa_proplist_free(propList);
3603     pa_operation_unref(updatePropOperation);
3604 
3605     pa_threaded_mainloop_unlock(mainLoop);
3606 }
3607 
SetStreamSpeed(float speed)3608 int32_t AudioServiceClient::SetStreamSpeed(float speed)
3609 {
3610     speed_ = speed;
3611     return SUCCESS;
3612 }
3613 
GetStreamSpeed()3614 float AudioServiceClient::GetStreamSpeed()
3615 {
3616     return speed_;
3617 }
3618 
GetAppTokenId() const3619 uint32_t AudioServiceClient::GetAppTokenId() const
3620 {
3621     return appTokenId_;
3622 }
3623 
AudioSpatializationStateChangeCallbackImpl()3624 AudioSpatializationStateChangeCallbackImpl::AudioSpatializationStateChangeCallbackImpl()
3625 {
3626     AUDIO_INFO_LOG("AudioSpatializationStateChangeCallbackImpl instance create");
3627 }
3628 
~AudioSpatializationStateChangeCallbackImpl()3629 AudioSpatializationStateChangeCallbackImpl::~AudioSpatializationStateChangeCallbackImpl()
3630 {
3631     AUDIO_INFO_LOG("AudioSpatializationStateChangeCallbackImpl instance destory");
3632 }
3633 
setAudioServiceClientObj(AudioServiceClient * serviceClientObj)3634 void AudioSpatializationStateChangeCallbackImpl::setAudioServiceClientObj(AudioServiceClient *serviceClientObj)
3635 {
3636     serviceClient_ = serviceClientObj;
3637 }
3638 
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)3639 void AudioSpatializationStateChangeCallbackImpl::OnSpatializationStateChange(
3640     const AudioSpatializationState &spatializationState)
3641 {
3642     if (serviceClient_ == nullptr) {
3643         return;
3644     }
3645     serviceClient_->OnSpatializationStateChange(spatializationState);
3646 }
3647 } // namespace AudioStandard
3648 } // namespace OHOS
3649 
3650