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