1 /*
2 * Copyright (c) 2022-2024 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioUtils"
17 #endif
18
19 #include "audio_utils.h"
20 #include <cinttypes>
21 #include <ctime>
22 #include <sstream>
23 #include <ostream>
24 #include <climits>
25 #include <string>
26 #include <climits>
27 #include "audio_utils.h"
28 #include "audio_utils_c.h"
29 #include "audio_errors.h"
30 #include "audio_common_log.h"
31 #ifdef FEATURE_HITRACE_METER
32 #include "hitrace_meter.h"
33 #endif
34 #include "parameter.h"
35 #include "tokenid_kit.h"
36 #include "ipc_skeleton.h"
37 #include "access_token.h"
38 #include "accesstoken_kit.h"
39 #include "privacy_kit.h"
40 #include "xcollie/xcollie.h"
41 #include "xcollie/xcollie_define.h"
42 #include "securec.h"
43 #include "privacy_error.h"
44
45 using OHOS::Security::AccessToken::AccessTokenKit;
46
47 namespace OHOS {
48 namespace AudioStandard {
49 namespace {
50 constexpr int32_t UID_AUDIO = 1041;
51 constexpr int32_t UID_MSDP_SA = 6699;
52 constexpr int32_t UID_INTELLIGENT_VOICE_SA = 1042;
53 constexpr int32_t UID_CAAS_SA = 5527;
54 constexpr int32_t UID_DISTRIBUTED_AUDIO_SA = 3055;
55 constexpr int32_t UID_FOUNDATION_SA = 5523;
56 constexpr int32_t UID_DISTRIBUTED_CALL_SA = 3069;
57 constexpr int32_t UID_TELEPHONY_SA = 1001;
58 constexpr int32_t TIME_OUT_SECONDS = 10;
59
60 const uint32_t UNIQUE_ID_INTERVAL = 8;
61
62 constexpr size_t FIRST_CHAR = 1;
63 constexpr size_t MIN_LEN = 8;
64 constexpr size_t HEAD_STR_LEN = 2;
65 constexpr size_t TAIL_STR_LEN = 5;
66
67 const std::set<int32_t> RECORD_ALLOW_BACKGROUND_LIST = {
68 #ifdef AUDIO_BUILD_VARIANT_ROOT
69 0, // UID_ROOT
70 #endif
71 UID_MSDP_SA,
72 UID_INTELLIGENT_VOICE_SA,
73 UID_CAAS_SA,
74 UID_DISTRIBUTED_AUDIO_SA,
75 UID_FOUNDATION_SA,
76 UID_DISTRIBUTED_CALL_SA,
77 UID_AUDIO,
78 UID_TELEPHONY_SA // used in distributed communication call
79 };
80
81 const std::set<SourceType> NO_BACKGROUND_CHECK_SOURCE_TYPE = {
82 SOURCE_TYPE_PLAYBACK_CAPTURE,
83 SOURCE_TYPE_VOICE_CALL,
84 SOURCE_TYPE_REMOTE_CAST
85 };
86 }
87
88 static std::unordered_map<AudioStreamType, std::string> STREAM_TYPE_NAME_MAP = {
89 {STREAM_VOICE_ASSISTANT, "VOICE_ASSISTANT"},
90 {STREAM_VOICE_CALL, "VOICE_CALL"},
91 {STREAM_SYSTEM, "SYSTEM"},
92 {STREAM_RING, "RING"},
93 {STREAM_MUSIC, "MUSIC"},
94 {STREAM_ALARM, "ALARM"},
95 {STREAM_NOTIFICATION, "NOTIFICATION"},
96 {STREAM_BLUETOOTH_SCO, "BLUETOOTH_SCO"},
97 {STREAM_DTMF, "DTMF"},
98 {STREAM_TTS, "TTS"},
99 {STREAM_ACCESSIBILITY, "ACCESSIBILITY"},
100 {STREAM_ULTRASONIC, "ULTRASONIC"},
101 {STREAM_WAKEUP, "WAKEUP"},
102 {STREAM_CAMCORDER, "CAMCORDER"},
103 {STREAM_ENFORCED_AUDIBLE, "ENFORCED_AUDIBLE"},
104 {STREAM_MOVIE, "MOVIE"},
105 {STREAM_GAME, "GAME"},
106 {STREAM_SPEECH, "SPEECH"},
107 {STREAM_SYSTEM_ENFORCED, "SYSTEM_ENFORCED"},
108 {STREAM_VOICE_MESSAGE, "VOICE_MESSAGE"},
109 {STREAM_NAVIGATION, "NAVIGATION"},
110 {STREAM_INTERNAL_FORCE_STOP, "INTERNAL_FORCE_STOP"},
111 {STREAM_SOURCE_VOICE_CALL, "SOURCE_VOICE_CALL"},
112 {STREAM_VOICE_COMMUNICATION, "VOICE_COMMUNICATION"},
113 {STREAM_VOICE_RING, "VOICE_RING"},
114 {STREAM_VOICE_CALL_ASSISTANT, "VOICE_CALL_ASSISTANT"},
115 };
116
WatchTimeout(const std::string & funcName,int64_t timeoutNs)117 WatchTimeout::WatchTimeout(const std::string &funcName, int64_t timeoutNs) : funcName_(funcName), timeoutNs_(timeoutNs)
118 {
119 startTimeNs_ = ClockTime::GetCurNano();
120 }
121
~WatchTimeout()122 WatchTimeout::~WatchTimeout()
123 {
124 if (!isChecked_) {
125 CheckCurrTimeout();
126 }
127 }
128
CheckCurrTimeout()129 void WatchTimeout::CheckCurrTimeout()
130 {
131 int64_t cost = ClockTime::GetCurNano() - startTimeNs_;
132 if (cost > timeoutNs_) {
133 AUDIO_WARNING_LOG("[%{public}s] cost %{public}" PRId64"ms!", funcName_.c_str(), cost / AUDIO_US_PER_SECOND);
134 }
135 isChecked_ = true;
136 }
IsDualToneStreamType(const AudioStreamType streamType)137 bool Util::IsDualToneStreamType(const AudioStreamType streamType)
138 {
139 return streamType == STREAM_RING || streamType == STREAM_VOICE_RING || streamType == STREAM_ALARM;
140 }
141
IsRingerOrAlarmerStreamUsage(const StreamUsage & usage)142 bool Util::IsRingerOrAlarmerStreamUsage(const StreamUsage &usage)
143 {
144 return usage == STREAM_USAGE_ALARM || usage == STREAM_USAGE_VOICE_RINGTONE || usage == STREAM_USAGE_RINGTONE;
145 }
146
IsRingerAudioScene(const AudioScene & audioScene)147 bool Util::IsRingerAudioScene(const AudioScene &audioScene)
148 {
149 return audioScene == AUDIO_SCENE_RINGING || audioScene == AUDIO_SCENE_VOICE_RINGING;
150 }
151
GetSamplePerFrame(const AudioSampleFormat & format)152 uint32_t Util::GetSamplePerFrame(const AudioSampleFormat &format)
153 {
154 uint32_t audioPerSampleLength = 2; // 2 byte
155 switch (format) {
156 case AudioSampleFormat::SAMPLE_U8:
157 audioPerSampleLength = 1;
158 break;
159 case AudioSampleFormat::SAMPLE_S16LE:
160 audioPerSampleLength = 2; // 2 byte
161 break;
162 case AudioSampleFormat::SAMPLE_S24LE:
163 audioPerSampleLength = 3; // 3 byte
164 break;
165 case AudioSampleFormat::SAMPLE_S32LE:
166 case AudioSampleFormat::SAMPLE_F32LE:
167 audioPerSampleLength = 4; // 4 byte
168 break;
169 default:
170 break;
171 }
172 return audioPerSampleLength;
173 }
174
GetCurNano()175 int64_t ClockTime::GetCurNano()
176 {
177 int64_t result = -1; // -1 for bad result.
178 struct timespec time;
179 clockid_t clockId = CLOCK_MONOTONIC;
180 int ret = clock_gettime(clockId, &time);
181 CHECK_AND_RETURN_RET_LOG(ret >= 0, result,
182 "GetCurNanoTime fail, result:%{public}d", ret);
183 result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
184 return result;
185 }
186
GetRealNano()187 int64_t ClockTime::GetRealNano()
188 {
189 int64_t result = -1; // -1 for bad result
190 struct timespec time;
191 clockid_t clockId = CLOCK_REALTIME;
192 int ret = clock_gettime(clockId, &time);
193 CHECK_AND_RETURN_RET_LOG(ret >= 0, result,
194 "GetRealNanotime fail, result:%{public}d", ret);
195 result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
196 return result;
197 }
198
AbsoluteSleep(int64_t nanoTime)199 int32_t ClockTime::AbsoluteSleep(int64_t nanoTime)
200 {
201 int32_t ret = -1; // -1 for bad result.
202 CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
203 "AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
204 struct timespec time;
205 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
206 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
207
208 clockid_t clockId = CLOCK_MONOTONIC;
209 ret = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
210 if (ret != 0) {
211 AUDIO_WARNING_LOG("AbsoluteSleep may failed, ret is :%{public}d", ret);
212 }
213
214 return ret;
215 }
216
NanoTimeToString(int64_t nanoTime)217 std::string ClockTime::NanoTimeToString(int64_t nanoTime)
218 {
219 struct tm *tm_info;
220 char buffer[80];
221 time_t time_seconds = nanoTime / AUDIO_NS_PER_SECOND;
222
223 tm_info = localtime(&time_seconds);
224 if (tm_info == NULL) {
225 AUDIO_ERR_LOG("get localtime failed!");
226 return "";
227 }
228
229 size_t res = strftime(buffer, sizeof(buffer), "%H:%M:%S", tm_info);
230 CHECK_AND_RETURN_RET_LOG(res != 0, "", "strftime failed!");
231 return std::string(buffer);
232 }
233
RelativeSleep(int64_t nanoTime)234 int32_t ClockTime::RelativeSleep(int64_t nanoTime)
235 {
236 int32_t ret = -1; // -1 for bad result.
237 CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
238 "AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
239 struct timespec time;
240 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
241 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
242
243 clockid_t clockId = CLOCK_MONOTONIC;
244 const int relativeFlag = 0; // flag of relative sleep.
245 ret = clock_nanosleep(clockId, relativeFlag, &time, nullptr);
246 if (ret != 0) {
247 AUDIO_WARNING_LOG("RelativeSleep may failed, ret is :%{public}d", ret);
248 }
249
250 return ret;
251 }
252
Count(const std::string & value,int64_t count)253 void Trace::Count(const std::string &value, int64_t count)
254 {
255 #ifdef FEATURE_HITRACE_METER
256 CountTrace(HITRACE_TAG_ZAUDIO, value, count);
257 #endif
258 }
259
CountVolume(const std::string & value,uint8_t data)260 void Trace::CountVolume(const std::string &value, uint8_t data)
261 {
262 #ifdef FEATURE_HITRACE_METER
263 if (data == 0) {
264 CountTrace(HITRACE_TAG_ZAUDIO, value, PCM_MAYBE_SILENT);
265 } else {
266 CountTrace(HITRACE_TAG_ZAUDIO, value, PCM_MAYBE_NOT_SILENT);
267 }
268 #endif
269 }
270
Trace(const std::string & value)271 Trace::Trace(const std::string &value)
272 {
273 value_ = value;
274 isFinished_ = false;
275 #ifdef FEATURE_HITRACE_METER
276 StartTrace(HITRACE_TAG_ZAUDIO, value_);
277 #endif
278 }
279
End()280 void Trace::End()
281 {
282 #ifdef FEATURE_HITRACE_METER
283 if (!isFinished_) {
284 FinishTrace(HITRACE_TAG_ZAUDIO);
285 isFinished_ = true;
286 }
287 #endif
288 }
289
~Trace()290 Trace::~Trace()
291 {
292 End();
293 }
294
AudioXCollie(const std::string & tag,uint32_t timeoutSeconds,std::function<void (void *)> func,void * arg,uint32_t flag)295 AudioXCollie::AudioXCollie(const std::string &tag, uint32_t timeoutSeconds,
296 std::function<void(void *)> func, void *arg, uint32_t flag)
297 {
298 AUDIO_DEBUG_LOG("Start AudioXCollie, tag: %{public}s, timeoutSeconds: %{public}u, flag: %{public}u",
299 tag.c_str(), timeoutSeconds, flag);
300 id_ = HiviewDFX::XCollie::GetInstance().SetTimer(tag, timeoutSeconds, func, arg, flag);
301 tag_ = tag;
302 isCanceled_ = false;
303 }
304
~AudioXCollie()305 AudioXCollie::~AudioXCollie()
306 {
307 CancelXCollieTimer();
308 }
309
CancelXCollieTimer()310 void AudioXCollie::CancelXCollieTimer()
311 {
312 if (!isCanceled_) {
313 HiviewDFX::XCollie::GetInstance().CancelTimer(id_);
314 isCanceled_ = true;
315 AUDIO_DEBUG_LOG("CancelXCollieTimer: cancel timer %{public}s", tag_.c_str());
316 }
317 }
318
VerifyIsShell()319 bool PermissionUtil::VerifyIsShell()
320 {
321 auto tokenId = IPCSkeleton::GetCallingTokenID();
322 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
323 if (tokenTypeFlag == Security::AccessToken::TOKEN_SHELL) {
324 return true;
325 }
326 return false;
327 }
328
VerifyIsAudio()329 bool PermissionUtil::VerifyIsAudio()
330 {
331 int32_t callingUid = IPCSkeleton::GetCallingUid();
332 if (UID_AUDIO == callingUid) {
333 return true;
334 }
335 #ifdef AUDIO_BUILD_VARIANT_ROOT
336 if (callingUid == 0) {
337 AUDIO_WARNING_LOG("Root calling!");
338 return true;
339 }
340 #endif
341 return false;
342 }
343
VerifyIsSystemApp()344 bool PermissionUtil::VerifyIsSystemApp()
345 {
346 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
347 bool tmp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
348 CHECK_AND_RETURN_RET(!tmp, true);
349
350 AUDIO_PRERELEASE_LOGE("Check system app permission reject");
351 return false;
352 }
353
VerifySelfPermission()354 bool PermissionUtil::VerifySelfPermission()
355 {
356 Security::AccessToken::FullTokenID selfToken = IPCSkeleton::GetSelfTokenID();
357
358 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfToken));
359
360 CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_NATIVE, true);
361
362 CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_SHELL, true);
363
364 bool tmp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken);
365 CHECK_AND_RETURN_RET(!tmp, true);
366
367 AUDIO_ERR_LOG("Check self app permission reject");
368 return false;
369 }
370
VerifySystemPermission()371 bool PermissionUtil::VerifySystemPermission()
372 {
373 auto tokenId = IPCSkeleton::GetCallingTokenID();
374 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
375
376 CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_NATIVE, true);
377 #ifdef AUDIO_BUILD_VARIANT_ROOT
378 CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_SHELL, true);
379 #endif
380 bool tmp = VerifyIsSystemApp();
381 CHECK_AND_RETURN_RET(!tmp, true);
382
383 AUDIO_PRERELEASE_LOGE("Check system permission reject");
384 return false;
385 }
386
VerifyPermission(const std::string & permissionName,uint32_t tokenId)387 bool PermissionUtil::VerifyPermission(const std::string &permissionName, uint32_t tokenId)
388 {
389 int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
390 CHECK_AND_RETURN_RET_LOG(res == Security::AccessToken::PermissionState::PERMISSION_GRANTED,
391 false, "Permission denied [%{public}s]", permissionName.c_str());
392
393 return true;
394 }
395
NeedVerifyBackgroundCapture(int32_t callingUid,SourceType sourceType)396 bool PermissionUtil::NeedVerifyBackgroundCapture(int32_t callingUid, SourceType sourceType)
397 {
398 if (RECORD_ALLOW_BACKGROUND_LIST.count(callingUid)) {
399 AUDIO_INFO_LOG("internal sa(%{public}d) user directly recording", callingUid);
400 return false;
401 }
402 if (NO_BACKGROUND_CHECK_SOURCE_TYPE.count(sourceType)) {
403 AUDIO_INFO_LOG("sourceType %{public}d", sourceType);
404 return false;
405 }
406 return true;
407 }
408
VerifyBackgroundCapture(uint32_t tokenId,uint64_t fullTokenId)409 bool PermissionUtil::VerifyBackgroundCapture(uint32_t tokenId, uint64_t fullTokenId)
410 {
411 Trace trace("PermissionUtil::VerifyBackgroundCapture");
412 if (Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
413 AUDIO_INFO_LOG("system app recording");
414 return true;
415 }
416
417 bool ret = Security::AccessToken::PrivacyKit::IsAllowedUsingPermission(tokenId, MICROPHONE_PERMISSION);
418 if (!ret) {
419 AUDIO_ERR_LOG("failed: not allowed!");
420 }
421 AUDIO_INFO_LOG("tokenId:%{public}u fullTokenId:%{public}" PRIu64": %{public}s", tokenId, fullTokenId, (ret ? "true"
422 : "false"));
423 return ret;
424 }
425
426 std::mutex recordMapMutex;
427 std::map<std::uint32_t, std::set<uint32_t>> g_tokenIdRecordMap_ = {};
428
NotifyStart(uint32_t targetTokenId,uint32_t sessionId)429 bool PermissionUtil::NotifyStart(uint32_t targetTokenId, uint32_t sessionId)
430 {
431 AudioXCollie audioXCollie("PermissionUtil::NotifyStart", TIME_OUT_SECONDS);
432 std::lock_guard<std::mutex> lock(recordMapMutex);
433 if (g_tokenIdRecordMap_.count(targetTokenId)) {
434 if (!g_tokenIdRecordMap_[targetTokenId].count(sessionId)) {
435 g_tokenIdRecordMap_[targetTokenId].emplace(sessionId);
436 } else {
437 AUDIO_WARNING_LOG("this stream %{public}u is already running, no need call start", sessionId);
438 }
439 } else {
440 Trace trace("PrivacyKit::StartUsingPermission");
441 AUDIO_WARNING_LOG("PrivacyKit::StartUsingPermission tokenId: %{public}d sessionId:%{public}d",
442 targetTokenId, sessionId);
443 WatchTimeout guard("Security::AccessToken::PrivacyKit::StartUsingPermission:NotifyPrivacy");
444 int res = Security::AccessToken::PrivacyKit::StartUsingPermission(targetTokenId, MICROPHONE_PERMISSION);
445 guard.CheckCurrTimeout();
446 if (res != 0) {
447 AUDIO_ERR_LOG("StartUsingPermission for tokenId %{public}u!, The PrivacyKit error code is %{public}d",
448 targetTokenId, res);
449 return false;
450 }
451 WatchTimeout reguard("Security::AccessToken::PrivacyKit::AddPermissionUsedRecord:NotifyPrivacy");
452 res = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(targetTokenId, MICROPHONE_PERMISSION, 1, 0);
453 reguard.CheckCurrTimeout();
454 if (res != 0) {
455 AUDIO_ERR_LOG("AddPermissionUsedRecord for tokenId %{public}u! The PrivacyKit error code is %{public}d",
456 targetTokenId, res);
457 return false;
458 }
459 g_tokenIdRecordMap_[targetTokenId] = {sessionId};
460 }
461 return true;
462 }
463
NotifyStop(uint32_t targetTokenId,uint32_t sessionId)464 bool PermissionUtil::NotifyStop(uint32_t targetTokenId, uint32_t sessionId)
465 {
466 AudioXCollie audioXCollie("PermissionUtil::NotifyStop", TIME_OUT_SECONDS);
467 std::unique_lock<std::mutex> lock(recordMapMutex);
468 if (!g_tokenIdRecordMap_.count(targetTokenId)) {
469 AUDIO_INFO_LOG("this TokenId %{public}u is already not in using", targetTokenId);
470 return true;
471 }
472
473 if (g_tokenIdRecordMap_[targetTokenId].count(sessionId)) {
474 g_tokenIdRecordMap_[targetTokenId].erase(sessionId);
475 }
476 AUDIO_DEBUG_LOG("this TokenId %{public}u set size is %{public}zu!", targetTokenId,
477 g_tokenIdRecordMap_[targetTokenId].size());
478 if (g_tokenIdRecordMap_[targetTokenId].empty()) {
479 g_tokenIdRecordMap_.erase(targetTokenId);
480
481 Trace trace("PrivacyKit::StopUsingPermission");
482 AUDIO_WARNING_LOG("PrivacyKit::StopUsingPermission tokenId:%{public}d sessionId:%{public}d",
483 targetTokenId, sessionId);
484 WatchTimeout guard("Security::AccessToken::PrivacyKit::StopUsingPermission:NotifyPrivacy");
485 int32_t res = Security::AccessToken::PrivacyKit::StopUsingPermission(targetTokenId, MICROPHONE_PERMISSION);
486 guard.CheckCurrTimeout();
487 if (res != 0) {
488 AUDIO_ERR_LOG("StopUsingPermission for tokenId %{public}u!, The PrivacyKit error code is %{public}d",
489 targetTokenId, res);
490 return false;
491 }
492 }
493 return true;
494 }
495
AdjustStereoToMonoForPCM8Bit(int8_t * data,uint64_t len)496 void AdjustStereoToMonoForPCM8Bit(int8_t *data, uint64_t len)
497 {
498 // the number 2: stereo audio has 2 channels
499 uint64_t count = len / 2;
500
501 while (count > 0) {
502 // the number 2 is the count of stereo audio channels
503 data[0] = data[0] / 2 + data[1] / 2;
504 data[1] = data[0];
505 data += 2;
506 count--;
507 }
508 }
509
AdjustStereoToMonoForPCM16Bit(int16_t * data,uint64_t len)510 void AdjustStereoToMonoForPCM16Bit(int16_t *data, uint64_t len)
511 {
512 uint64_t count = len / 2 / 2;
513 // first number 2: stereo audio has 2 channels
514 // second number 2: the bit depth of PCM16Bit is 16 bits (2 bytes)
515
516 while (count > 0) {
517 // the number 2 is the count of stereo audio channels
518 data[0] = data[0] / 2 + data[1] / 2;
519 data[1] = data[0];
520 data += 2;
521 count--;
522 }
523 }
524
AdjustStereoToMonoForPCM24Bit(int8_t * data,uint64_t len)525 void AdjustStereoToMonoForPCM24Bit(int8_t *data, uint64_t len)
526 {
527 // 24bit is not supported for audio balance.
528 }
529
AdjustStereoToMonoForPCM32Bit(int32_t * data,uint64_t len)530 void AdjustStereoToMonoForPCM32Bit(int32_t *data, uint64_t len)
531 {
532 uint64_t count = len / 2 / 4;
533 // first number 2: stereo audio has 2 channels
534 // second number 4: the bit depth of PCM32Bit is 32 bits (4 bytes)
535
536 while (count > 0) {
537 // the number 2 is the count of stereo audio channels
538 data[0] = data[0] / 2 + data[1] / 2;
539 data[1] = data[0];
540 data += 2;
541 count--;
542 }
543 }
544
AdjustAudioBalanceForPCM8Bit(int8_t * data,uint64_t len,float left,float right)545 void AdjustAudioBalanceForPCM8Bit(int8_t *data, uint64_t len, float left, float right)
546 {
547 uint64_t count = len / 2;
548 // the number 2: stereo audio has 2 channels
549
550 while (count > 0) {
551 // the number 2 is the count of stereo audio channels
552 data[0] *= left;
553 data[1] *= right;
554 data += 2;
555 count--;
556 }
557 }
558
AdjustAudioBalanceForPCM16Bit(int16_t * data,uint64_t len,float left,float right)559 void AdjustAudioBalanceForPCM16Bit(int16_t *data, uint64_t len, float left, float right)
560 {
561 uint64_t count = len / 2 / 2;
562 // first number 2: stereo audio has 2 channels
563 // second number 2: the bit depth of PCM16Bit is 16 bits (2 bytes)
564
565 while (count > 0) {
566 // the number 2 is the count of stereo audio channels
567 data[0] *= left;
568 data[1] *= right;
569 data += 2;
570 count--;
571 }
572 }
573
AdjustAudioBalanceForPCM24Bit(int8_t * data,uint64_t len,float left,float right)574 void AdjustAudioBalanceForPCM24Bit(int8_t *data, uint64_t len, float left, float right)
575 {
576 // 24bit is not supported for audio balance.
577 }
578
AdjustAudioBalanceForPCM32Bit(int32_t * data,uint64_t len,float left,float right)579 void AdjustAudioBalanceForPCM32Bit(int32_t *data, uint64_t len, float left, float right)
580 {
581 uint64_t count = len / 2 / 4;
582 // first number 2: stereo audio has 2 channels
583 // second number 4: the bit depth of PCM32Bit is 32 bits (4 bytes)
584
585 while (count > 0) {
586 // the number 2 is the count of stereo audio channels
587 data[0] *= left;
588 data[1] *= right;
589 data += 2;
590 count--;
591 }
592 }
593
Read24Bit(const uint8_t * p)594 uint32_t Read24Bit(const uint8_t *p)
595 {
596 return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]);
597 }
598
Write24Bit(uint8_t * p,uint32_t u)599 void Write24Bit(uint8_t *p, uint32_t u)
600 {
601 p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16);
602 p[1] = static_cast<uint8_t>(u >> BIT_8);
603 p[0] = static_cast<uint8_t>(u);
604 }
605
ConvertFrom24BitToFloat(unsigned n,const uint8_t * a,float * b)606 void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b)
607 {
608 for (; n > 0; n--) {
609 int32_t s = Read24Bit(a) << BIT_8;
610 *b = s * (1.0f / (1U << (BIT_32 - 1)));
611 a += OFFSET_BIT_24;
612 b++;
613 }
614 }
615
ConvertFrom32BitToFloat(unsigned n,const int32_t * a,float * b)616 void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b)
617 {
618 for (; n > 0; n--) {
619 *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1)));
620 }
621 }
622
CapMax(float v)623 float CapMax(float v)
624 {
625 float value = v;
626 if (v > 1.0f) {
627 value = 1.0f - FLOAT_EPS;
628 } else if (v < -1.0f) {
629 value = -1.0f + FLOAT_EPS;
630 }
631 return value;
632 }
633
ConvertFromFloatTo24Bit(unsigned n,const float * a,uint8_t * b)634 void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b)
635 {
636 for (; n > 0; n--) {
637 float tmp = *a++;
638 float v = CapMax(tmp) * (1U << (BIT_32 - 1));
639 Write24Bit(b, (static_cast<int32_t>(v)) >> BIT_8);
640 b += OFFSET_BIT_24;
641 }
642 }
643
ConvertFromFloatTo32Bit(unsigned n,const float * a,int32_t * b)644 void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b)
645 {
646 for (; n > 0; n--) {
647 float tmp = *a++;
648 float v = CapMax(tmp) * (1U << (BIT_32 - 1));
649 *(b++) = static_cast<int32_t>(v);
650 }
651 }
652
UpdateMaxAmplitude(ConvertHdiFormat adapterFormat,char * frame,uint64_t replyBytes)653 float UpdateMaxAmplitude(ConvertHdiFormat adapterFormat, char *frame, uint64_t replyBytes)
654 {
655 switch (adapterFormat) {
656 case SAMPLE_U8_C: {
657 return CalculateMaxAmplitudeForPCM8Bit(reinterpret_cast<int8_t *>(frame), replyBytes);
658 }
659 case SAMPLE_S16_C: {
660 return CalculateMaxAmplitudeForPCM16Bit(reinterpret_cast<int16_t *>(frame),
661 (replyBytes / sizeof(int16_t)));
662 }
663 case SAMPLE_S24_C: {
664 return CalculateMaxAmplitudeForPCM24Bit(frame, (replyBytes / 3)); // 3 bytes
665 }
666 case SAMPLE_S32_C: {
667 return CalculateMaxAmplitudeForPCM32Bit(reinterpret_cast<int32_t *>(frame),
668 (replyBytes / sizeof(int32_t)));
669 }
670 default: {
671 AUDIO_INFO_LOG("getMaxAmplitude: Unsupported audio format: %{public}d", adapterFormat);
672 return 0;
673 }
674 }
675 }
676
CalculateMaxAmplitudeForPCM8Bit(int8_t * frame,uint64_t nSamples)677 float CalculateMaxAmplitudeForPCM8Bit(int8_t *frame, uint64_t nSamples)
678 {
679 int curMaxAmplitude = 0;
680 for (uint32_t i = nSamples; i > 0; --i) {
681 int8_t value = *frame++;
682 if (value < 0) {
683 value = -value;
684 }
685 if (curMaxAmplitude < value) {
686 curMaxAmplitude = value;
687 }
688 }
689 return float(curMaxAmplitude) / SCHAR_MAX;
690 }
691
CalculateMaxAmplitudeForPCM16Bit(int16_t * frame,uint64_t nSamples)692 float CalculateMaxAmplitudeForPCM16Bit(int16_t *frame, uint64_t nSamples)
693 {
694 int curMaxAmplitude = 0;
695 for (uint32_t i = nSamples; i > 0; --i) {
696 int16_t value = *frame++;
697 if (value < 0) {
698 value = -value;
699 }
700 if (curMaxAmplitude < value) {
701 curMaxAmplitude = value;
702 }
703 }
704 return float(curMaxAmplitude) / SHRT_MAX;
705 }
706
CalculateMaxAmplitudeForPCM24Bit(char * frame,uint64_t nSamples)707 float CalculateMaxAmplitudeForPCM24Bit(char *frame, uint64_t nSamples)
708 {
709 int curMaxAmplitude = 0;
710 for (uint32_t i = 0; i < nSamples; ++i) {
711 char *curPos = frame + (i * 3); // 3 bytes
712 int curValue = 0;
713 for (int j = 0; j < 3; ++j) { // 3 bytes
714 curValue += (*(curPos + j) << (BIT_8 * j));
715 }
716 if (curValue < 0) {
717 curValue = -curValue;
718 }
719 if (curMaxAmplitude < curValue) {
720 curMaxAmplitude = curValue;
721 }
722 }
723 return float(curMaxAmplitude) / MAX_VALUE_OF_SIGNED_24_BIT;
724 }
725
CalculateMaxAmplitudeForPCM32Bit(int32_t * frame,uint64_t nSamples)726 float CalculateMaxAmplitudeForPCM32Bit(int32_t *frame, uint64_t nSamples)
727 {
728 int curMaxAmplitude = 0;
729 for (uint32_t i = nSamples; i > 0; --i) {
730 int32_t value = *frame++;
731 if (value < 0) {
732 value = -value;
733 }
734 if (curMaxAmplitude < value) {
735 curMaxAmplitude = value;
736 }
737 }
738 return float(curMaxAmplitude) / LONG_MAX;
739 }
740
SetSysPara(const std::string & key,int32_t value)741 bool SetSysPara(const std::string &key, int32_t value)
742 {
743 auto res = SetParameter(key.c_str(), std::to_string(value).c_str());
744 if (res < 0) {
745 AUDIO_WARNING_LOG("SetSysPara fail, key:%{public}s res:%{public}d", key.c_str(), res);
746 return false;
747 }
748 AUDIO_INFO_LOG("SetSysPara %{public}d success.", value);
749 return true;
750 }
751
752 template <typename T>
GetSysPara(const char * key,T & value)753 bool GetSysPara(const char *key, T &value)
754 {
755 CHECK_AND_RETURN_RET_LOG(key != nullptr, false, "key is nullptr");
756 char paraValue[30] = {0}; // 30 for system parameter
757 auto res = GetParameter(key, "-1", paraValue, sizeof(paraValue));
758
759 CHECK_AND_RETURN_RET_LOG(res > 0, false, "GetSysPara fail, key:%{public}s res:%{public}d", key, res);
760 AUDIO_DEBUG_LOG("key:%{public}s value:%{public}s", key, paraValue);
761 std::stringstream valueStr;
762 valueStr << paraValue;
763 valueStr >> value;
764 return true;
765 }
766
767 template bool GetSysPara(const char *key, int32_t &value);
768 template bool GetSysPara(const char *key, uint32_t &value);
769 template bool GetSysPara(const char *key, int64_t &value);
770 template bool GetSysPara(const char *key, std::string &value);
771
772 std::map<std::string, std::string> DumpFileUtil::g_lastPara = {};
773
OpenDumpFileInner(std::string para,std::string fileName,AudioDumpFileType fileType)774 FILE *DumpFileUtil::OpenDumpFileInner(std::string para, std::string fileName, AudioDumpFileType fileType)
775 {
776 std::string filePath;
777 switch (fileType) {
778 case AUDIO_APP:
779 filePath = DUMP_APP_DIR + fileName;
780 break;
781 case OTHER_NATIVE_SERVICE:
782 filePath = DUMP_SERVICE_DIR + fileName;
783 break;
784 case AUDIO_PULSE:
785 filePath = DUMP_PULSE_DIR + fileName;
786 break;
787 default:
788 AUDIO_ERR_LOG("Invalid AudioDumpFileType");
789 break;
790 }
791 std::string dumpPara;
792 FILE *dumpFile = nullptr;
793 bool res = GetSysPara(para.c_str(), dumpPara);
794 if (!res || dumpPara.empty()) {
795 AUDIO_INFO_LOG("%{public}s is not set, dump audio is not required", para.c_str());
796 g_lastPara[para] = dumpPara;
797 return dumpFile;
798 }
799 AUDIO_DEBUG_LOG("%{public}s = %{public}s", para.c_str(), dumpPara.c_str());
800 if (dumpPara == "w") {
801 dumpFile = fopen(filePath.c_str(), "wb+");
802 CHECK_AND_RETURN_RET_LOG(dumpFile != nullptr, dumpFile,
803 "Error opening pcm dump file:%{public}s", filePath.c_str());
804 } else if (dumpPara == "a") {
805 dumpFile = fopen(filePath.c_str(), "ab+");
806 CHECK_AND_RETURN_RET_LOG(dumpFile != nullptr, dumpFile,
807 "Error opening pcm dump file:%{public}s", filePath.c_str());
808 }
809 if (dumpFile != nullptr) {
810 AUDIO_INFO_LOG("Dump file path: %{public}s", filePath.c_str());
811 }
812 g_lastPara[para] = dumpPara;
813 return dumpFile;
814 }
815
WriteDumpFile(FILE * dumpFile,void * buffer,size_t bufferSize)816 void DumpFileUtil::WriteDumpFile(FILE *dumpFile, void *buffer, size_t bufferSize)
817 {
818 if (dumpFile == nullptr) {
819 return;
820 }
821 CHECK_AND_RETURN_LOG(buffer != nullptr, "Invalid write param");
822 size_t writeResult = fwrite(buffer, 1, bufferSize, dumpFile);
823 CHECK_AND_RETURN_LOG(writeResult == bufferSize, "Failed to write the file.");
824 }
825
CloseDumpFile(FILE ** dumpFile)826 void DumpFileUtil::CloseDumpFile(FILE **dumpFile)
827 {
828 if (*dumpFile) {
829 fclose(*dumpFile);
830 *dumpFile = nullptr;
831 }
832 }
833
ChangeDumpFileState(std::string para,FILE ** dumpFile,std::string filePath)834 void DumpFileUtil::ChangeDumpFileState(std::string para, FILE **dumpFile, std::string filePath)
835 {
836 CHECK_AND_RETURN_LOG(*dumpFile != nullptr, "Invalid file para");
837 CHECK_AND_RETURN_LOG(g_lastPara[para] == "w" || g_lastPara[para] == "a", "Invalid input para");
838 std::string dumpPara;
839 bool res = GetSysPara(para.c_str(), dumpPara);
840 if (!res || dumpPara.empty()) {
841 AUDIO_WARNING_LOG("get %{public}s fail", para.c_str());
842 }
843 if (g_lastPara[para] == "w" && dumpPara == "w") {
844 return;
845 }
846 CloseDumpFile(dumpFile);
847 OpenDumpFile(para, filePath, dumpFile);
848 }
849
OpenDumpFile(std::string para,std::string fileName,FILE ** file)850 void DumpFileUtil::OpenDumpFile(std::string para, std::string fileName, FILE **file)
851 {
852 if (*file != nullptr) {
853 DumpFileUtil::ChangeDumpFileState(para, file, fileName);
854 return;
855 }
856
857 if (para == DUMP_SERVER_PARA) {
858 *file = DumpFileUtil::OpenDumpFileInner(para, fileName, AUDIO_PULSE);
859 } else {
860 *file = DumpFileUtil::OpenDumpFileInner(para, fileName, AUDIO_APP);
861 if (*file == nullptr) {
862 *file = DumpFileUtil::OpenDumpFileInner(para, fileName, OTHER_NATIVE_SERVICE);
863 }
864 }
865 }
866
CloseFd(int fd)867 void CloseFd(int fd)
868 {
869 // log stdin, stdout, stderr.
870 if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) {
871 AUDIO_WARNING_LOG("special fd: %{public}d will be closed", fd);
872 }
873 int tmpFd = fd;
874 close(fd);
875 AUDIO_DEBUG_LOG("fd: %{public}d closed successfuly!", tmpFd);
876 }
877
MemcpyToI32FromI16(int16_t * src,int32_t * dst,size_t count)878 static void MemcpyToI32FromI16(int16_t *src, int32_t *dst, size_t count)
879 {
880 for (size_t i = 0; i < count; i++) {
881 *(dst + i) = static_cast<int32_t>(*(src + i));
882 }
883 }
884
MemcpyToI32FromI24(uint8_t * src,int32_t * dst,size_t count)885 static void MemcpyToI32FromI24(uint8_t *src, int32_t *dst, size_t count)
886 {
887 for (size_t i = 0; i < count; i++) {
888 uint8_t *tmp = src + 3 * i; // 3 is byte size of SAMPLE_S24LE;
889 *(dst + i) = static_cast<int32_t>(tmp[2] << (2 * sizeof(uint8_t))) |
890 static_cast<int32_t>(tmp[1] << sizeof(uint8_t)) | static_cast<int32_t>(tmp[0]);
891 }
892 }
893
NearZero(int16_t number)894 bool NearZero(int16_t number)
895 {
896 return number >= -DETECTED_ZERO_THRESHOLD && number <= DETECTED_ZERO_THRESHOLD;
897 }
898
GetTime()899 std::string GetTime()
900 {
901 std::string curTime;
902 struct timeval tv;
903 struct timezone tz;
904 struct tm *t;
905 gettimeofday(&tv, &tz);
906 t = localtime(&tv.tv_sec);
907 if (t == nullptr) {
908 return "";
909 }
910
911 curTime += std::to_string(YEAR_BASE + t->tm_year);
912 curTime += (1 + t->tm_mon < DECIMAL_EXPONENT ? "0" + std::to_string(1 + t->tm_mon) :
913 std::to_string(1 + t->tm_mon));
914 curTime += (t->tm_mday < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_mday) :
915 std::to_string(t->tm_mday));
916 curTime += (t->tm_hour < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_hour) :
917 std::to_string(t->tm_hour));
918 curTime += (t->tm_min < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_min) :
919 std::to_string(t->tm_min));
920 curTime += (t->tm_sec < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_sec) :
921 std::to_string(t->tm_sec));
922 int64_t mSec = static_cast<int64_t>(tv.tv_usec / AUDIO_MS_PER_SECOND);
923 curTime += (mSec < (DECIMAL_EXPONENT * DECIMAL_EXPONENT) ? (mSec < DECIMAL_EXPONENT ? "00" : "0")
924 + std::to_string(mSec) : std::to_string(mSec));
925 return curTime;
926 }
927
GetFormatByteSize(int32_t format)928 int32_t GetFormatByteSize(int32_t format)
929 {
930 int32_t formatByteSize;
931 switch (format) {
932 case SAMPLE_S16LE:
933 formatByteSize = 2; // size is 2
934 break;
935 case SAMPLE_S24LE:
936 formatByteSize = 3; // size is 3
937 break;
938 case SAMPLE_S32LE:
939 formatByteSize = 4; // size is 4
940 break;
941 default:
942 formatByteSize = 2; // size is 2
943 break;
944 }
945 return formatByteSize;
946 }
947
CheckAudioData(uint8_t * buffer,size_t bufferLen)948 bool SignalDetectAgent::CheckAudioData(uint8_t *buffer, size_t bufferLen)
949 {
950 CHECK_AND_RETURN_RET_LOG(formatByteSize_ != 0, false, "LatencyMeas checkAudioData failed, "
951 "formatByteSize_ %{public}d", formatByteSize_);
952 frameCountIgnoreChannel_ = bufferLen / static_cast<uint32_t>(formatByteSize_);
953 if (cacheAudioData_.capacity() < frameCountIgnoreChannel_) {
954 cacheAudioData_.clear();
955 cacheAudioData_.reserve(frameCountIgnoreChannel_);
956 }
957 int32_t *cache = cacheAudioData_.data();
958 if (sampleFormat_ == SAMPLE_S32LE) {
959 int32_t ret = memcpy_s(cache, sizeof(int32_t) * cacheAudioData_.capacity(), buffer, bufferLen);
960 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "LatencyMeas checkAudioData failed, dstSize "
961 "%{public}zu, srcSize %{public}zu", sizeof(int32_t) * cacheAudioData_.capacity(), bufferLen);
962 } else if (sampleFormat_ == SAMPLE_S24LE) {
963 MemcpyToI32FromI24(buffer, cache, frameCountIgnoreChannel_);
964 } else {
965 int16_t *cp = reinterpret_cast<int16_t*>(buffer);
966 MemcpyToI32FromI16(cp, cache, frameCountIgnoreChannel_);
967 }
968 if (DetectSignalData(cache, frameCountIgnoreChannel_)) {
969 ResetDetectResult();
970 return true;
971 }
972 return false;
973 }
974
DetectSignalData(int32_t * buffer,size_t bufferLen)975 bool SignalDetectAgent::DetectSignalData(int32_t *buffer, size_t bufferLen)
976 {
977 std::string curTime = GetTime();
978 uint32_t rightZeroSignal = 0;
979 int32_t currentPeakIndex = -1;
980 int32_t currentPeakSignal = SHRT_MIN;
981 bool hasNoneZero = false;
982 size_t frameCount = bufferLen / static_cast<size_t>(channels_);
983 for (size_t index = 0; index < frameCount; index++) {
984 int32_t tempMax = SHRT_MIN;
985 int32_t tempMin = SHRT_MAX;
986 for (uint32_t channel = 0; channel < static_cast<uint32_t>(channels_); channel++) {
987 int32_t temp = buffer[index * static_cast<uint32_t>(channels_) + channel];
988 tempMax = temp > tempMax ? temp : tempMax;
989 tempMin = temp < tempMin ? temp : tempMin;
990 }
991 if (!NearZero(tempMax) || !NearZero(tempMin)) {
992 rightZeroSignal = index + 1;
993 hasNoneZero = true;
994 if (currentPeakIndex == -1 || tempMax > currentPeakSignal) {
995 currentPeakIndex = static_cast<int32_t>(index);
996 currentPeakSignal = tempMax;
997 }
998 }
999 }
1000 if (!hasNoneZero) {
1001 blankPeriod_ += static_cast<int32_t>(frameCount);
1002 } else {
1003 if (!hasFirstNoneZero_) {
1004 lastPeakBufferTime_ = curTime;
1005 hasFirstNoneZero_ = true;
1006 }
1007 if (currentPeakSignal > lastPeakSignal_) {
1008 lastPeakSignal_ = currentPeakSignal;
1009 lastPeakSignalPos_ = currentPeakIndex;
1010 }
1011 blankHaveOutput_ = false;
1012 blankPeriod_ = static_cast<int32_t>(frameCount) - static_cast<int32_t>(rightZeroSignal);
1013 }
1014 int32_t thresholdBlankPeriod = BLANK_THRESHOLD_MS * sampleRate_ / MILLISECOND_PER_SECOND;
1015 if (blankPeriod_ > thresholdBlankPeriod) {
1016 return !blankHaveOutput_;
1017 }
1018 return false;
1019 }
1020
ResetDetectResult()1021 void SignalDetectAgent::ResetDetectResult()
1022 {
1023 blankHaveOutput_ = true;
1024 hasFirstNoneZero_ = false;
1025 lastPeakSignal_ = SHRT_MIN;
1026 signalDetected_ = true;
1027 dspTimestampGot_ = false;
1028 return;
1029 }
1030
MockPcmData(uint8_t * buffer,size_t bufferLen)1031 bool AudioLatencyMeasurement::MockPcmData(uint8_t *buffer, size_t bufferLen)
1032 {
1033 memset_s(buffer, bufferLen, 0, bufferLen);
1034 int16_t *signal = signalData_.get();
1035 size_t newlyMocked = bufferLen * MILLISECOND_PER_SECOND /
1036 static_cast<uint32_t>(channelCount_ * sampleRate_ * formatByteSize_);
1037 mockedTime_ += newlyMocked;
1038 if (mockedTime_ >= MOCK_INTERVAL) {
1039 mockedTime_ = 0;
1040 if (format_ == SAMPLE_S32LE) {
1041 MemcpyToI32FromI16(signal, reinterpret_cast<int32_t*>(buffer), SIGNAL_DATA_SIZE);
1042 } else {
1043 int32_t ret = memcpy_s(buffer, bufferLen, signal, SIGNAL_DATA_SIZE * sizeof(uint8_t));
1044 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "LatencyMeas mockPcmData failed, dstSize "
1045 "%{public}zu, srcSize %{public}zu", bufferLen, SIGNAL_DATA_SIZE * sizeof(uint8_t));
1046 }
1047 return true;
1048 }
1049 return false;
1050 }
1051
AudioLatencyMeasurement(const int32_t & sampleRate,const int32_t & channelCount,const int32_t & sampleFormat,const std::string & appName,const uint32_t & sessionId)1052 AudioLatencyMeasurement::AudioLatencyMeasurement(const int32_t &sampleRate,
1053 const int32_t &channelCount, const int32_t &sampleFormat,
1054 const std::string &appName, const uint32_t &sessionId)
1055 :format_(sampleFormat),
1056 sampleRate_(sampleRate),
1057 channelCount_(channelCount),
1058 sessionId_(sessionId),
1059 appName_(appName)
1060 {
1061 std::string appToMock = "com.example.null";
1062 GetSysPara("persist.multimedia.apptomock", appToMock);
1063 AUDIO_INFO_LOG("LatencyMeas appName:%{public}s, appToMock:%{public}s, g_sessionId:%{public}u",
1064 appName.c_str(), appToMock.c_str(), g_sessionToMock);
1065 if (appToMock == appName && g_sessionToMock == 0) {
1066 mockThisStream_ = true;
1067 g_sessionToMock = sessionId;
1068 }
1069 formatByteSize_ = GetFormatByteSize(sampleFormat);
1070 InitSignalData();
1071 }
1072
~AudioLatencyMeasurement()1073 AudioLatencyMeasurement::~AudioLatencyMeasurement()
1074 {
1075 if (mockThisStream_ && g_sessionToMock == sessionId_) {
1076 g_sessionToMock = 0;
1077 }
1078 }
1079
InitSignalData()1080 void AudioLatencyMeasurement::InitSignalData()
1081 {
1082 signalData_ = std::make_unique<int16_t[]>(SIGNAL_DATA_SIZE);
1083 memset_s(signalData_.get(), SIGNAL_DATA_SIZE, 0, SIGNAL_DATA_SIZE);
1084 const int16_t channels = 2; // 2 channels
1085 const int16_t samplePerChannel = SIGNAL_DATA_SIZE / channels;
1086 int16_t *signalBuffer = signalData_.get();
1087 for (int16_t index = 0; index < samplePerChannel; index++) {
1088 signalBuffer[index * channels] = SIGNAL_THRESHOLD + static_cast<int16_t>(sinf(2.0f *
1089 static_cast<float>(M_PI) * index / samplePerChannel) * (SHRT_MAX - SIGNAL_THRESHOLD));
1090 for (int16_t k = 1; k < channels; k++) {
1091 signalBuffer[channels * index + k] = signalBuffer[channels * index];
1092 }
1093 }
1094 AUDIO_INFO_LOG("LatencyMeas signalData inited");
1095 return;
1096 }
1097
CheckIfEnabled()1098 bool AudioLatencyMeasurement::CheckIfEnabled()
1099 {
1100 int32_t latencyMeasure = -1;
1101 GetSysPara("persist.multimedia.audiolatency", latencyMeasure);
1102 return (latencyMeasure == 1);
1103 }
1104
GetInstance()1105 LatencyMonitor& LatencyMonitor::GetInstance()
1106 {
1107 static LatencyMonitor latencyMonitor_;
1108 return latencyMonitor_;
1109 }
1110
UpdateClientTime(bool isRenderer,std::string & timestamp)1111 void LatencyMonitor::UpdateClientTime(bool isRenderer, std::string ×tamp)
1112 {
1113 if (isRenderer) {
1114 rendererMockTime_ = timestamp;
1115 } else {
1116 capturerDetectedTime_ = timestamp;
1117 }
1118 }
1119
UpdateSinkOrSourceTime(bool isRenderer,std::string & timestamp)1120 void LatencyMonitor::UpdateSinkOrSourceTime(bool isRenderer, std::string ×tamp)
1121 {
1122 if (isRenderer) {
1123 sinkDetectedTime_ = timestamp;
1124 } else {
1125 sourceDetectedTime_ = timestamp;
1126 }
1127 }
1128
UpdateDspTime(std::string timestamp)1129 void LatencyMonitor::UpdateDspTime(std::string timestamp)
1130 {
1131 dspDetectedTime_ = timestamp;
1132 }
1133
ShowTimestamp(bool isRenderer)1134 void LatencyMonitor::ShowTimestamp(bool isRenderer)
1135 {
1136 if (extraStrLen_ == 0) {
1137 extraStrLen_ = dspDetectedTime_.find("20");
1138 }
1139 if (isRenderer) {
1140 if (dspDetectedTime_.length() == 0) {
1141 AUDIO_ERR_LOG("LatencyMeas GetExtraParameter failed!");
1142 AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, SinkDetectedTime:%{public}s",
1143 rendererMockTime_.c_str(), sinkDetectedTime_.c_str());
1144 return;
1145 }
1146 dspBeforeSmartPa_ = dspDetectedTime_.substr(extraStrLen_, DATE_LENGTH);
1147 dspAfterSmartPa_ = dspDetectedTime_.substr(extraStrLen_ + DATE_LENGTH + 1 +
1148 extraStrLen_, DATE_LENGTH);
1149 AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, SinkDetectedTime:%{public}s, "
1150 "DspBeforeSmartPa:%{public}s, DspAfterSmartPa:%{public}s", rendererMockTime_.c_str(),
1151 sinkDetectedTime_.c_str(), dspBeforeSmartPa_.c_str(), dspAfterSmartPa_.c_str());
1152 } else {
1153 if (dspDetectedTime_.length() == 0) {
1154 AUDIO_ERR_LOG("LatencyMeas GetExtraParam failed!");
1155 AUDIO_INFO_LOG("LatencyMeas CapturerDetectedTime:%{public}s, SourceDetectedTime:%{public}s",
1156 capturerDetectedTime_.c_str(), sourceDetectedTime_.c_str());
1157 return;
1158 }
1159 dspMockTime_ = dspDetectedTime_.substr(extraStrLen_ + DATE_LENGTH + extraStrLen_ + 1 +
1160 DATE_LENGTH + extraStrLen_ + 1, DATE_LENGTH);
1161 AUDIO_INFO_LOG("LatencyMeas CapturerDetectedTime:%{public}s, SourceDetectedTime:%{public}s, "
1162 "DspMockTime:%{public}s", capturerDetectedTime_.c_str(), sourceDetectedTime_.c_str(),
1163 dspMockTime_.c_str());
1164 }
1165 }
1166
ShowBluetoothTimestamp()1167 void LatencyMonitor::ShowBluetoothTimestamp()
1168 {
1169 AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, BTSinkDetectedTime:%{public}s",
1170 rendererMockTime_.c_str(), sinkDetectedTime_.c_str());
1171 }
1172
GetStreamName(AudioStreamType streamType)1173 const std::string AudioInfoDumpUtils::GetStreamName(AudioStreamType streamType)
1174 {
1175 std::string name;
1176 std::unordered_map<AudioStreamType, std::string> map = STREAM_TYPE_NAME_MAP;
1177 auto it = map.find(streamType);
1178 if (it != map.end()) {
1179 name = it->second;
1180 } else {
1181 name = "UNKNOWN";
1182 }
1183
1184 const std::string streamName = name;
1185 return streamName;
1186 }
1187
GetDeviceTypeName(DeviceType deviceType)1188 const std::string AudioInfoDumpUtils::GetDeviceTypeName(DeviceType deviceType)
1189 {
1190 std::string device;
1191 switch (deviceType) {
1192 case DEVICE_TYPE_EARPIECE:
1193 device = "EARPIECE";
1194 break;
1195 case DEVICE_TYPE_SPEAKER:
1196 device = "SPEAKER";
1197 break;
1198 case DEVICE_TYPE_WIRED_HEADSET:
1199 device = "WIRED_HEADSET";
1200 break;
1201 case DEVICE_TYPE_WIRED_HEADPHONES:
1202 device = "WIRED_HEADPHONES";
1203 break;
1204 case DEVICE_TYPE_BLUETOOTH_SCO:
1205 device = "BLUETOOTH_SCO";
1206 break;
1207 case DEVICE_TYPE_BLUETOOTH_A2DP:
1208 device = "BLUETOOTH_A2DP";
1209 break;
1210 case DEVICE_TYPE_MIC:
1211 device = "MIC";
1212 break;
1213 case DEVICE_TYPE_WAKEUP:
1214 device = "WAKEUP";
1215 break;
1216 case DEVICE_TYPE_NONE:
1217 device = "NONE";
1218 break;
1219 case DEVICE_TYPE_INVALID:
1220 device = "INVALID";
1221 break;
1222 default:
1223 device = "UNKNOWN";
1224 }
1225
1226 const std::string deviceTypeName = device;
1227 return deviceTypeName;
1228 }
1229
GetConnectTypeName(ConnectType connectType)1230 const std::string AudioInfoDumpUtils::GetConnectTypeName(ConnectType connectType)
1231 {
1232 std::string connectName;
1233 switch (connectType) {
1234 case OHOS::AudioStandard::CONNECT_TYPE_LOCAL:
1235 connectName = "LOCAL";
1236 break;
1237 case OHOS::AudioStandard::CONNECT_TYPE_DISTRIBUTED:
1238 connectName = "REMOTE";
1239 break;
1240 default:
1241 connectName = "UNKNOWN";
1242 break;
1243 }
1244 const std::string connectTypeName = connectName;
1245 return connectTypeName;
1246 }
1247
GetSourceName(SourceType sourceType)1248 const std::string AudioInfoDumpUtils::GetSourceName(SourceType sourceType)
1249 {
1250 std::string name;
1251 switch (sourceType) {
1252 case SOURCE_TYPE_INVALID:
1253 name = "INVALID";
1254 break;
1255 case SOURCE_TYPE_MIC:
1256 name = "MIC";
1257 break;
1258 case SOURCE_TYPE_CAMCORDER:
1259 name = "CAMCORDER";
1260 break;
1261 case SOURCE_TYPE_VOICE_RECOGNITION:
1262 name = "VOICE_RECOGNITION";
1263 break;
1264 case SOURCE_TYPE_ULTRASONIC:
1265 name = "ULTRASONIC";
1266 break;
1267 case SOURCE_TYPE_VOICE_COMMUNICATION:
1268 name = "VOICE_COMMUNICATION";
1269 break;
1270 case SOURCE_TYPE_WAKEUP:
1271 name = "WAKEUP";
1272 break;
1273 case SOURCE_TYPE_UNPROCESSED:
1274 name = "SOURCE_TYPE_UNPROCESSED";
1275 break;
1276 default:
1277 name = "UNKNOWN";
1278 }
1279
1280 const std::string sourceName = name;
1281 return sourceName;
1282 }
1283
GetDeviceVolumeTypeName(DeviceVolumeType deviceType)1284 const std::string AudioInfoDumpUtils::GetDeviceVolumeTypeName(DeviceVolumeType deviceType)
1285 {
1286 std::string device;
1287 switch (deviceType) {
1288 case EARPIECE_VOLUME_TYPE:
1289 device = "EARPIECE";
1290 break;
1291 case SPEAKER_VOLUME_TYPE:
1292 device = "SPEAKER";
1293 break;
1294 case HEADSET_VOLUME_TYPE:
1295 device = "HEADSET";
1296 break;
1297 default:
1298 device = "UNKNOWN";
1299 }
1300
1301 const std::string deviceTypeName = device;
1302 return deviceTypeName;
1303 }
1304
1305 std::unordered_map<AudioStreamType, AudioVolumeType> VolumeUtils::defaultVolumeMap_ = {
1306 {STREAM_VOICE_CALL, STREAM_VOICE_CALL},
1307 {STREAM_VOICE_MESSAGE, STREAM_VOICE_CALL},
1308 {STREAM_VOICE_COMMUNICATION, STREAM_VOICE_CALL},
1309 {STREAM_VOICE_CALL_ASSISTANT, STREAM_VOICE_CALL_ASSISTANT},
1310
1311 {STREAM_RING, STREAM_RING},
1312 {STREAM_SYSTEM, STREAM_RING},
1313 {STREAM_NOTIFICATION, STREAM_RING},
1314 {STREAM_SYSTEM_ENFORCED, STREAM_RING},
1315 {STREAM_DTMF, STREAM_RING},
1316 {STREAM_VOICE_RING, STREAM_RING},
1317
1318 {STREAM_MUSIC, STREAM_MUSIC},
1319 {STREAM_MEDIA, STREAM_MUSIC},
1320 {STREAM_MOVIE, STREAM_MUSIC},
1321 {STREAM_GAME, STREAM_MUSIC},
1322 {STREAM_SPEECH, STREAM_MUSIC},
1323 {STREAM_NAVIGATION, STREAM_MUSIC},
1324 {STREAM_CAMCORDER, STREAM_MUSIC},
1325
1326 {STREAM_VOICE_ASSISTANT, STREAM_VOICE_ASSISTANT},
1327 {STREAM_ALARM, STREAM_ALARM},
1328 {STREAM_ACCESSIBILITY, STREAM_ACCESSIBILITY},
1329 {STREAM_ULTRASONIC, STREAM_ULTRASONIC},
1330 {STREAM_ALL, STREAM_ALL},
1331 };
1332
GetVolumeMap()1333 std::unordered_map<AudioStreamType, AudioVolumeType>& VolumeUtils::GetVolumeMap()
1334 {
1335 return defaultVolumeMap_;
1336 }
1337
GetVolumeTypeFromStreamType(AudioStreamType streamType)1338 AudioVolumeType VolumeUtils::GetVolumeTypeFromStreamType(AudioStreamType streamType)
1339 {
1340 std::unordered_map<AudioStreamType, AudioVolumeType> map = GetVolumeMap();
1341 auto it = map.find(streamType);
1342 if (it != map.end()) {
1343 return it->second;
1344 }
1345 return STREAM_MUSIC;
1346 }
1347
GetEncryptStr(const std::string & src)1348 std::string GetEncryptStr(const std::string &src)
1349 {
1350 if (src.empty()) {
1351 return std::string("");
1352 }
1353
1354 size_t strLen = src.length();
1355 std::string dst;
1356
1357 if (strLen < MIN_LEN) {
1358 // src: abcdef
1359 // dst: *bcdef
1360 dst = '*' + src.substr(FIRST_CHAR, strLen - FIRST_CHAR);
1361 } else {
1362 // src: 00:00:00:00:00:00
1363 // dst: 00**********00:00
1364 dst = src.substr(0, HEAD_STR_LEN);
1365 std::string tempStr(strLen - HEAD_STR_LEN - TAIL_STR_LEN, '*');
1366 dst += tempStr;
1367 dst += src.substr(strLen - TAIL_STR_LEN, TAIL_STR_LEN);
1368 }
1369
1370 return dst;
1371 }
1372
ConvertNetworkId(const std::string & networkId)1373 std::string ConvertNetworkId(const std::string &networkId)
1374 {
1375 if (!networkId.empty() && networkId != LOCAL_NETWORK_ID) {
1376 return REMOTE_NETWORK_ID;
1377 }
1378
1379 return networkId;
1380 }
1381
GenerateUniqueID(AudioHdiUniqueIDBase base,uint32_t offset)1382 uint32_t GenerateUniqueID(AudioHdiUniqueIDBase base, uint32_t offset)
1383 {
1384 return base + offset * UNIQUE_ID_INTERVAL;
1385 }
1386
GetInstance()1387 AudioDump& AudioDump::GetInstance()
1388 {
1389 static AudioDump mAudioDump;
1390 return mAudioDump;
1391 }
1392
SetVersionType(const std::string & versionType)1393 void AudioDump::SetVersionType(const std::string& versionType)
1394 {
1395 versionType_ = versionType;
1396 }
1397
GetVersionType()1398 std::string AudioDump::GetVersionType()
1399 {
1400 return versionType_;
1401 }
1402 } // namespace AudioStandard
1403 } // namespace OHOS
1404
1405 #ifdef __cplusplus
1406 extern "C" {
1407 #endif
1408
1409 struct CTrace {
CTraceCTrace1410 explicit CTrace(const char *traceName) : trace(OHOS::AudioStandard::Trace(traceName)) {};
1411 OHOS::AudioStandard::Trace trace;
1412 };
1413
GetAndStart(const char * traceName)1414 CTrace *GetAndStart(const char *traceName)
1415 {
1416 std::unique_ptr<CTrace> cTrace = std::make_unique<CTrace>(traceName);
1417
1418 return cTrace.release();
1419 }
1420
EndCTrace(CTrace * cTrace)1421 void EndCTrace(CTrace *cTrace)
1422 {
1423 if (cTrace != nullptr) {
1424 cTrace->trace.End();
1425 }
1426 }
1427
CTraceCount(const char * traceName,int64_t count)1428 void CTraceCount(const char *traceName, int64_t count)
1429 {
1430 OHOS::AudioStandard::Trace::Count(traceName, count);
1431 }
1432
CallEndAndClear(CTrace ** cTrace)1433 void CallEndAndClear(CTrace **cTrace)
1434 {
1435 if (cTrace != nullptr && *cTrace != nullptr) {
1436 EndCTrace(*cTrace);
1437 delete *cTrace;
1438 *cTrace = nullptr;
1439 }
1440 }
1441
1442 #ifdef __cplusplus
1443 }
1444 #endif
1445