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