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
16 #include <cinttypes>
17 #include <ctime>
18 #include <sstream>
19 #include <ostream>
20 #include "audio_utils.h"
21 #include "audio_log.h"
22 #ifdef FEATURE_HITRACE_METER
23 #include "hitrace_meter.h"
24 #endif
25 #include "parameter.h"
26 #include "tokenid_kit.h"
27 #include "ipc_skeleton.h"
28 #include "access_token.h"
29 #include "accesstoken_kit.h"
30
31 using OHOS::Security::AccessToken::AccessTokenKit;
32
33 namespace OHOS {
34 namespace AudioStandard {
GetCurNano()35 int64_t ClockTime::GetCurNano()
36 {
37 int64_t result = -1; // -1 for bad result.
38 struct timespec time;
39 clockid_t clockId = CLOCK_MONOTONIC;
40 int ret = clock_gettime(clockId, &time);
41 if (ret < 0) {
42 AUDIO_WARNING_LOG("GetCurNanoTime fail, result:%{public}d", ret);
43 return result;
44 }
45 result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
46 return result;
47 }
48
AbsoluteSleep(int64_t nanoTime)49 int32_t ClockTime::AbsoluteSleep(int64_t nanoTime)
50 {
51 int32_t ret = -1; // -1 for bad result.
52 if (nanoTime <= 0) {
53 AUDIO_WARNING_LOG("AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
54 return ret;
55 }
56 struct timespec time;
57 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
58 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
59
60 clockid_t clockId = CLOCK_MONOTONIC;
61 ret = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
62 if (ret != 0) {
63 AUDIO_WARNING_LOG("AbsoluteSleep may failed, ret is :%{public}d", ret);
64 }
65
66 return ret;
67 }
68
RelativeSleep(int64_t nanoTime)69 int32_t ClockTime::RelativeSleep(int64_t nanoTime)
70 {
71 int32_t ret = -1; // -1 for bad result.
72 if (nanoTime <= 0) {
73 AUDIO_WARNING_LOG("AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
74 return ret;
75 }
76 struct timespec time;
77 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
78 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
79
80 clockid_t clockId = CLOCK_MONOTONIC;
81 const int relativeFlag = 0; // flag of relative sleep.
82 ret = clock_nanosleep(clockId, relativeFlag, &time, nullptr);
83 if (ret != 0) {
84 AUDIO_WARNING_LOG("RelativeSleep may failed, ret is :%{public}d", ret);
85 }
86
87 return ret;
88 }
89
Count(const std::string & value,int64_t count,bool isEnable)90 void Trace::Count(const std::string &value, int64_t count, bool isEnable)
91 {
92 #ifdef FEATURE_HITRACE_METER
93 CountTraceDebug(isEnable, HITRACE_TAG_ZAUDIO, value, count);
94 #endif
95 }
96
Trace(const std::string & value,bool isShowLog,bool isEnable)97 Trace::Trace(const std::string &value, bool isShowLog, bool isEnable)
98 {
99 value_ = value;
100 isShowLog_ = isShowLog;
101 isEnable_ = isEnable;
102 isFinished_ = false;
103 #ifdef FEATURE_HITRACE_METER
104 if (isShowLog) {
105 isShowLog_ = true;
106 AUDIO_INFO_LOG("%{public}s start.", value_.c_str());
107 }
108 StartTraceDebug(isEnable_, HITRACE_TAG_ZAUDIO, value);
109 #endif
110 }
111
End()112 void Trace::End()
113 {
114 #ifdef FEATURE_HITRACE_METER
115 if (!isFinished_) {
116 FinishTraceDebug(isEnable_, HITRACE_TAG_ZAUDIO);
117 isFinished_ = true;
118 if (isShowLog_) {
119 AUDIO_INFO_LOG("%{public}s end.", value_.c_str());
120 }
121 }
122 #endif
123 }
124
~Trace()125 Trace::~Trace()
126 {
127 End();
128 }
129
VerifyIsSystemApp()130 bool PermissionUtil::VerifyIsSystemApp()
131 {
132 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
133 if (Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
134 return true;
135 }
136
137 AUDIO_ERR_LOG("Check system app permission reject");
138 return false;
139 }
140
VerifySelfPermission()141 bool PermissionUtil::VerifySelfPermission()
142 {
143 Security::AccessToken::FullTokenID selfToken = IPCSkeleton::GetSelfTokenID();
144
145 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfToken));
146 if (tokenTypeFlag == Security::AccessToken::TOKEN_NATIVE) {
147 return true;
148 }
149
150 if (tokenTypeFlag == Security::AccessToken::TOKEN_SHELL) {
151 return true;
152 }
153
154 if (Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
155 return true;
156 }
157
158 AUDIO_ERR_LOG("Check self app permission reject");
159 return false;
160 }
161
VerifySystemPermission()162 bool PermissionUtil::VerifySystemPermission()
163 {
164 auto tokenId = IPCSkeleton::GetCallingTokenID();
165 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
166 if (tokenTypeFlag == Security::AccessToken::TOKEN_NATIVE) {
167 return true;
168 }
169
170 if (tokenTypeFlag == Security::AccessToken::TOKEN_SHELL) {
171 return true;
172 }
173
174 if (VerifyIsSystemApp()) {
175 return true;
176 }
177
178 AUDIO_ERR_LOG("Check system permission reject");
179 return false;
180 }
181
AdjustStereoToMonoForPCM8Bit(int8_t * data,uint64_t len)182 void AdjustStereoToMonoForPCM8Bit(int8_t *data, uint64_t len)
183 {
184 for (unsigned i = len >> 1; i > 0; i--) {
185 // the number 2 is the count of stereo audio channels
186 data[0] = data[0] / 2 + data[1] / 2;
187 data[1] = data[0];
188 data += 2;
189 }
190 }
191
AdjustStereoToMonoForPCM16Bit(int16_t * data,uint64_t len)192 void AdjustStereoToMonoForPCM16Bit(int16_t *data, uint64_t len)
193 {
194 for (unsigned i = len >> 1; i > 0; i--) {
195 // the number 2 is the count of stereo audio channels
196 data[0] = data[0] / 2 + data[1] / 2;
197 data[1] = data[0];
198 data += 2;
199 }
200 }
201
AdjustStereoToMonoForPCM24Bit(int8_t * data,uint64_t len)202 void AdjustStereoToMonoForPCM24Bit(int8_t *data, uint64_t len)
203 {
204 // int8_t is used for reading data of PCM24BIT here
205 // 24 / 8 = 3, so we need repeat the calculation three times in each loop
206 for (unsigned i = len >> 1; i > 0; i--) {
207 // the number 2 is the count of stereo audio channels, 2 * 3 = 6
208 data[0] = data[0] / 2 + data[3] / 2;
209 data[3] = data[0];
210 data[1] = data[1] / 2 + data[4] / 2;
211 data[4] = data[1];
212 data[2] = data[2] / 2 + data[5] / 2;
213 data[5] = data[2];
214 data += 6;
215 }
216 }
217
AdjustStereoToMonoForPCM32Bit(int32_t * data,uint64_t len)218 void AdjustStereoToMonoForPCM32Bit(int32_t *data, uint64_t len)
219 {
220 for (unsigned i = len >> 1; i > 0; i--) {
221 // the number 2 is the count of stereo audio channels
222 data[0] = data[0] / 2 + data[1] / 2;
223 data[1] = data[0];
224 data += 2;
225 }
226 }
227
AdjustAudioBalanceForPCM8Bit(int8_t * data,uint64_t len,float left,float right)228 void AdjustAudioBalanceForPCM8Bit(int8_t *data, uint64_t len, float left, float right)
229 {
230 for (unsigned i = len >> 1; i > 0; i--) {
231 // the number 2 is the count of stereo audio channels
232 data[0] *= left;
233 data[1] *= right;
234 data += 2;
235 }
236 }
237
AdjustAudioBalanceForPCM16Bit(int16_t * data,uint64_t len,float left,float right)238 void AdjustAudioBalanceForPCM16Bit(int16_t *data, uint64_t len, float left, float right)
239 {
240 for (unsigned i = len >> 1; i > 0; i--) {
241 // the number 2 is the count of stereo audio channels
242 data[0] *= left;
243 data[1] *= right;
244 data += 2;
245 }
246 }
247
AdjustAudioBalanceForPCM24Bit(int8_t * data,uint64_t len,float left,float right)248 void AdjustAudioBalanceForPCM24Bit(int8_t *data, uint64_t len, float left, float right)
249 {
250 // int8_t is used for reading data of PCM24BIT here
251 // 24 / 8 = 3, so we need repeat the calculation three times in each loop
252 for (unsigned i = len >> 1; i > 0; i--) {
253 // the number 2 is the count of stereo audio channels, 2 * 3 = 6
254 data[0] *= left;
255 data[1] *= left;
256 data[2] *= left;
257 data[3] *= right;
258 data[4] *= right;
259 data[5] *= right;
260 data += 6;
261 }
262 }
263
AdjustAudioBalanceForPCM32Bit(int32_t * data,uint64_t len,float left,float right)264 void AdjustAudioBalanceForPCM32Bit(int32_t *data, uint64_t len, float left, float right)
265 {
266 for (unsigned i = len >> 1; i > 0; i--) {
267 // the number 2 is the count of stereo audio channels
268 data[0] *= left;
269 data[1] *= right;
270 data += 2;
271 }
272 }
273
274 template <typename T>
GetSysPara(const char * key,T & value)275 bool GetSysPara(const char *key, T &value)
276 {
277 if (key == nullptr) {
278 AUDIO_ERR_LOG("GetSysPara: key is nullptr");
279 return false;
280 }
281 char paraValue[20] = {0}; // 20 for system parameter
282 auto res = GetParameter(key, "-1", paraValue, sizeof(paraValue));
283 if (res <= 0) {
284 AUDIO_WARNING_LOG("GetSysPara fail, key:%{public}s res:%{public}d", key, res);
285 return false;
286 }
287 AUDIO_INFO_LOG("GetSysPara: key:%{public}s value:%{public}s", key, paraValue);
288 std::stringstream valueStr;
289 valueStr << paraValue;
290 valueStr >> value;
291 return true;
292 }
293
294 template bool GetSysPara(const char *key, int32_t &value);
295 template bool GetSysPara(const char *key, uint32_t &value);
296 template bool GetSysPara(const char *key, int64_t &value);
297 template bool GetSysPara(const char *key, std::string &value);
298 } // namespace AudioStandard
299 } // namespace OHOS
300