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