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