• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 <thread>
26 #include <string>
27 #include "audio_utils_c.h"
28 #include "audio_errors.h"
29 #include "audio_common_log.h"
30 #ifdef FEATURE_HITRACE_METER
31 #include "hitrace_meter.h"
32 #endif
33 #include "bundle_mgr_interface.h"
34 #include "parameter.h"
35 #include "tokenid_kit.h"
36 #include "ipc_skeleton.h"
37 #include "iservice_registry.h"
38 #include "access_token.h"
39 #include "accesstoken_kit.h"
40 #include "privacy_kit.h"
41 #include "xcollie/xcollie.h"
42 #include "xcollie/xcollie_define.h"
43 #include "securec.h"
44 #include "privacy_error.h"
45 
46 using OHOS::Security::AccessToken::AccessTokenKit;
47 
48 namespace OHOS {
49 namespace AudioStandard {
50 namespace {
51 const int32_t YEAR_BASE = 1900;
52 const size_t MOCK_INTERVAL = 2000;
53 const int32_t DETECTED_ZERO_THRESHOLD = 1;
54 const int32_t BLANK_THRESHOLD_MS = 100;
55 const int32_t SIGNAL_THRESHOLD = 10;
56 const uint32_t MAX_VALUE_OF_SIGNED_24_BIT = 8388607;
57 const int64_t PCM_MAYBE_SILENT = 1;
58 const int64_t PCM_MAYBE_NOT_SILENT = 5;
59 const int32_t SIGNAL_DATA_SIZE = 96;
60 const int32_t DECIMAL_EXPONENT = 10;
61 const size_t DATE_LENGTH = 17;
62 static uint32_t g_sessionToMock = 0;
63 constexpr int32_t UID_AUDIO = 1041;
64 constexpr int32_t UID_MSDP_SA = 6699;
65 constexpr int32_t UID_INTELLIGENT_VOICE_SA = 1042;
66 constexpr int32_t UID_CAAS_SA = 5527;
67 constexpr int32_t UID_DISTRIBUTED_AUDIO_SA = 3055;
68 constexpr int32_t UID_TELEPHONY_SA = 1001;
69 constexpr int32_t UID_THPEXTRA_SA = 5000;
70 constexpr int32_t TIME_OUT_SECONDS = 10;
71 constexpr int32_t BOOTUP_MUSIC_UID = 1003;
72 
73 const uint32_t UNIQUE_ID_INTERVAL = 8;
74 
75 constexpr size_t FIRST_CHAR = 1;
76 constexpr size_t MIN_LEN = 8;
77 constexpr size_t HEAD_STR_LEN = 2;
78 constexpr size_t TAIL_STR_LEN = 5;
79 
80 const int32_t DATA_INDEX_0 = 0;
81 const int32_t DATA_INDEX_1 = 1;
82 const int32_t DATA_INDEX_2 = 2;
83 const int32_t DATA_INDEX_3 = 3;
84 const int32_t DATA_INDEX_4 = 4;
85 const int32_t DATA_INDEX_5 = 5;
86 const int32_t STEREO_CHANNEL_COUNT = 2;
87 const int BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
88 
89 const char* DUMP_PULSE_DIR = "/data/data/.pulse_dir/";
90 const char* DUMP_SERVICE_DIR = "/data/local/tmp/";
91 const char* DUMP_APP_DIR = "/data/storage/el2/base/cache/";
92 
93 
94 const std::set<int32_t> RECORD_ALLOW_BACKGROUND_LIST = {
95 #ifdef AUDIO_BUILD_VARIANT_ROOT
96     0, // UID_ROOT
97 #endif
98     UID_MSDP_SA,
99     UID_INTELLIGENT_VOICE_SA,
100     UID_CAAS_SA,
101     UID_DISTRIBUTED_AUDIO_SA,
102     UID_THPEXTRA_SA,
103     UID_TELEPHONY_SA // used in distributed communication call
104 };
105 
106 const std::set<SourceType> NO_BACKGROUND_CHECK_SOURCE_TYPE = {
107     SOURCE_TYPE_PLAYBACK_CAPTURE,
108     SOURCE_TYPE_VOICE_CALL,
109     SOURCE_TYPE_REMOTE_CAST
110 };
111 } // namespace
112 
113 static std::unordered_map<AudioStreamType, std::string> STREAM_TYPE_NAME_MAP = {
114     {STREAM_VOICE_ASSISTANT, "VOICE_ASSISTANT"},
115     {STREAM_VOICE_CALL, "VOICE_CALL"},
116     {STREAM_SYSTEM, "SYSTEM"},
117     {STREAM_RING, "RING"},
118     {STREAM_MUSIC, "MUSIC"},
119     {STREAM_ALARM, "ALARM"},
120     {STREAM_NOTIFICATION, "NOTIFICATION"},
121     {STREAM_BLUETOOTH_SCO, "BLUETOOTH_SCO"},
122     {STREAM_DTMF, "DTMF"},
123     {STREAM_TTS, "TTS"},
124     {STREAM_ACCESSIBILITY, "ACCESSIBILITY"},
125     {STREAM_ULTRASONIC, "ULTRASONIC"},
126     {STREAM_WAKEUP, "WAKEUP"},
127     {STREAM_CAMCORDER, "CAMCORDER"},
128     {STREAM_ENFORCED_AUDIBLE, "ENFORCED_AUDIBLE"},
129     {STREAM_MOVIE, "MOVIE"},
130     {STREAM_GAME, "GAME"},
131     {STREAM_SPEECH, "SPEECH"},
132     {STREAM_SYSTEM_ENFORCED, "SYSTEM_ENFORCED"},
133     {STREAM_VOICE_MESSAGE, "VOICE_MESSAGE"},
134     {STREAM_NAVIGATION, "NAVIGATION"},
135     {STREAM_INTERNAL_FORCE_STOP, "INTERNAL_FORCE_STOP"},
136     {STREAM_SOURCE_VOICE_CALL, "SOURCE_VOICE_CALL"},
137     {STREAM_VOICE_COMMUNICATION, "VOICE_COMMUNICATION"},
138     {STREAM_VOICE_RING, "VOICE_RING"},
139     {STREAM_VOICE_CALL_ASSISTANT, "VOICE_CALL_ASSISTANT"},
140 };
141 
GetSamplePerFrame(const AudioSampleFormat & format)142 uint32_t Util::GetSamplePerFrame(const AudioSampleFormat &format)
143 {
144     uint32_t audioPerSampleLength = 2; // 2 byte
145     switch (format) {
146         case AudioSampleFormat::SAMPLE_U8:
147             audioPerSampleLength = 1;
148             break;
149         case AudioSampleFormat::SAMPLE_S16LE:
150             audioPerSampleLength = 2; // 2 byte
151             break;
152         case AudioSampleFormat::SAMPLE_S24LE:
153             audioPerSampleLength = 3; // 3 byte
154             break;
155         case AudioSampleFormat::SAMPLE_S32LE:
156         case AudioSampleFormat::SAMPLE_F32LE:
157             audioPerSampleLength = 4; // 4 byte
158             break;
159         default:
160             break;
161     }
162     return audioPerSampleLength;
163 }
164 
IsScoSupportSource(const SourceType sourceType)165 bool Util::IsScoSupportSource(const SourceType sourceType)
166 {
167     return sourceType == SOURCE_TYPE_VOICE_RECOGNITION || sourceType == SOURCE_TYPE_VOICE_TRANSCRIPTION;
168 }
169 
IsDualToneStreamType(const AudioStreamType streamType)170 bool Util::IsDualToneStreamType(const AudioStreamType streamType)
171 {
172     return streamType == STREAM_RING || streamType == STREAM_VOICE_RING || streamType == STREAM_ALARM;
173 }
174 
IsRingerOrAlarmerStreamUsage(const StreamUsage & usage)175 bool Util::IsRingerOrAlarmerStreamUsage(const StreamUsage &usage)
176 {
177     return usage == STREAM_USAGE_ALARM || usage == STREAM_USAGE_VOICE_RINGTONE || usage == STREAM_USAGE_RINGTONE;
178 }
179 
IsRingerAudioScene(const AudioScene & audioScene)180 bool Util::IsRingerAudioScene(const AudioScene &audioScene)
181 {
182     return audioScene == AUDIO_SCENE_RINGING || audioScene == AUDIO_SCENE_VOICE_RINGING;
183 }
184 
WatchTimeout(const std::string & funcName,int64_t timeoutNs)185 WatchTimeout::WatchTimeout(const std::string &funcName, int64_t timeoutNs) : funcName_(funcName), timeoutNs_(timeoutNs)
186 {
187     startTimeNs_ = ClockTime::GetCurNano();
188 }
189 
~WatchTimeout()190 WatchTimeout::~WatchTimeout()
191 {
192     if (!isChecked_) {
193         CheckCurrTimeout();
194     }
195 }
196 
CheckCurrTimeout()197 void WatchTimeout::CheckCurrTimeout()
198 {
199     int64_t cost = ClockTime::GetCurNano() - startTimeNs_;
200     if (cost > timeoutNs_) {
201         AUDIO_WARNING_LOG("[%{public}s] cost %{public}" PRId64"ms!", funcName_.c_str(), cost / AUDIO_US_PER_SECOND);
202     }
203     isChecked_ = true;
204 }
205 
CheckoutSystemApp(int32_t uid)206 bool CheckoutSystemAppUtil::CheckoutSystemApp(int32_t uid)
207 {
208     if (uid == BOOTUP_MUSIC_UID) {
209         // boot animation must be system app, no need query from BMS, to redeuce boot latency.
210         AUDIO_INFO_LOG("boot animation must be system app, no need query from BMS.");
211         return true;
212     }
213     bool isSystemApp = false;
214     WatchTimeout guard("SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager():CheckoutSystemApp");
215     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
216     CHECK_AND_RETURN_RET_LOG(systemAbilityManager != nullptr, false, "systemAbilityManager is nullptr");
217     guard.CheckCurrTimeout();
218     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
219     CHECK_AND_RETURN_RET_LOG(remoteObject != nullptr, false, "remoteObject is nullptr");
220     sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
221     CHECK_AND_RETURN_RET_LOG(bundleMgrProxy != nullptr, false, "bundleMgrProxy is nullptr");
222     WatchTimeout reguard("bundleMgrProxy->CheckIsSystemAppByUid:CheckoutSystemApp");
223     isSystemApp = bundleMgrProxy->CheckIsSystemAppByUid(uid);
224     reguard.CheckCurrTimeout();
225     return isSystemApp;
226 }
227 
GetCurNano()228 int64_t ClockTime::GetCurNano()
229 {
230     int64_t result = -1; // -1 for bad result.
231     struct timespec time;
232     clockid_t clockId = CLOCK_MONOTONIC;
233     int ret = clock_gettime(clockId, &time);
234     CHECK_AND_RETURN_RET_LOG(ret >= 0, result,
235         "GetCurNanoTime fail, result:%{public}d", ret);
236     result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
237     return result;
238 }
239 
GetRealNano()240 int64_t ClockTime::GetRealNano()
241 {
242     int64_t result = -1; // -1 for bad result
243     struct timespec time;
244     clockid_t clockId = CLOCK_REALTIME;
245     int ret = clock_gettime(clockId, &time);
246     CHECK_AND_RETURN_RET_LOG(ret >= 0, result,
247         "GetRealNanotime fail, result:%{public}d", ret);
248     result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
249     return result;
250 }
251 
AbsoluteSleep(int64_t nanoTime)252 int32_t ClockTime::AbsoluteSleep(int64_t nanoTime)
253 {
254     int32_t ret = -1; // -1 for bad result.
255     CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
256         "AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
257     struct timespec time;
258     time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
259     time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
260 
261     clockid_t clockId = CLOCK_MONOTONIC;
262     ret = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
263     if (ret != 0) {
264         AUDIO_WARNING_LOG("AbsoluteSleep may failed, ret is :%{public}d", ret);
265     }
266 
267     return ret;
268 }
269 
NanoTimeToString(int64_t nanoTime)270 std::string ClockTime::NanoTimeToString(int64_t nanoTime)
271 {
272     struct tm *tm_info;
273     char buffer[80];
274     time_t time_seconds = nanoTime / AUDIO_NS_PER_SECOND;
275 
276     tm_info = localtime(&time_seconds);
277     if (tm_info == NULL) {
278         AUDIO_ERR_LOG("get localtime failed!");
279         return "";
280     }
281 
282     size_t res = strftime(buffer, sizeof(buffer), "%H:%M:%S", tm_info);
283     CHECK_AND_RETURN_RET_LOG(res != 0, "", "strftime failed!");
284     return std::string(buffer);
285 }
286 
RelativeSleep(int64_t nanoTime)287 int32_t ClockTime::RelativeSleep(int64_t nanoTime)
288 {
289     int32_t ret = -1; // -1 for bad result.
290     CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
291         "AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
292     struct timespec time;
293     time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
294     time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
295 
296     clockid_t clockId = CLOCK_MONOTONIC;
297     const int relativeFlag = 0; // flag of relative sleep.
298     ret = clock_nanosleep(clockId, relativeFlag, &time, nullptr);
299     if (ret != 0) {
300         AUDIO_WARNING_LOG("RelativeSleep may failed, ret is :%{public}d", ret);
301     }
302 
303     return ret;
304 }
305 
Count(const std::string & value,int64_t count)306 void Trace::Count(const std::string &value, int64_t count)
307 {
308 #ifdef FEATURE_HITRACE_METER
309     CountTrace(HITRACE_TAG_ZAUDIO, value, count);
310 #endif
311 }
312 
CountVolume(const std::string & value,uint8_t data)313 void Trace::CountVolume(const std::string &value, uint8_t data)
314 {
315 #ifdef FEATURE_HITRACE_METER
316     if (data == 0) {
317         CountTrace(HITRACE_TAG_ZAUDIO, value, PCM_MAYBE_SILENT);
318     } else {
319         CountTrace(HITRACE_TAG_ZAUDIO, value, PCM_MAYBE_NOT_SILENT);
320     }
321 #endif
322 }
323 
Trace(const std::string & value)324 Trace::Trace(const std::string &value)
325 {
326     value_ = value;
327     isFinished_ = false;
328 #ifdef FEATURE_HITRACE_METER
329     StartTrace(HITRACE_TAG_ZAUDIO, value_);
330 #endif
331 }
332 
End()333 void Trace::End()
334 {
335 #ifdef FEATURE_HITRACE_METER
336     if (!isFinished_) {
337         FinishTrace(HITRACE_TAG_ZAUDIO);
338         isFinished_ = true;
339     }
340 #endif
341 }
342 
~Trace()343 Trace::~Trace()
344 {
345     End();
346 }
347 
AudioXCollie(const std::string & tag,uint32_t timeoutSeconds,std::function<void (void *)> func,void * arg,uint32_t flag)348 AudioXCollie::AudioXCollie(const std::string &tag, uint32_t timeoutSeconds,
349     std::function<void(void *)> func, void *arg, uint32_t flag)
350 {
351     AUDIO_DEBUG_LOG("Start AudioXCollie, tag: %{public}s, timeoutSeconds: %{public}u, flag: %{public}u",
352         tag.c_str(), timeoutSeconds, flag);
353     id_ = HiviewDFX::XCollie::GetInstance().SetTimer(tag, timeoutSeconds, func, arg, flag);
354     tag_ = tag;
355     isCanceled_ = false;
356 }
357 
~AudioXCollie()358 AudioXCollie::~AudioXCollie()
359 {
360     CancelXCollieTimer();
361 }
362 
CancelXCollieTimer()363 void AudioXCollie::CancelXCollieTimer()
364 {
365     if (!isCanceled_) {
366         HiviewDFX::XCollie::GetInstance().CancelTimer(id_);
367         isCanceled_ = true;
368         AUDIO_DEBUG_LOG("CancelXCollieTimer: cancel timer %{public}s", tag_.c_str());
369     }
370 }
371 
VerifyIsShell()372 bool PermissionUtil::VerifyIsShell()
373 {
374     auto tokenId = IPCSkeleton::GetCallingTokenID();
375     auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
376     if (tokenTypeFlag == Security::AccessToken::TOKEN_SHELL) {
377         return true;
378     }
379     return false;
380 }
381 
VerifyIsAudio()382 bool PermissionUtil::VerifyIsAudio()
383 {
384     int32_t callingUid = IPCSkeleton::GetCallingUid();
385     if (UID_AUDIO == callingUid) {
386         return true;
387     }
388 #ifdef AUDIO_BUILD_VARIANT_ROOT
389     if (callingUid == 0) {
390         AUDIO_WARNING_LOG("Root calling!");
391         return true;
392     }
393 #endif
394     return false;
395 }
396 
VerifyIsSystemApp()397 bool PermissionUtil::VerifyIsSystemApp()
398 {
399     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
400     bool tmp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
401     CHECK_AND_RETURN_RET(!tmp, true);
402 
403     AUDIO_PRERELEASE_LOGE("Check system app permission reject");
404     return false;
405 }
406 
VerifySelfPermission()407 bool PermissionUtil::VerifySelfPermission()
408 {
409     Security::AccessToken::FullTokenID selfToken = IPCSkeleton::GetSelfTokenID();
410 
411     auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfToken));
412 
413     CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_NATIVE, true);
414 
415     CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_SHELL, true);
416 
417     bool tmp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken);
418     CHECK_AND_RETURN_RET(!tmp, true);
419 
420     AUDIO_ERR_LOG("Check self app permission reject");
421     return false;
422 }
423 
VerifySystemPermission()424 bool PermissionUtil::VerifySystemPermission()
425 {
426     auto tokenId = IPCSkeleton::GetCallingTokenID();
427     auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
428 
429     CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_NATIVE, true);
430 #ifdef AUDIO_BUILD_VARIANT_ROOT
431     CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_SHELL, true);
432 #endif
433     bool tmp = VerifyIsSystemApp();
434     CHECK_AND_RETURN_RET(!tmp, true);
435 
436     AUDIO_PRERELEASE_LOGE("Check system permission reject");
437     return false;
438 }
439 
VerifyPermission(const std::string & permissionName,uint32_t tokenId)440 bool PermissionUtil::VerifyPermission(const std::string &permissionName, uint32_t tokenId)
441 {
442     int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
443     CHECK_AND_RETURN_RET_LOG(res == Security::AccessToken::PermissionState::PERMISSION_GRANTED,
444         false, "Permission denied [%{public}s]", permissionName.c_str());
445 
446     return true;
447 }
448 
NeedVerifyBackgroundCapture(int32_t callingUid,SourceType sourceType)449 bool PermissionUtil::NeedVerifyBackgroundCapture(int32_t callingUid, SourceType sourceType)
450 {
451     if (RECORD_ALLOW_BACKGROUND_LIST.count(callingUid)) {
452         AUDIO_INFO_LOG("internal sa(%{public}d) user directly recording", callingUid);
453         return false;
454     }
455     if (NO_BACKGROUND_CHECK_SOURCE_TYPE.count(sourceType)) {
456         AUDIO_INFO_LOG("sourceType %{public}d", sourceType);
457         return false;
458     }
459     return true;
460 }
461 
VerifyBackgroundCapture(uint32_t tokenId,uint64_t fullTokenId)462 bool PermissionUtil::VerifyBackgroundCapture(uint32_t tokenId, uint64_t fullTokenId)
463 {
464     Trace trace("PermissionUtil::VerifyBackgroundCapture");
465     if (Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
466         AUDIO_INFO_LOG("system app recording");
467         return true;
468     }
469 
470     bool ret = Security::AccessToken::PrivacyKit::IsAllowedUsingPermission(tokenId, MICROPHONE_PERMISSION);
471     if (!ret) {
472         AUDIO_ERR_LOG("failed: not allowed!");
473     }
474     return ret;
475 }
476 
477 std::mutex g_switchMapMutex;
478 static std::map<SwitchStreamInfo, SwitchState> g_switchStreamRecordMap = {};
479 
IsSwitchStreamSwitching(SwitchStreamInfo & info,SwitchState targetState)480 bool SwitchStreamUtil::IsSwitchStreamSwitching(SwitchStreamInfo &info, SwitchState targetState)
481 {
482     std::lock_guard<std::mutex> lock(g_switchMapMutex);
483     auto iter = g_switchStreamRecordMap.find(info);
484     if (iter != g_switchStreamRecordMap.end() && targetState == SWITCH_STATE_CREATED &&
485         iter->second == SWITCH_STATE_WAITING && (info.nextState == CAPTURER_PREPARED)) {
486         AUDIO_INFO_LOG("stream:%{public}u is recreating , need not check using mic in background !",
487             info.sessionId);
488         return true;
489     }
490     if (iter != g_switchStreamRecordMap.end() && targetState == SWITCH_STATE_STARTED &&
491         iter->second == SWITCH_STATE_CREATED && (info.nextState == CAPTURER_RUNNING)) {
492         AUDIO_INFO_LOG("stream:%{public}u is restarting , need not check using mic in background !",
493             info.sessionId);
494         return true;
495     }
496     return false;
497 }
498 
InsertSwitchStreamRecord(SwitchStreamInfo & info,SwitchState targetState)499 bool SwitchStreamUtil::InsertSwitchStreamRecord(SwitchStreamInfo &info, SwitchState targetState)
500 {
501     if (RECORD_ALLOW_BACKGROUND_LIST.count(info.callerUid)) {
502         AUDIO_INFO_LOG("internal sa(%{public}d) user directly recording", info.callerUid);
503         return true;
504     }
505     auto ret = g_switchStreamRecordMap.insert(std::make_pair(info, targetState));
506     CHECK_AND_RETURN_RET_LOG(ret.second, false, "Update Record switchState:%{public}d for stream:%{public}u failed",
507         targetState, info.sessionId);
508     AUDIO_INFO_LOG("SwitchStream will start!Update Record switchState:%{public}d for stream:%{public}u"
509         "uid:%{public}d CapturerState:%{public}d success", targetState, info.sessionId, info.appUid, info.nextState);
510     std::thread(TimeoutThreadHandleTimeoutRecord, info, targetState).detach();
511     return true;
512 }
513 
TimeoutThreadHandleTimeoutRecord(SwitchStreamInfo info,SwitchState targetState)514 void SwitchStreamUtil::TimeoutThreadHandleTimeoutRecord(SwitchStreamInfo info, SwitchState targetState)
515 {
516     const std::chrono::seconds TIMEOUT_DURATION(2);
517     AUDIO_INFO_LOG("Start timing. It will change to SWITCH_STATE_TIMEOUT after 2 seconds.");
518     std::this_thread::sleep_for(TIMEOUT_DURATION);
519 
520     {
521         std::lock_guard<std::mutex> lock(g_switchMapMutex);
522         auto it = g_switchStreamRecordMap.find(info);
523         if (it != g_switchStreamRecordMap.end()) {
524             it->second = SWITCH_STATE_TIMEOUT;
525             g_switchStreamRecordMap.erase(it);
526             AUDIO_INFO_LOG("SwitchStream:%{public}u uid:%{public}d CapturerState:%{public}d was timeout! "
527                 "Update Record switchState:%{public}d success",
528                 info.sessionId, info.appUid, info.nextState, SWITCH_STATE_TIMEOUT);
529         }
530     }
531 }
532 
533 //Remove switchStreamInfo from  switchStreamRecordMap must be called with g_switchMapMutex held
RemoveSwitchStreamRecord(SwitchStreamInfo & info,SwitchState targetState)534 bool SwitchStreamUtil::RemoveSwitchStreamRecord(SwitchStreamInfo &info, SwitchState targetState)
535 {
536     if (g_switchStreamRecordMap.count(info) != 0) {
537         g_switchStreamRecordMap.erase(info);
538 
539         CHECK_AND_RETURN_RET((g_switchStreamRecordMap.count(info) == 0), false,
540             "Remove exist record failed for stream:%{public}u", info.sessionId);
541         AUDIO_WARNING_LOG("Exist Record has been Removed for stream:%{public}u", info.sessionId);
542     }
543     return true;
544 }
545 
RemoveAllRecordBySessionId(uint32_t sessionId)546 bool SwitchStreamUtil::RemoveAllRecordBySessionId(uint32_t sessionId)
547 {
548     std::lock_guard<std::mutex> lock(g_switchMapMutex);
549 
550     for (auto it = g_switchStreamRecordMap.begin(); it != g_switchStreamRecordMap.end();) {
551         if (it->first.sessionId == sessionId) {
552             it = g_switchStreamRecordMap.erase(it);
553         } else {
554             ++it;
555         }
556     }
557     return true;
558 }
559 
UpdateSwitchStreamRecord(SwitchStreamInfo & info,SwitchState targetState)560 bool SwitchStreamUtil::UpdateSwitchStreamRecord(SwitchStreamInfo &info, SwitchState targetState)
561 {
562     std::lock_guard<std::mutex> lock(g_switchMapMutex);
563     auto iter = g_switchStreamRecordMap.find(info);
564     bool isInfoInRecord = (iter != g_switchStreamRecordMap.end());
565     if (!isInfoInRecord) {
566         if (targetState == SWITCH_STATE_WAITING) {
567             CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::InsertSwitchStreamRecord(info, targetState),
568                 false, "Insert SwitchStream into Record fail!");
569             AUDIO_INFO_LOG("Insert SwitchStream into Record success!");
570         }
571         return true;
572     }
573 
574     switch (targetState) {
575         case SWITCH_STATE_WAITING:
576             CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState),
577                 false, "Remove Error Record for Stream:%{public}u Failed!", iter->first.sessionId);
578             CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::InsertSwitchStreamRecord(info, targetState),
579                 false, "Insert SwitchStream into Record fail!");
580             break;
581         case SWITCH_STATE_CREATED:
582             CHECK_AND_RETURN_RET_LOG(HandleCreatedSwitchInfoInRecord(info, targetState), false,
583                 "Handle switch record to SWITCH_STATE_CREATED failed!");
584             break;
585         case SWITCH_STATE_STARTED:
586             CHECK_AND_RETURN_RET_LOG(HandleStartedSwitchInfoInRecord(info, targetState), false,
587                 "Handle switch record to SWITCH_STATE_STARTED failed!");
588             break;
589         default:
590             CHECK_AND_RETURN_RET_LOG(HandleSwitchInfoInRecord(info, targetState), false,
591                 "Handle switch info in record failed!");
592             break;
593     }
594     if (iter->first.nextState == info.nextState) {
595         g_switchStreamRecordMap[info] = SWITCH_STATE_FINISHED;
596         g_switchStreamRecordMap.erase(info);
597         AUDIO_INFO_LOG("SwitchStream will finish!Remove Record for stream:%{public}u uid:%{public}d ",
598             info.sessionId, info.appUid);
599     }
600     if (iter->second == SWITCH_STATE_TIMEOUT || iter->second == SWITCH_STATE_FINISHED) {
601         CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState), false,
602             "Remove TIMEOUT or FINISHED Record for Stream:%{public}u Failed!", iter->first.sessionId);
603         return false;
604     }
605     return true;
606 }
607 
HandleCreatedSwitchInfoInRecord(SwitchStreamInfo & info,SwitchState targetState)608 bool SwitchStreamUtil::HandleCreatedSwitchInfoInRecord(SwitchStreamInfo &info, SwitchState targetState)
609 {
610     auto iter = g_switchStreamRecordMap.find(info);
611     if (iter->second == SWITCH_STATE_WAITING && (info.nextState == CAPTURER_PREPARED)) {
612         g_switchStreamRecordMap[info] = targetState;
613         AUDIO_INFO_LOG("SwitchStream will reCreated!Update Record switchState:%{public}d for"
614             "stream:%{public}u uid:%{public}d streamState:%{public}d success",
615             targetState, info.sessionId, info.appUid, info.nextState);
616     } else {
617         CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState),
618             false, "Remove Error Record for Stream:%{public}u Failed!", iter->first.sessionId);
619     }
620     return true;
621 }
622 
HandleSwitchInfoInRecord(SwitchStreamInfo & info,SwitchState targetState)623 bool SwitchStreamUtil::HandleSwitchInfoInRecord(SwitchStreamInfo &info, SwitchState targetState)
624 {
625     auto iter = g_switchStreamRecordMap.find(info);
626     if (((iter->second == SWITCH_STATE_CREATED) || (iter->second == SWITCH_STATE_STARTED)) &&
627         (info.nextState == CAPTURER_STOPPED || info.nextState == CAPTURER_PAUSED ||
628         info.nextState == CAPTURER_RELEASED || info.nextState == CAPTURER_INVALID)) {
629         CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState),
630             false, "Remove Finished Record for Stream:%{public}u Failed!", iter->first.sessionId);
631     } else if ((iter->second == SWITCH_STATE_WAITING) && (info.nextState == CAPTURER_STOPPED ||
632         info.nextState == CAPTURER_PAUSED || info.nextState == CAPTURER_RELEASED ||
633         info.nextState == CAPTURER_INVALID)) {
634         AUDIO_INFO_LOG("SwitchStream streamState has been changed to [%{public}d] before recreate!",
635             info.nextState);
636     } else {
637         CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState),
638             false, "Remove Error Record for Stream:%{public}u Failed!", iter->first.sessionId);
639         AUDIO_INFO_LOG("Error Record has been Removed for stream:%{public}u", iter->first.sessionId);
640     }
641     return true;
642 }
643 
HandleStartedSwitchInfoInRecord(SwitchStreamInfo & info,SwitchState targetState)644 bool SwitchStreamUtil::HandleStartedSwitchInfoInRecord(SwitchStreamInfo &info, SwitchState targetState)
645 {
646     auto iter = g_switchStreamRecordMap.find(info);
647     if ((iter->second == SWITCH_STATE_CREATED) && (info.nextState == CAPTURER_RUNNING)) {
648         g_switchStreamRecordMap[info] = targetState;
649         AUDIO_INFO_LOG("SwitchStream will reStarted!Update Record switchState:%{public}d for"
650             "stream:%{public}u uid:%{public}d streamState:%{public}d success",
651             targetState, info.sessionId, info.appUid, info.nextState);
652     } else {
653         CHECK_AND_RETURN_RET_LOG(SwitchStreamUtil::RemoveSwitchStreamRecord(info, targetState),
654             false, "Remove Error Record for Stream:%{public}u Failed!", iter->first.sessionId);
655     }
656     return true;
657 }
658 
659 std::mutex g_recordMapMutex;
660 std::map<std::uint32_t, std::set<uint32_t>> g_tokenIdRecordMap = {};
661 
StartUsingPermission(uint32_t targetTokenId,const char * permission)662 int32_t PermissionUtil::StartUsingPermission(uint32_t targetTokenId, const char* permission)
663 {
664     Trace trace("PrivacyKit::StartUsingPermission");
665     AUDIO_WARNING_LOG("PrivacyKit::StartUsingPermission tokenId:%{public}d permission:%{public}s",
666         targetTokenId, permission);
667     WatchTimeout guard("PrivacyKit::StartUsingPermission:PermissionUtil::StartUsingPermission");
668     int32_t res = Security::AccessToken::PrivacyKit::StartUsingPermission(targetTokenId, permission);
669     guard.CheckCurrTimeout();
670     return res;
671 }
672 
StopUsingPermission(uint32_t targetTokenId,const char * permission)673 int32_t PermissionUtil::StopUsingPermission(uint32_t targetTokenId, const char* permission)
674 {
675     Trace trace("PrivacyKit::StopUsingPermission");
676     AUDIO_WARNING_LOG("PrivacyKit::StopUsingPermission tokenId:%{public}d permission:%{public}s",
677         targetTokenId, permission);
678     WatchTimeout guard("PrivacyKit::StopUsingPermission:PermissionUtil::StopUsingPermission");
679     int32_t res = Security::AccessToken::PrivacyKit::StopUsingPermission(targetTokenId, permission);
680     guard.CheckCurrTimeout();
681     return res;
682 }
683 
NotifyPrivacyStart(uint32_t targetTokenId,uint32_t sessionId)684 bool PermissionUtil::NotifyPrivacyStart(uint32_t targetTokenId, uint32_t sessionId)
685 {
686     AudioXCollie audioXCollie("PermissionUtil::NotifyPrivacyStart", TIME_OUT_SECONDS);
687     std::lock_guard<std::mutex> lock(g_recordMapMutex);
688     if (g_tokenIdRecordMap.count(targetTokenId)) {
689         if (!g_tokenIdRecordMap[targetTokenId].count(sessionId)) {
690             g_tokenIdRecordMap[targetTokenId].emplace(sessionId);
691         } else {
692             AUDIO_WARNING_LOG("this stream %{public}u is already running, no need call start", sessionId);
693         }
694     } else {
695         AUDIO_INFO_LOG("Notify PrivacyKit to display the microphone privacy indicator "
696             "for tokenId: %{public}d sessionId:%{public}d", targetTokenId, sessionId);
697         int32_t res = PermissionUtil::StartUsingPermission(targetTokenId, MICROPHONE_PERMISSION);
698         CHECK_AND_RETURN_RET_LOG(res == 0 || res == Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING, false,
699             "StartUsingPermission for tokenId:%{public}u, PrivacyKit error code:%{public}d", targetTokenId, res);
700         if (res == Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING) {
701             AUDIO_ERR_LOG("The PrivacyKit return ERR_PERMISSION_ALREADY_START_USING error code:%{public}d", res);
702         }
703         WatchTimeout reguard("Security::AccessToken::PrivacyKit::AddPermissionUsedRecord:NotifyPrivacyStart");
704         res = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(targetTokenId, MICROPHONE_PERMISSION, 1, 0);
705         reguard.CheckCurrTimeout();
706         CHECK_AND_RETURN_RET_LOG(res == 0, false, "AddPermissionUsedRecord for tokenId %{public}u!"
707             "The PrivacyKit error code:%{public}d", targetTokenId, res);
708         g_tokenIdRecordMap[targetTokenId] = {sessionId};
709     }
710     return true;
711 }
712 
NotifyPrivacyStop(uint32_t targetTokenId,uint32_t sessionId)713 bool PermissionUtil::NotifyPrivacyStop(uint32_t targetTokenId, uint32_t sessionId)
714 {
715     AudioXCollie audioXCollie("PermissionUtil::NotifyPrivacyStop", TIME_OUT_SECONDS);
716     std::unique_lock<std::mutex> lock(g_recordMapMutex);
717     if (!g_tokenIdRecordMap.count(targetTokenId)) {
718         AUDIO_INFO_LOG("this TokenId %{public}u is already not in using", targetTokenId);
719         return true;
720     }
721 
722     if (g_tokenIdRecordMap[targetTokenId].count(sessionId)) {
723         g_tokenIdRecordMap[targetTokenId].erase(sessionId);
724     }
725     AUDIO_DEBUG_LOG("this TokenId %{public}u set size is %{public}zu!", targetTokenId,
726         g_tokenIdRecordMap[targetTokenId].size());
727     if (g_tokenIdRecordMap[targetTokenId].empty()) {
728         g_tokenIdRecordMap.erase(targetTokenId);
729         AUDIO_INFO_LOG("Notify PrivacyKit to remove the microphone privacy indicator "
730             "for tokenId: %{public}d sessionId:%{public}d", targetTokenId, sessionId);
731         int32_t res = PermissionUtil::StopUsingPermission(targetTokenId, MICROPHONE_PERMISSION);
732         CHECK_AND_RETURN_RET_LOG(res == 0, false, "StopUsingPermission for tokenId %{public}u!"
733             "The PrivacyKit error code:%{public}d", targetTokenId, res);
734     }
735     return true;
736 }
737 
AdjustStereoToMonoForPCM8Bit(int8_t * data,uint64_t len)738 void AdjustStereoToMonoForPCM8Bit(int8_t *data, uint64_t len)
739 {
740     // the number 2: stereo audio has 2 channels
741     uint64_t count = len / 2;
742 
743     while (count > 0) {
744         // the number 2 is the count of stereo audio channels
745         data[0] = data[0] / 2 + data[1] / 2;
746         data[1] = data[0];
747         data += 2;
748         count--;
749     }
750 }
751 
AdjustStereoToMonoForPCM16Bit(int16_t * data,uint64_t len)752 void AdjustStereoToMonoForPCM16Bit(int16_t *data, uint64_t len)
753 {
754     uint64_t count = len / 2 / 2;
755     // first number 2: stereo audio has 2 channels
756     // second number 2: the bit depth of PCM16Bit is 16 bits (2 bytes)
757 
758     while (count > 0) {
759         // the number 2 is the count of stereo audio channels
760         data[0] = data[0] / 2 + data[1] / 2;
761         data[1] = data[0];
762         data += 2;
763         count--;
764     }
765 }
766 
AdjustStereoToMonoForPCM24Bit(uint8_t * data,uint64_t len)767 void AdjustStereoToMonoForPCM24Bit(uint8_t *data, uint64_t len)
768 {
769     uint64_t count = len / STEREO_CHANNEL_COUNT / 3; // 3: the bit depth of PCM24Bit is 24 bits (3 bytes)
770 
771     while (count > 0) {
772         uint32_t leftData = (static_cast<uint32_t>(data[DATA_INDEX_2]) << BIT_16) |
773             (static_cast<uint32_t>(data[DATA_INDEX_1]) << BIT_8) |
774             (static_cast<uint32_t>(data[DATA_INDEX_0]));
775         uint32_t rightData = (static_cast<uint32_t>(data[DATA_INDEX_5]) << BIT_16) |
776             (static_cast<uint32_t>(data[DATA_INDEX_4]) << BIT_8) |
777             (static_cast<uint32_t>(data[DATA_INDEX_3]));
778 
779         leftData = static_cast<uint32_t>(static_cast<int32_t>(leftData << BIT_8) / STEREO_CHANNEL_COUNT +
780             static_cast<int32_t>(rightData << BIT_8) / STEREO_CHANNEL_COUNT) >> BIT_8;
781         rightData = leftData;
782 
783         data[DATA_INDEX_0] = static_cast<uint8_t>(leftData);
784         data[DATA_INDEX_1] = static_cast<uint8_t>(leftData >> BIT_8);
785         data[DATA_INDEX_2] = static_cast<uint8_t>(leftData >> BIT_16);
786         data[DATA_INDEX_3] = static_cast<uint8_t>(rightData);
787         data[DATA_INDEX_4] = static_cast<uint8_t>(rightData >> BIT_8);
788         data[DATA_INDEX_5] = static_cast<uint8_t>(rightData >> BIT_16);
789         data += 6; // 6: 2 channels, 24 bits (3 bytes), 2 * 3 = 6
790         count--;
791     }
792 }
793 
AdjustStereoToMonoForPCM32Bit(int32_t * data,uint64_t len)794 void AdjustStereoToMonoForPCM32Bit(int32_t *data, uint64_t len)
795 {
796     uint64_t count = len / 2 / 4;
797     // first number 2: stereo audio has 2 channels
798     // second number 4: the bit depth of PCM32Bit is 32 bits (4 bytes)
799 
800     while (count > 0) {
801         // the number 2 is the count of stereo audio channels
802         data[0] = data[0] / 2 + data[1] / 2;
803         data[1] = data[0];
804         data += 2;
805         count--;
806     }
807 }
808 
AdjustAudioBalanceForPCM8Bit(int8_t * data,uint64_t len,float left,float right)809 void AdjustAudioBalanceForPCM8Bit(int8_t *data, uint64_t len, float left, float right)
810 {
811     uint64_t count = len / 2;
812     // the number 2: stereo audio has 2 channels
813 
814     while (count > 0) {
815         // the number 2 is the count of stereo audio channels
816         data[0] *= left;
817         data[1] *= right;
818         data += 2;
819         count--;
820     }
821 }
822 
AdjustAudioBalanceForPCM16Bit(int16_t * data,uint64_t len,float left,float right)823 void AdjustAudioBalanceForPCM16Bit(int16_t *data, uint64_t len, float left, float right)
824 {
825     uint64_t count = len / 2 / 2;
826     // first number 2: stereo audio has 2 channels
827     // second number 2: the bit depth of PCM16Bit is 16 bits (2 bytes)
828 
829     while (count > 0) {
830         // the number 2 is the count of stereo audio channels
831         data[0] *= left;
832         data[1] *= right;
833         data += 2;
834         count--;
835     }
836 }
837 
AdjustAudioBalanceForPCM24Bit(uint8_t * data,uint64_t len,float left,float right)838 void AdjustAudioBalanceForPCM24Bit(uint8_t *data, uint64_t len, float left, float right)
839 {
840     uint64_t count = len / STEREO_CHANNEL_COUNT / 3; // 3: the bit depth of PCM24Bit is 24 bits (3 bytes)
841 
842     while (count > 0) {
843         uint32_t leftData = (static_cast<uint32_t>(data[DATA_INDEX_2]) << BIT_16) |
844             (static_cast<uint32_t>(data[DATA_INDEX_1]) << BIT_8) |
845             (static_cast<uint32_t>(data[DATA_INDEX_0]));
846         int32_t leftTemp = static_cast<int32_t>(leftData << BIT_8);
847         leftTemp *= left;
848         leftData = static_cast<uint32_t>(leftTemp) >> BIT_8;
849         data[DATA_INDEX_0] = static_cast<uint8_t>(leftData);
850         data[DATA_INDEX_1] = static_cast<uint8_t>(leftData >> BIT_8);
851         data[DATA_INDEX_2] = static_cast<uint8_t>(leftData >> BIT_16);
852 
853         uint32_t rightData = (static_cast<uint32_t>(data[DATA_INDEX_5]) << BIT_16) |
854             (static_cast<uint32_t>(data[DATA_INDEX_4]) << BIT_8) |
855             (static_cast<uint32_t>(data[DATA_INDEX_3]));
856         int32_t rightTemp = static_cast<int32_t>(rightData << BIT_8);
857         rightTemp *= right;
858         rightData = static_cast<uint32_t>(rightTemp) >> BIT_8;
859         data[DATA_INDEX_3] = static_cast<uint8_t>(rightData);
860         data[DATA_INDEX_4] = static_cast<uint8_t>(rightData >> BIT_8);
861         data[DATA_INDEX_5] = static_cast<uint8_t>(rightData >> BIT_16);
862         data += 6; // 6: 2 channels, 24 bits (3 bytes), 2 * 3 = 6
863         count--;
864     }
865 }
866 
AdjustAudioBalanceForPCM32Bit(int32_t * data,uint64_t len,float left,float right)867 void AdjustAudioBalanceForPCM32Bit(int32_t *data, uint64_t len, float left, float right)
868 {
869     uint64_t count = len / 2 / 4;
870     // first number 2: stereo audio has 2 channels
871     // second number 4: the bit depth of PCM32Bit is 32 bits (4 bytes)
872 
873     while (count > 0) {
874         // the number 2 is the count of stereo audio channels
875         data[0] *= left;
876         data[1] *= right;
877         data += 2;
878         count--;
879     }
880 }
881 
Read24Bit(const uint8_t * p)882 uint32_t Read24Bit(const uint8_t *p)
883 {
884     return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]);
885 }
886 
Write24Bit(uint8_t * p,uint32_t u)887 void Write24Bit(uint8_t *p, uint32_t u)
888 {
889     p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16);
890     p[1] = static_cast<uint8_t>(u >> BIT_8);
891     p[0] = static_cast<uint8_t>(u);
892 }
893 
ConvertFrom24BitToFloat(unsigned n,const uint8_t * a,float * b)894 void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b)
895 {
896     for (; n > 0; n--) {
897         int32_t s = Read24Bit(a) << BIT_8;
898         *b = s * (1.0f / (1U << (BIT_32 - 1)));
899         a += OFFSET_BIT_24;
900         b++;
901     }
902 }
903 
ConvertFrom32BitToFloat(unsigned n,const int32_t * a,float * b)904 void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b)
905 {
906     for (; n > 0; n--) {
907         *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1)));
908     }
909 }
910 
CapMax(float v)911 float CapMax(float v)
912 {
913     float value = v;
914     if (v > 1.0f) {
915         value = 1.0f - FLOAT_EPS;
916     } else if (v < -1.0f) {
917         value = -1.0f + FLOAT_EPS;
918     }
919     return value;
920 }
921 
ConvertFromFloatTo24Bit(unsigned n,const float * a,uint8_t * b)922 void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b)
923 {
924     for (; n > 0; n--) {
925         float tmp = *a++;
926         float v = CapMax(tmp) * (1U << (BIT_32 - 1));
927         Write24Bit(b, (static_cast<int32_t>(v)) >> BIT_8);
928         b += OFFSET_BIT_24;
929     }
930 }
931 
ConvertFromFloatTo32Bit(unsigned n,const float * a,int32_t * b)932 void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b)
933 {
934     for (; n > 0; n--) {
935         float tmp = *a++;
936         float v = CapMax(tmp) * (1U << (BIT_32 - 1));
937         *(b++) = static_cast<int32_t>(v);
938     }
939 }
940 
UpdateMaxAmplitude(ConvertHdiFormat adapterFormat,char * frame,uint64_t replyBytes)941 float UpdateMaxAmplitude(ConvertHdiFormat adapterFormat, char *frame, uint64_t replyBytes)
942 {
943     switch (adapterFormat) {
944         case SAMPLE_U8_C: {
945             return CalculateMaxAmplitudeForPCM8Bit(reinterpret_cast<int8_t *>(frame), replyBytes);
946         }
947         case SAMPLE_S16_C: {
948             return CalculateMaxAmplitudeForPCM16Bit(reinterpret_cast<int16_t *>(frame),
949                 (replyBytes / sizeof(int16_t)));
950         }
951         case SAMPLE_S24_C: {
952             return CalculateMaxAmplitudeForPCM24Bit(frame, (replyBytes / 3)); // 3 bytes
953         }
954         case SAMPLE_S32_C: {
955             return CalculateMaxAmplitudeForPCM32Bit(reinterpret_cast<int32_t *>(frame),
956                 (replyBytes / sizeof(int32_t)));
957         }
958         default: {
959             AUDIO_INFO_LOG("getMaxAmplitude: Unsupported audio format: %{public}d", adapterFormat);
960             return 0;
961         }
962     }
963 }
964 
CalculateMaxAmplitudeForPCM8Bit(int8_t * frame,uint64_t nSamples)965 float CalculateMaxAmplitudeForPCM8Bit(int8_t *frame, uint64_t nSamples)
966 {
967     int curMaxAmplitude = 0;
968     for (uint32_t i = nSamples; i > 0; --i) {
969         int8_t value = *frame++;
970         if (value < 0) {
971             value = -value;
972         }
973         if (curMaxAmplitude < value) {
974             curMaxAmplitude = value;
975         }
976     }
977     return float(curMaxAmplitude) / SCHAR_MAX;
978 }
979 
CalculateMaxAmplitudeForPCM16Bit(int16_t * frame,uint64_t nSamples)980 float CalculateMaxAmplitudeForPCM16Bit(int16_t *frame, uint64_t nSamples)
981 {
982     int curMaxAmplitude = 0;
983     for (uint32_t i = nSamples; i > 0; --i) {
984         int16_t value = *frame++;
985         if (value < 0) {
986             value = -value;
987         }
988         if (curMaxAmplitude < value) {
989             curMaxAmplitude = value;
990         }
991     }
992     return float(curMaxAmplitude) / SHRT_MAX;
993 }
994 
CalculateMaxAmplitudeForPCM24Bit(char * frame,uint64_t nSamples)995 float CalculateMaxAmplitudeForPCM24Bit(char *frame, uint64_t nSamples)
996 {
997     int curMaxAmplitude = 0;
998     for (uint32_t i = 0; i < nSamples; ++i) {
999         char *curPos = frame + (i * 3); // 3 bytes
1000         int curValue = 0;
1001         for (int j = 0; j < 3; ++j) { // 3 bytes
1002             curValue += (*(curPos + j) << (BIT_8 * j));
1003         }
1004         if (curValue < 0) {
1005             curValue = -curValue;
1006         }
1007         if (curMaxAmplitude < curValue) {
1008             curMaxAmplitude = curValue;
1009         }
1010     }
1011     return float(curMaxAmplitude) / MAX_VALUE_OF_SIGNED_24_BIT;
1012 }
1013 
CalculateMaxAmplitudeForPCM32Bit(int32_t * frame,uint64_t nSamples)1014 float CalculateMaxAmplitudeForPCM32Bit(int32_t *frame, uint64_t nSamples)
1015 {
1016     int curMaxAmplitude = 0;
1017     for (uint32_t i = nSamples; i > 0; --i) {
1018         int32_t value = *frame++;
1019         if (value < 0) {
1020             value = -value;
1021         }
1022         if (curMaxAmplitude < value) {
1023             curMaxAmplitude = value;
1024         }
1025     }
1026     return float(curMaxAmplitude) / static_cast<float>(INT_MAX);
1027 }
1028 
1029 template <typename T>
StringConverter(const std::string & str,T & result)1030 bool StringConverter(const std::string &str, T &result)
1031 {
1032     if (str == "-0") {
1033         result = 0;
1034         return true;
1035     }
1036     auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
1037     return ec == std::errc{} && ptr == str.data() + str.size();
1038 }
1039 
1040 template bool StringConverter(const std::string &str, uint64_t &result);
1041 template bool StringConverter(const std::string &str, uint32_t &result);
1042 template bool StringConverter(const std::string &str, int32_t &result);
1043 template bool StringConverter(const std::string &str, uint16_t &result);
1044 template bool StringConverter(const std::string &str, uint8_t &result);
1045 template bool StringConverter(const std::string &str, int8_t &result);
1046 
StringConverterFloat(const std::string & str,float & result)1047 bool StringConverterFloat(const std::string &str, float &result)
1048 {
1049     char *end = nullptr;
1050     errno = 0;
1051     result = std::strtof(str.c_str(), &end);
1052     return end != str.c_str() && *end == '\0' && errno == 0;
1053 }
1054 
SetSysPara(const std::string & key,int32_t value)1055 bool SetSysPara(const std::string &key, int32_t value)
1056 {
1057     auto res = SetParameter(key.c_str(), std::to_string(value).c_str());
1058     if (res < 0) {
1059         AUDIO_WARNING_LOG("SetSysPara fail, key:%{public}s res:%{public}d", key.c_str(), res);
1060         return false;
1061     }
1062     AUDIO_INFO_LOG("SetSysPara %{public}d success.", value);
1063     return true;
1064 }
1065 
1066 template <typename T>
GetSysPara(const char * key,T & value)1067 bool GetSysPara(const char *key, T &value)
1068 {
1069     CHECK_AND_RETURN_RET_LOG(key != nullptr, false, "key is nullptr");
1070     char paraValue[30] = {0}; // 30 for system parameter
1071     auto res = GetParameter(key, "-1", paraValue, sizeof(paraValue));
1072 
1073     CHECK_AND_RETURN_RET_LOG(res > 0, false, "GetSysPara fail, key:%{public}s res:%{public}d", key, res);
1074     AUDIO_DEBUG_LOG("key:%{public}s value:%{public}s", key, paraValue);
1075     std::stringstream valueStr;
1076     valueStr << paraValue;
1077     valueStr >> value;
1078     return true;
1079 }
1080 
1081 template bool GetSysPara(const char *key, int32_t &value);
1082 template bool GetSysPara(const char *key, uint32_t &value);
1083 template bool GetSysPara(const char *key, int64_t &value);
1084 template bool GetSysPara(const char *key, std::string &value);
1085 
1086 std::map<std::string, std::string> DumpFileUtil::g_lastPara = {};
1087 
OpenDumpFileInner(std::string para,std::string fileName,AudioDumpFileType fileType)1088 FILE *DumpFileUtil::OpenDumpFileInner(std::string para, std::string fileName, AudioDumpFileType fileType)
1089 {
1090     std::string filePath;
1091     switch (fileType) {
1092         case AUDIO_APP:
1093             filePath = DUMP_APP_DIR + fileName;
1094             break;
1095         case OTHER_NATIVE_SERVICE:
1096             filePath = DUMP_SERVICE_DIR + fileName;
1097             break;
1098         case AUDIO_PULSE:
1099             filePath = DUMP_PULSE_DIR + fileName;
1100             break;
1101         default:
1102             AUDIO_ERR_LOG("Invalid AudioDumpFileType");
1103             break;
1104     }
1105     std::string dumpPara;
1106     FILE *dumpFile = nullptr;
1107     bool res = GetSysPara(para.c_str(), dumpPara);
1108     if (!res || dumpPara.empty()) {
1109         AUDIO_INFO_LOG("%{public}s is not set, dump audio is not required", para.c_str());
1110         g_lastPara[para] = dumpPara;
1111         return dumpFile;
1112     }
1113     AUDIO_DEBUG_LOG("%{public}s = %{public}s", para.c_str(), dumpPara.c_str());
1114     if (dumpPara == "w") {
1115         dumpFile = fopen(filePath.c_str(), "wb+");
1116         CHECK_AND_RETURN_RET_LOG(dumpFile != nullptr, dumpFile,
1117             "Error opening pcm dump file:%{public}s", filePath.c_str());
1118     } else if (dumpPara == "a") {
1119         dumpFile = fopen(filePath.c_str(), "ab+");
1120         CHECK_AND_RETURN_RET_LOG(dumpFile != nullptr, dumpFile,
1121             "Error opening pcm dump file:%{public}s", filePath.c_str());
1122     }
1123     if (dumpFile != nullptr) {
1124         AUDIO_INFO_LOG("Dump file path: %{public}s", filePath.c_str());
1125     }
1126     g_lastPara[para] = dumpPara;
1127     return dumpFile;
1128 }
1129 
WriteDumpFile(FILE * dumpFile,void * buffer,size_t bufferSize)1130 void DumpFileUtil::WriteDumpFile(FILE *dumpFile, void *buffer, size_t bufferSize)
1131 {
1132     if (dumpFile == nullptr) {
1133         return;
1134     }
1135     CHECK_AND_RETURN_LOG(buffer != nullptr, "Invalid write param");
1136     size_t writeResult = fwrite(buffer, 1, bufferSize, dumpFile);
1137     CHECK_AND_RETURN_LOG(writeResult == bufferSize, "Failed to write the file.");
1138 }
1139 
CloseDumpFile(FILE ** dumpFile)1140 void DumpFileUtil::CloseDumpFile(FILE **dumpFile)
1141 {
1142     if (*dumpFile) {
1143         fclose(*dumpFile);
1144         *dumpFile = nullptr;
1145     }
1146 }
1147 
ChangeDumpFileState(std::string para,FILE ** dumpFile,std::string filePath)1148 void DumpFileUtil::ChangeDumpFileState(std::string para, FILE **dumpFile, std::string filePath)
1149 {
1150     CHECK_AND_RETURN_LOG(*dumpFile != nullptr, "Invalid file para");
1151     CHECK_AND_RETURN_LOG(g_lastPara[para] == "w" || g_lastPara[para] == "a", "Invalid input para");
1152     std::string dumpPara;
1153     bool res = GetSysPara(para.c_str(), dumpPara);
1154     if (!res || dumpPara.empty()) {
1155         AUDIO_WARNING_LOG("get %{public}s fail", para.c_str());
1156     }
1157     if (g_lastPara[para] == "w" && dumpPara == "w") {
1158         return;
1159     }
1160     CloseDumpFile(dumpFile);
1161     OpenDumpFile(para, filePath, dumpFile);
1162 }
1163 
OpenDumpFile(std::string para,std::string fileName,FILE ** file)1164 void DumpFileUtil::OpenDumpFile(std::string para, std::string fileName, FILE **file)
1165 {
1166     if (*file != nullptr) {
1167         DumpFileUtil::ChangeDumpFileState(para, file, fileName);
1168         return;
1169     }
1170 
1171     if (para == DUMP_SERVER_PARA) {
1172         *file = DumpFileUtil::OpenDumpFileInner(para, fileName, AUDIO_PULSE);
1173     } else {
1174         *file = DumpFileUtil::OpenDumpFileInner(para, fileName, AUDIO_APP);
1175         if (*file == nullptr) {
1176             *file = DumpFileUtil::OpenDumpFileInner(para, fileName, OTHER_NATIVE_SERVICE);
1177         }
1178     }
1179 }
1180 
CloseFd(int fd)1181 void CloseFd(int fd)
1182 {
1183     // log stdin, stdout, stderr.
1184     if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) {
1185         AUDIO_WARNING_LOG("special fd: %{public}d will be closed", fd);
1186     }
1187     int tmpFd = fd;
1188     close(fd);
1189     AUDIO_DEBUG_LOG("fd: %{public}d closed successfuly!", tmpFd);
1190 }
1191 
MemcpyToI32FromI16(int16_t * src,int32_t * dst,size_t count)1192 static void MemcpyToI32FromI16(int16_t *src, int32_t *dst, size_t count)
1193 {
1194     for (size_t i = 0; i < count; i++) {
1195         *(dst + i) = static_cast<int32_t>(*(src + i));
1196     }
1197 }
1198 
MemcpyToI32FromI24(uint8_t * src,int32_t * dst,size_t count)1199 static void MemcpyToI32FromI24(uint8_t *src, int32_t *dst, size_t count)
1200 {
1201     for (size_t i = 0; i < count; i++) {
1202         uint8_t *tmp = src + 3 * i; // 3 is byte size of SAMPLE_S24LE;
1203         *(dst + i) = static_cast<int32_t>(tmp[2] << (2 * sizeof(uint8_t))) |
1204             static_cast<int32_t>(tmp[1] << sizeof(uint8_t)) | static_cast<int32_t>(tmp[0]);
1205     }
1206 }
1207 
MemcpyToI32FromF32(float * src,int32_t * dst,size_t count)1208 static void MemcpyToI32FromF32(float *src, int32_t *dst, size_t count)
1209 {
1210     for (size_t i = 0; i < count; i++) {
1211         *(dst + i) = static_cast<int32_t>(*(src + i));
1212     }
1213 }
1214 
NearZero(int16_t number)1215 bool NearZero(int16_t number)
1216 {
1217     return number >= -DETECTED_ZERO_THRESHOLD && number <= DETECTED_ZERO_THRESHOLD;
1218 }
1219 
GetTime()1220 std::string GetTime()
1221 {
1222     std::string curTime;
1223     struct timeval tv;
1224     struct timezone tz;
1225     struct tm *t;
1226     gettimeofday(&tv, &tz);
1227     t = localtime(&tv.tv_sec);
1228     if (t == nullptr) {
1229         return "";
1230     }
1231 
1232     curTime += std::to_string(YEAR_BASE + t->tm_year);
1233     curTime += (1 + t->tm_mon < DECIMAL_EXPONENT ? "0" + std::to_string(1 + t->tm_mon) :
1234         std::to_string(1 + t->tm_mon));
1235     curTime += (t->tm_mday < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_mday) :
1236         std::to_string(t->tm_mday));
1237     curTime += (t->tm_hour < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_hour) :
1238         std::to_string(t->tm_hour));
1239     curTime += (t->tm_min < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_min) :
1240         std::to_string(t->tm_min));
1241     curTime += (t->tm_sec < DECIMAL_EXPONENT ? "0" + std::to_string(t->tm_sec) :
1242         std::to_string(t->tm_sec));
1243     int64_t mSec = static_cast<int64_t>(tv.tv_usec / AUDIO_MS_PER_SECOND);
1244     curTime += (mSec < (DECIMAL_EXPONENT * DECIMAL_EXPONENT) ? (mSec < DECIMAL_EXPONENT ? "00" : "0") +
1245         std::to_string(mSec) : std::to_string(mSec));
1246     return curTime;
1247 }
1248 
GetFormatByteSize(int32_t format)1249 int32_t GetFormatByteSize(int32_t format)
1250 {
1251     int32_t formatByteSize;
1252     switch (format) {
1253         case SAMPLE_S16LE:
1254             formatByteSize = 2; // size is 2
1255             break;
1256         case SAMPLE_S24LE:
1257             formatByteSize = 3; // size is 3
1258             break;
1259         case SAMPLE_S32LE:
1260             formatByteSize = 4; // size is 4
1261             break;
1262         case SAMPLE_F32LE:
1263             formatByteSize = 4; // size is 4
1264             break;
1265         default:
1266             formatByteSize = 2; // size is 2
1267             break;
1268     }
1269     return formatByteSize;
1270 }
1271 
CheckAudioData(uint8_t * buffer,size_t bufferLen)1272 bool SignalDetectAgent::CheckAudioData(uint8_t *buffer, size_t bufferLen)
1273 {
1274     CHECK_AND_RETURN_RET_LOG(formatByteSize_ != 0, false, "LatencyMeas checkAudioData failed, "
1275         "formatByteSize_ %{public}d", formatByteSize_);
1276     frameCountIgnoreChannel_ = bufferLen / static_cast<uint32_t>(formatByteSize_);
1277     if (cacheAudioData_.capacity() < frameCountIgnoreChannel_) {
1278         cacheAudioData_.clear();
1279         cacheAudioData_.reserve(frameCountIgnoreChannel_);
1280     }
1281     int32_t *cache = cacheAudioData_.data();
1282     if (sampleFormat_ == SAMPLE_S32LE) {
1283         int32_t ret = memcpy_s(cache, sizeof(int32_t) * cacheAudioData_.capacity(), buffer, bufferLen);
1284         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "LatencyMeas checkAudioData failed, dstSize "
1285             "%{public}zu, srcSize %{public}zu", sizeof(int32_t) * cacheAudioData_.capacity(), bufferLen);
1286     } else if (sampleFormat_ == SAMPLE_F32LE) {
1287         float *cp = reinterpret_cast<float*>(buffer);
1288         MemcpyToI32FromF32(cp, cache, frameCountIgnoreChannel_);
1289     } else if (sampleFormat_ == SAMPLE_S24LE) {
1290         MemcpyToI32FromI24(buffer, cache, frameCountIgnoreChannel_);
1291     } else {
1292         int16_t *cp = reinterpret_cast<int16_t*>(buffer);
1293         MemcpyToI32FromI16(cp, cache, frameCountIgnoreChannel_);
1294     }
1295     if (DetectSignalData(cache, frameCountIgnoreChannel_)) {
1296         ResetDetectResult();
1297         return true;
1298     }
1299     return false;
1300 }
1301 
DetectSignalData(int32_t * buffer,size_t bufferLen)1302 bool SignalDetectAgent::DetectSignalData(int32_t *buffer, size_t bufferLen)
1303 {
1304     std::string curTime = GetTime();
1305     uint32_t rightZeroSignal = 0;
1306     int32_t currentPeakIndex = -1;
1307     int32_t currentPeakSignal = SHRT_MIN;
1308     bool hasNoneZero = false;
1309     size_t frameCount = bufferLen / static_cast<size_t>(channels_);
1310     for (size_t index = 0; index < frameCount; index++) {
1311         int32_t tempMax = SHRT_MIN;
1312         int32_t tempMin = SHRT_MAX;
1313         for (uint32_t channel = 0; channel < static_cast<uint32_t>(channels_); channel++) {
1314             int32_t temp = buffer[index * static_cast<uint32_t>(channels_) + channel];
1315             tempMax = temp > tempMax ? temp : tempMax;
1316             tempMin = temp < tempMin ? temp : tempMin;
1317         }
1318         if (!NearZero(tempMax) || !NearZero(tempMin)) {
1319             rightZeroSignal = index + 1;
1320             hasNoneZero = true;
1321             if (currentPeakIndex == -1 || tempMax > currentPeakSignal) {
1322                 currentPeakIndex = static_cast<int32_t>(index);
1323                 currentPeakSignal = tempMax;
1324             }
1325         }
1326     }
1327     if (!hasNoneZero) {
1328         blankPeriod_ += static_cast<int32_t>(frameCount);
1329     } else {
1330         if (!hasFirstNoneZero_) {
1331             lastPeakBufferTime_ = curTime;
1332             hasFirstNoneZero_ = true;
1333         }
1334         if (currentPeakSignal > lastPeakSignal_) {
1335             lastPeakSignal_ = currentPeakSignal;
1336             lastPeakSignalPos_ = currentPeakIndex;
1337         }
1338         blankHaveOutput_ = false;
1339         blankPeriod_ = static_cast<int32_t>(frameCount - rightZeroSignal);
1340     }
1341     int32_t thresholdBlankPeriod = BLANK_THRESHOLD_MS * sampleRate_ / MILLISECOND_PER_SECOND;
1342     if (blankPeriod_ > thresholdBlankPeriod) {
1343         return !blankHaveOutput_;
1344     }
1345     return false;
1346 }
1347 
ResetDetectResult()1348 void SignalDetectAgent::ResetDetectResult()
1349 {
1350     blankHaveOutput_ = true;
1351     hasFirstNoneZero_ = false;
1352     lastPeakSignal_ = SHRT_MIN;
1353     signalDetected_ = true;
1354     dspTimestampGot_ = false;
1355     return;
1356 }
1357 
MockPcmData(uint8_t * buffer,size_t bufferLen)1358 bool AudioLatencyMeasurement::MockPcmData(uint8_t *buffer, size_t bufferLen)
1359 {
1360     memset_s(buffer, bufferLen, 0, bufferLen);
1361     int16_t *signal = signalData_.get();
1362     size_t newlyMocked = bufferLen * MILLISECOND_PER_SECOND /
1363         static_cast<size_t>(channelCount_ * sampleRate_ * formatByteSize_);
1364     mockedTime_ += newlyMocked;
1365     if (mockedTime_ >= MOCK_INTERVAL) {
1366         mockedTime_ = 0;
1367         if (format_ == SAMPLE_S32LE) {
1368             MemcpyToI32FromI16(signal, reinterpret_cast<int32_t*>(buffer), SIGNAL_DATA_SIZE);
1369         } else {
1370             int32_t ret = memcpy_s(buffer, bufferLen, signal, SIGNAL_DATA_SIZE * sizeof(uint8_t));
1371             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "LatencyMeas mockPcmData failed, dstSize "
1372                 "%{public}zu, srcSize %{public}zu", bufferLen, SIGNAL_DATA_SIZE * sizeof(uint8_t));
1373         }
1374         return true;
1375     }
1376     return false;
1377 }
1378 
AudioLatencyMeasurement(const int32_t & sampleRate,const int32_t & channelCount,const int32_t & sampleFormat,const std::string & appName,const uint32_t & sessionId)1379 AudioLatencyMeasurement::AudioLatencyMeasurement(const int32_t &sampleRate,
1380                                                  const int32_t &channelCount, const int32_t &sampleFormat,
1381                                                  const std::string &appName, const uint32_t &sessionId)
1382     :format_(sampleFormat),
1383      sampleRate_(sampleRate),
1384      channelCount_(channelCount),
1385      sessionId_(sessionId),
1386      appName_(appName)
1387 {
1388     std::string appToMock = "com.example.null";
1389     GetSysPara("persist.multimedia.apptomock", appToMock);
1390     AUDIO_INFO_LOG("LatencyMeas appName:%{public}s, appToMock:%{public}s, g_sessionId:%{public}u",
1391         appName.c_str(), appToMock.c_str(), g_sessionToMock);
1392     if (appToMock == appName && g_sessionToMock == 0) {
1393         mockThisStream_ = true;
1394         g_sessionToMock = sessionId;
1395     }
1396     formatByteSize_ = GetFormatByteSize(sampleFormat);
1397     InitSignalData();
1398 }
1399 
~AudioLatencyMeasurement()1400 AudioLatencyMeasurement::~AudioLatencyMeasurement()
1401 {
1402     if (mockThisStream_ && g_sessionToMock == sessionId_) {
1403         g_sessionToMock = 0;
1404     }
1405 }
1406 
InitSignalData()1407 void AudioLatencyMeasurement::InitSignalData()
1408 {
1409     signalData_ = std::make_unique<int16_t[]>(SIGNAL_DATA_SIZE);
1410     memset_s(signalData_.get(), SIGNAL_DATA_SIZE, 0, SIGNAL_DATA_SIZE);
1411     const int16_t channels = 2; // 2 channels
1412     const int16_t samplePerChannel = SIGNAL_DATA_SIZE / channels;
1413     int16_t *signalBuffer = signalData_.get();
1414     for (int16_t index = 0; index < samplePerChannel; index++) {
1415         signalBuffer[index * channels] = SIGNAL_THRESHOLD + static_cast<int16_t>(sinf(2.0f *
1416             static_cast<float>(M_PI) * index / samplePerChannel) * (SHRT_MAX - SIGNAL_THRESHOLD));
1417         for (int16_t k = 1; k < channels; k++) {
1418             signalBuffer[channels * index + k] = signalBuffer[channels * index];
1419         }
1420     }
1421     AUDIO_INFO_LOG("LatencyMeas signalData inited");
1422     return;
1423 }
1424 
CheckIfEnabled()1425 bool AudioLatencyMeasurement::CheckIfEnabled()
1426 {
1427     int32_t latencyMeasure = -1;
1428     GetSysPara("persist.multimedia.audiolatency", latencyMeasure);
1429     return (latencyMeasure == 1);
1430 }
1431 
GetInstance()1432 LatencyMonitor& LatencyMonitor::GetInstance()
1433 {
1434     static LatencyMonitor latencyMonitor_;
1435     return latencyMonitor_;
1436 }
1437 
UpdateClientTime(bool isRenderer,std::string & timestamp)1438 void LatencyMonitor::UpdateClientTime(bool isRenderer, std::string &timestamp)
1439 {
1440     if (isRenderer) {
1441         rendererMockTime_ = timestamp;
1442     } else {
1443         capturerDetectedTime_ = timestamp;
1444     }
1445 }
1446 
UpdateSinkOrSourceTime(bool isRenderer,std::string & timestamp)1447 void LatencyMonitor::UpdateSinkOrSourceTime(bool isRenderer, std::string &timestamp)
1448 {
1449     if (isRenderer) {
1450         sinkDetectedTime_ = timestamp;
1451     } else {
1452         sourceDetectedTime_ = timestamp;
1453     }
1454 }
1455 
UpdateDspTime(std::string timestamp)1456 void LatencyMonitor::UpdateDspTime(std::string timestamp)
1457 {
1458     dspDetectedTime_ = timestamp;
1459 }
1460 
ShowTimestamp(bool isRenderer)1461 void LatencyMonitor::ShowTimestamp(bool isRenderer)
1462 {
1463     if (extraStrLen_ == 0) {
1464         extraStrLen_ = dspDetectedTime_.find("20");
1465     }
1466     if (isRenderer) {
1467         if (dspDetectedTime_.length() == 0) {
1468             AUDIO_ERR_LOG("LatencyMeas GetExtraParameter failed!");
1469             AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, SinkDetectedTime:%{public}s",
1470                 rendererMockTime_.c_str(), sinkDetectedTime_.c_str());
1471             return;
1472         }
1473         dspBeforeSmartPa_ = dspDetectedTime_.substr(extraStrLen_, DATE_LENGTH);
1474         dspAfterSmartPa_ = dspDetectedTime_.substr(extraStrLen_ + DATE_LENGTH + 1 +
1475             extraStrLen_, DATE_LENGTH);
1476         AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, SinkDetectedTime:%{public}s, "
1477                        "DspBeforeSmartPa:%{public}s, DspAfterSmartPa:%{public}s", rendererMockTime_.c_str(),
1478                        sinkDetectedTime_.c_str(), dspBeforeSmartPa_.c_str(), dspAfterSmartPa_.c_str());
1479     } else {
1480         AUDIO_INFO_LOG("renderer mock time %{public}s", rendererMockTime_.c_str());
1481         if (dspDetectedTime_.length() == 0) {
1482             AUDIO_ERR_LOG("LatencyMeas GetExtraParam failed!");
1483             AUDIO_INFO_LOG("LatencyMeas CapturerDetectedTime:%{public}s, SourceDetectedTime:%{public}s",
1484                 capturerDetectedTime_.c_str(), sourceDetectedTime_.c_str());
1485             return;
1486         }
1487         dspMockTime_ = dspDetectedTime_.substr(extraStrLen_ + DATE_LENGTH + extraStrLen_ + 1 +
1488             DATE_LENGTH + extraStrLen_ + 1, DATE_LENGTH);
1489         AUDIO_INFO_LOG("LatencyMeas CapturerDetectedTime:%{public}s, SourceDetectedTime:%{public}s, "
1490                        "DspMockTime:%{public}s", capturerDetectedTime_.c_str(), sourceDetectedTime_.c_str(),
1491                        dspMockTime_.c_str());
1492     }
1493 }
1494 
ShowBluetoothTimestamp()1495 void LatencyMonitor::ShowBluetoothTimestamp()
1496 {
1497     AUDIO_INFO_LOG("LatencyMeas RendererMockTime:%{public}s, BTSinkDetectedTime:%{public}s",
1498         rendererMockTime_.c_str(), sinkDetectedTime_.c_str());
1499 }
1500 
GetStreamName(AudioStreamType streamType)1501 const std::string AudioInfoDumpUtils::GetStreamName(AudioStreamType streamType)
1502 {
1503     std::string name;
1504     std::unordered_map<AudioStreamType, std::string> map = STREAM_TYPE_NAME_MAP;
1505     auto it = map.find(streamType);
1506     if (it != map.end()) {
1507         name = it->second;
1508     } else {
1509         name = "UNKNOWN";
1510     }
1511 
1512     const std::string streamName = name;
1513     return streamName;
1514 }
1515 
GetDeviceTypeName(DeviceType deviceType)1516 const std::string AudioInfoDumpUtils::GetDeviceTypeName(DeviceType deviceType)
1517 {
1518     std::string device;
1519     switch (deviceType) {
1520         case DEVICE_TYPE_EARPIECE:
1521             device = "EARPIECE";
1522             break;
1523         case DEVICE_TYPE_SPEAKER:
1524             device = "SPEAKER";
1525             break;
1526         case DEVICE_TYPE_WIRED_HEADSET:
1527             device = "WIRED_HEADSET";
1528             break;
1529         case DEVICE_TYPE_WIRED_HEADPHONES:
1530             device = "WIRED_HEADPHONES";
1531             break;
1532         case DEVICE_TYPE_BLUETOOTH_SCO:
1533              device = "BLUETOOTH_SCO";
1534             break;
1535         case DEVICE_TYPE_BLUETOOTH_A2DP:
1536             device = "BLUETOOTH_A2DP";
1537             break;
1538         case DEVICE_TYPE_MIC:
1539             device = "MIC";
1540             break;
1541         case DEVICE_TYPE_HDMI:
1542             device = "HDMI";
1543             break;
1544         case DEVICE_TYPE_WAKEUP:
1545             device = "WAKEUP";
1546             break;
1547         case DEVICE_TYPE_NONE:
1548             device = "NONE";
1549             break;
1550         case DEVICE_TYPE_INVALID:
1551             device = "INVALID";
1552             break;
1553         default:
1554             device = "UNKNOWN";
1555     }
1556 
1557     const std::string deviceTypeName = device;
1558     return deviceTypeName;
1559 }
1560 
GetConnectTypeName(ConnectType connectType)1561 const std::string AudioInfoDumpUtils::GetConnectTypeName(ConnectType connectType)
1562 {
1563     std::string connectName;
1564     switch (connectType) {
1565         case OHOS::AudioStandard::CONNECT_TYPE_LOCAL:
1566             connectName = "LOCAL";
1567             break;
1568         case OHOS::AudioStandard::CONNECT_TYPE_DISTRIBUTED:
1569             connectName = "REMOTE";
1570             break;
1571         default:
1572             connectName = "UNKNOWN";
1573             break;
1574     }
1575     const std::string connectTypeName = connectName;
1576     return connectTypeName;
1577 }
1578 
GetSourceName(SourceType sourceType)1579 const std::string AudioInfoDumpUtils::GetSourceName(SourceType sourceType)
1580 {
1581     std::string name;
1582     switch (sourceType) {
1583         case SOURCE_TYPE_INVALID:
1584             name = "INVALID";
1585             break;
1586         case SOURCE_TYPE_MIC:
1587             name = "MIC";
1588             break;
1589         case SOURCE_TYPE_CAMCORDER:
1590             name = "CAMCORDER";
1591             break;
1592         case SOURCE_TYPE_VOICE_RECOGNITION:
1593             name = "VOICE_RECOGNITION";
1594             break;
1595         case SOURCE_TYPE_ULTRASONIC:
1596             name = "ULTRASONIC";
1597             break;
1598         case SOURCE_TYPE_VOICE_COMMUNICATION:
1599             name = "VOICE_COMMUNICATION";
1600             break;
1601         case SOURCE_TYPE_WAKEUP:
1602             name = "WAKEUP";
1603             break;
1604         case SOURCE_TYPE_UNPROCESSED:
1605             name = "SOURCE_TYPE_UNPROCESSED";
1606             break;
1607         default:
1608             name = "UNKNOWN";
1609     }
1610 
1611     const std::string sourceName = name;
1612     return sourceName;
1613 }
1614 
GetDeviceVolumeTypeName(DeviceVolumeType deviceType)1615 const std::string AudioInfoDumpUtils::GetDeviceVolumeTypeName(DeviceVolumeType deviceType)
1616 {
1617     std::string device;
1618     switch (deviceType) {
1619         case EARPIECE_VOLUME_TYPE:
1620             device = "EARPIECE";
1621             break;
1622         case SPEAKER_VOLUME_TYPE:
1623             device = "SPEAKER";
1624             break;
1625         case HEADSET_VOLUME_TYPE:
1626             device = "HEADSET";
1627             break;
1628         default:
1629             device = "UNKNOWN";
1630     }
1631 
1632     const std::string deviceTypeName = device;
1633     return deviceTypeName;
1634 }
1635 
1636 bool VolumeUtils::isPCVolumeEnable_ = false;
1637 
1638 std::unordered_map<AudioStreamType, AudioVolumeType> VolumeUtils::defaultVolumeMap_ = {
1639     {STREAM_VOICE_CALL, STREAM_VOICE_CALL},
1640     {STREAM_VOICE_COMMUNICATION, STREAM_VOICE_CALL},
1641     {STREAM_VOICE_CALL_ASSISTANT, STREAM_VOICE_CALL_ASSISTANT},
1642 
1643     {STREAM_RING, STREAM_RING},
1644     {STREAM_SYSTEM, STREAM_RING},
1645     {STREAM_NOTIFICATION, STREAM_RING},
1646     {STREAM_SYSTEM_ENFORCED, STREAM_RING},
1647     {STREAM_DTMF, STREAM_RING},
1648     {STREAM_VOICE_RING, STREAM_RING},
1649 
1650     {STREAM_MUSIC, STREAM_MUSIC},
1651     {STREAM_MEDIA, STREAM_MUSIC},
1652     {STREAM_MOVIE, STREAM_MUSIC},
1653     {STREAM_GAME, STREAM_MUSIC},
1654     {STREAM_SPEECH, STREAM_MUSIC},
1655     {STREAM_NAVIGATION, STREAM_MUSIC},
1656     {STREAM_VOICE_MESSAGE, STREAM_MUSIC},
1657 
1658     {STREAM_VOICE_ASSISTANT, STREAM_VOICE_ASSISTANT},
1659     {STREAM_ALARM, STREAM_ALARM},
1660     {STREAM_ACCESSIBILITY, STREAM_ACCESSIBILITY},
1661     {STREAM_ULTRASONIC, STREAM_ULTRASONIC},
1662     {STREAM_ALL, STREAM_ALL},
1663     {STREAM_APP, STREAM_APP}
1664 };
1665 
1666 std::unordered_map<AudioStreamType, AudioVolumeType> VolumeUtils::audioPCVolumeMap_ = {
1667     {STREAM_VOICE_CALL, STREAM_MUSIC},
1668     {STREAM_VOICE_CALL_ASSISTANT, STREAM_VOICE_CALL_ASSISTANT},
1669     {STREAM_VOICE_MESSAGE, STREAM_MUSIC},
1670     {STREAM_VOICE_ASSISTANT, STREAM_MUSIC},
1671     {STREAM_VOICE_COMMUNICATION, STREAM_MUSIC},
1672     {STREAM_DTMF, STREAM_MUSIC},
1673     {STREAM_MUSIC, STREAM_MUSIC},
1674     {STREAM_MEDIA, STREAM_MUSIC},
1675     {STREAM_MOVIE, STREAM_MUSIC},
1676     {STREAM_GAME, STREAM_MUSIC},
1677     {STREAM_SPEECH, STREAM_MUSIC},
1678     {STREAM_RECORDING, STREAM_MUSIC},
1679     {STREAM_NAVIGATION, STREAM_MUSIC},
1680     {STREAM_ACCESSIBILITY, STREAM_MUSIC},
1681     {STREAM_ALL, STREAM_ALL},
1682 
1683     {STREAM_RING, STREAM_MUSIC},
1684     {STREAM_VOICE_RING, STREAM_MUSIC},
1685     {STREAM_ALARM, STREAM_MUSIC},
1686 
1687     {STREAM_SYSTEM, STREAM_SYSTEM},
1688     {STREAM_NOTIFICATION, STREAM_SYSTEM},
1689     {STREAM_SYSTEM_ENFORCED, STREAM_SYSTEM},
1690 
1691     {STREAM_ULTRASONIC, STREAM_ULTRASONIC},
1692     {STREAM_APP, STREAM_APP}
1693 };
1694 
GetVolumeMap()1695 std::unordered_map<AudioStreamType, AudioVolumeType>& VolumeUtils::GetVolumeMap()
1696 {
1697     if (isPCVolumeEnable_) {
1698         return audioPCVolumeMap_;
1699     } else {
1700         return defaultVolumeMap_;
1701     }
1702 }
1703 
SetPCVolumeEnable(const bool & isPCVolumeEnable)1704 void VolumeUtils::SetPCVolumeEnable(const bool& isPCVolumeEnable)
1705 {
1706     isPCVolumeEnable_ = isPCVolumeEnable;
1707 }
1708 
IsPCVolumeEnable()1709 bool VolumeUtils::IsPCVolumeEnable()
1710 {
1711     return isPCVolumeEnable_;
1712 }
1713 
GetVolumeTypeFromStreamType(AudioStreamType streamType)1714 AudioVolumeType VolumeUtils::GetVolumeTypeFromStreamType(AudioStreamType streamType)
1715 {
1716     std::unordered_map<AudioStreamType, AudioVolumeType> map = GetVolumeMap();
1717     auto it = map.find(streamType);
1718     if (it != map.end()) {
1719         return it->second;
1720     }
1721     return STREAM_MUSIC;
1722 }
1723 
GetEncryptStr(const std::string & src)1724 std::string GetEncryptStr(const std::string &src)
1725 {
1726     if (src.empty()) {
1727         return std::string("");
1728     }
1729 
1730     size_t strLen = src.length();
1731     std::string dst;
1732 
1733     if (strLen < MIN_LEN) {
1734         // src: abcdef
1735         // dst: *bcdef
1736         dst = '*' + src.substr(FIRST_CHAR, strLen - FIRST_CHAR);
1737     } else {
1738         // src: 00:00:00:00:00:00
1739         // dst: 00**********00:00
1740         dst = src.substr(0, HEAD_STR_LEN);
1741         std::string tempStr(strLen - HEAD_STR_LEN - TAIL_STR_LEN, '*');
1742         dst += tempStr;
1743         dst += src.substr(strLen - TAIL_STR_LEN, TAIL_STR_LEN);
1744     }
1745 
1746     return dst;
1747 }
1748 
ConvertNetworkId(const std::string & networkId)1749 std::string ConvertNetworkId(const std::string &networkId)
1750 {
1751     if (!networkId.empty() && networkId != LOCAL_NETWORK_ID) {
1752         return REMOTE_NETWORK_ID;
1753     }
1754 
1755     return networkId;
1756 }
1757 
GenerateUniqueID(AudioHdiUniqueIDBase base,uint32_t offset)1758 uint32_t GenerateUniqueID(AudioHdiUniqueIDBase base, uint32_t offset)
1759 {
1760     return base + offset * UNIQUE_ID_INTERVAL;
1761 }
1762 
GetInstance()1763 AudioDump& AudioDump::GetInstance()
1764 {
1765     static AudioDump mAudioDump;
1766     return mAudioDump;
1767 }
1768 
SetVersionType(const std::string & versionType)1769 void AudioDump::SetVersionType(const std::string& versionType)
1770 {
1771     versionType_ = versionType;
1772 }
1773 
GetVersionType()1774 std::string AudioDump::GetVersionType()
1775 {
1776     return versionType_;
1777 }
1778 } // namespace AudioStandard
1779 } // namespace OHOS
1780 
1781 #ifdef __cplusplus
1782 extern "C" {
1783 #endif
1784 
1785 struct CTrace {
CTraceCTrace1786     explicit CTrace(const char *traceName) : trace(OHOS::AudioStandard::Trace(traceName)) {};
1787     OHOS::AudioStandard::Trace trace;
1788 };
1789 
GetAndStart(const char * traceName)1790 CTrace *GetAndStart(const char *traceName)
1791 {
1792     std::unique_ptr<CTrace> cTrace = std::make_unique<CTrace>(traceName);
1793 
1794     return cTrace.release();
1795 }
1796 
EndCTrace(CTrace * cTrace)1797 void EndCTrace(CTrace *cTrace)
1798 {
1799     if (cTrace != nullptr) {
1800         cTrace->trace.End();
1801     }
1802 }
1803 
CTraceCount(const char * traceName,int64_t count)1804 void CTraceCount(const char *traceName, int64_t count)
1805 {
1806     OHOS::AudioStandard::Trace::Count(traceName, count);
1807 }
1808 
CallEndAndClear(CTrace ** cTrace)1809 void CallEndAndClear(CTrace **cTrace)
1810 {
1811     if (cTrace != nullptr && *cTrace != nullptr) {
1812         EndCTrace(*cTrace);
1813         delete *cTrace;
1814         *cTrace = nullptr;
1815     }
1816 }
1817 
1818 #ifdef __cplusplus
1819 }
1820 #endif
1821