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