• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "AudioUtils"
17 #endif
18 
19 #include "audio_utils.h"
20 #include <cinttypes>
21 #include <ctime>
22 #include <sstream>
23 #include <ostream>
24 #include <climits>
25 #include <thread>
26 #include <string>
27 #include "audio_utils_c.h"
28 #include "audio_errors.h"
29 #include "audio_common_log.h"
30 #ifdef FEATURE_HITRACE_METER
31 #include "hitrace_meter.h"
32 #endif
33 #include "bundle_mgr_interface.h"
34 #include "parameter.h"
35 #include "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> &timestamp)
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 &timestamp)
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 &timestamp)
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