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 ×tamp)
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 ×tamp)
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