• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &timestamp)
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 &timestamp)
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