• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2023 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  * Description: common method for cast session
15  * Author: lijianzhao
16  * Create: 2022-01-19
17  */
18 
19 #include "utils.h"
20 
21 #include <cctype>
22 #include <openssl/bio.h>
23 #include <openssl/evp.h>
24 #include <openssl/buffer.h>
25 #include <sys/prctl.h>
26 #include <sys/time.h>
27 
28 #include "wifi_device.h"
29 #include "ohos_account_kits.h"
30 #include "os_account_manager.h"
31 #include "os_account_constants.h"
32 #include "cast_engine_log.h"
33 #include "ipc_skeleton.h"
34 #include "token_setproc.h"
35 #include "power_mgr_client.h"
36 
37 using namespace OHOS::PowerMgr;
38 
39 namespace OHOS {
40 namespace CastEngine {
41 namespace CastEngineService {
42 DEFINE_CAST_ENGINE_LABEL("Cast-Utils");
43 
44 const uint32_t BASE64_UNIT_ONE_PADDING = 1;
45 const uint32_t BASE64_UNIT_TWO_PADDING = 2;
46 const uint32_t BASE64_SRC_UNIT_SIZE = 3;
47 const uint32_t BASE64_DEST_UNIT_SIZE = 4;
48 constexpr static int32_t DEFAULT_OS_ACCOUNT_ID = 100;
49 std::atomic<bool> Utils::isEnablePowerForceTimingOut = false;
50 
Base64Encode(const std::string & source,std::string & encoded)51 bool Utils::Base64Encode(const std::string &source, std::string &encoded)
52 {
53     BIO *bio = BIO_new(BIO_s_mem());
54     if (bio == nullptr) {
55         CLOGE("Base64Encode error: BIO_new failed");
56         return false;
57     }
58     BIO *b64 = BIO_new(BIO_f_base64());
59     if (b64 == nullptr) {
60         CLOGE("Base64Encode error: BIO_f_base64 failed");
61         BIO_free(bio);
62         return false;
63     }
64 
65     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
66     bio = BIO_push(b64, bio);
67     int result = BIO_write(b64, source.c_str(), source.length());
68     if (result <= 0) {
69         CLOGE("Base64Encode error: bio write fail.");
70         BIO_free_all(b64);
71         return false;
72     }
73     BIO_flush(b64);
74 
75     BUF_MEM *bptr = nullptr;
76     bool ret = false;
77     BIO_get_mem_ptr(b64, &bptr);
78     if (bptr != nullptr) {
79         encoded = std::string(bptr->data, bptr->length);
80         ret = true;
81     }
82     BIO_free_all(b64);
83     return ret;
84 }
85 
Base64Decode(const std::string & encoded,std::string & decoded)86 bool Utils::Base64Decode(const std::string &encoded, std::string &decoded)
87 {
88     if (encoded.length() % BASE64_DEST_UNIT_SIZE != 0 || encoded.length() == 0) {
89         return false;
90     }
91 
92     uint32_t decodedLen = encoded.length() * BASE64_SRC_UNIT_SIZE / BASE64_DEST_UNIT_SIZE;
93     if (encoded.at(encoded.length() - BASE64_UNIT_ONE_PADDING) == '=') {
94         decodedLen--;
95         if (encoded.at(encoded.length() - BASE64_UNIT_TWO_PADDING) == '=') {
96             decodedLen--;
97         }
98     }
99 
100     bool ret = false;
101     char* buffer = static_cast<char *>(malloc(decodedLen));
102     if (buffer == nullptr) {
103         return ret;
104     }
105 
106     BIO *bio = BIO_new_mem_buf(encoded.c_str(), encoded.length());
107     if (bio == nullptr) {
108         free(buffer);
109         return ret;
110     }
111 
112     BIO *b64 = BIO_new(BIO_f_base64());
113     if (b64 == nullptr) {
114         CLOGE("Base64Encode error: BIO_f_base64 failed");
115         free(buffer);
116         BIO_free(bio);
117         return false;
118     }
119 
120     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
121     bio = BIO_push(b64, bio);
122     if (BIO_read(b64, buffer, encoded.length()) == static_cast<int32_t>(decodedLen)) {
123         decoded = std::string(buffer, decodedLen);
124         ret = true;
125     }
126 
127     free(buffer);
128     BIO_free_all(b64);
129     return ret;
130 }
131 
SplitString(const std::string & src,std::vector<std::string> & dest,const std::string & seperator)132 void Utils::SplitString(const std::string &src, std::vector<std::string> &dest, const std::string &seperator)
133 {
134     std::string::size_type beginPos = 0;
135     std::string::size_type endPos = src.find(seperator);
136     while (endPos != std::string::npos) {
137         dest.push_back(src.substr(beginPos, endPos - beginPos));
138         beginPos = endPos + seperator.size();
139         endPos = src.find(seperator, beginPos);
140     }
141     if (beginPos != src.length()) {
142         dest.push_back(src.substr(beginPos));
143     }
144 }
145 
Trim(std::string & str)146 std::string &Utils::Trim(std::string &str)
147 {
148     if (str.empty()) {
149         return str;
150     }
151     str.erase(0, str.find_first_not_of(" "));
152     str.erase(str.find_last_not_of(" ") + 1);
153     return str;
154 }
155 
ToLower(std::string & str)156 std::string &Utils::ToLower(std::string &str)
157 {
158     std::locale loc;
159     for (std::string::size_type i = 0; i < str.length(); ++i) {
160         str[i] = std::tolower(str[i], loc);
161     }
162     return str;
163 }
164 
StartWith(const std::string & mainStr,const std::string & subStr)165 bool Utils::StartWith(const std::string &mainStr, const std::string &subStr)
166 {
167     return mainStr.find(subStr) == 0;
168 }
169 
IntToByteArray(int num,int length,uint8_t * output)170 int Utils::IntToByteArray(int num, int length, uint8_t *output)
171 {
172     for (int i = 0; i < length; i++) {
173         output[length - 1 - i] = static_cast<uint8_t>(
174             (static_cast<unsigned int>(num) >> static_cast<unsigned int>(BYTE_TO_BIT_OFFSET * i))) &
175             INT_TO_BYTE;
176     }
177     return length;
178 }
179 
ByteArrayToInt(const uint8_t * input,unsigned int length)180 uint32_t Utils::ByteArrayToInt(const uint8_t *input, unsigned int length)
181 {
182     uint32_t output = 0;
183     if (length > BYTE_TO_BIT_OFFSET) {
184         return output;
185     }
186     for (unsigned int i = 0; i < length; i++) {
187         output |= (input[i] << (BYTE_TO_BIT_OFFSET * (length - 1 - i)));
188     }
189     return output;
190 }
191 
StringToInt(const std::string & str,int base)192 int32_t Utils::StringToInt(const std::string &str, int base)
193 {
194     if (str.size() == 0) {
195         return 0;
196     }
197     char *nextPtr = nullptr;
198     long result = strtol(str.c_str(), &nextPtr, base);
199     if (errno == ERANGE || *nextPtr != '\0') {
200         return 0;
201     }
202     return static_cast<int32_t>(result);
203 }
204 
ConvertIpv4Address(unsigned int addressIpv4)205 std::string Utils::ConvertIpv4Address(unsigned int addressIpv4)
206 {
207     std::string address;
208     if (addressIpv4 == 0) {
209         return address;
210     }
211     std::ostringstream stream;
212     stream<<((addressIpv4>>OHOS::Wifi::BITS_24) & 0xFF)<<"."<<((addressIpv4>>OHOS::Wifi::BITS_16) & 0xFF)<<"."
213           <<((addressIpv4>>OHOS::Wifi::BITS_8) & 0xFF)<<"."<<(addressIpv4 & 0xFF);
214     address = stream.str();
215     return address;
216 }
217 
GetWifiIp()218 std::string Utils::GetWifiIp()
219 {
220     std::shared_ptr<OHOS::Wifi::WifiDevice> wifiDevice = OHOS::Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
221     if (wifiDevice == nullptr) {
222         return "";
223     }
224     OHOS::Wifi::IpInfo ipInfo;
225     ErrCode ret = wifiDevice->GetIpInfo(ipInfo);
226     if (ret != OHOS::Wifi::WIFI_OPT_SUCCESS) {
227         return "";
228     }
229     std::string strIp = Utils::ConvertIpv4Address(ipInfo.ipAddress);
230     return strIp;
231 }
232 
IsArrayAllZero(const uint8_t * input,int length)233 bool Utils::IsArrayAllZero(const uint8_t *input, int length)
234 {
235     bool isAllZero = true;
236     for (int i = 0; i < length; i++) {
237         if (input[i] != 0) {
238             isAllZero = false;
239             break;
240         }
241     }
242     return isAllZero;
243 }
244 
TimeMilliSecond()245 uint64_t Utils::TimeMilliSecond()
246 {
247     struct timeval curTime = {0, 0};
248     gettimeofday(&curTime, nullptr);
249     return static_cast<int64_t>(curTime.tv_sec) * USEC_1000 + curTime.tv_usec / USEC_1000;
250 }
251 
Mask(const std::string & str)252 std::string Utils::Mask(const std::string &str)
253 {
254     if (str.empty() || str.length() <= MASK_MIN_LEN) {
255         return str;
256     } else if (str.length() < (MASK_PRINT_PREFIX_LEN + MASK_PRINT_POSTFIX_LEN)) {
257         return str.substr(0, MASK_MIN_LEN) + "***" + str.substr(str.length() - 1);
258     } else {
259         return str.substr(0, MASK_PRINT_PREFIX_LEN) + "***" + str.substr(str.length() - MASK_PRINT_POSTFIX_LEN);
260     }
261 }
262 
DrmUuidToType(std::string drmUUID)263 DrmType Utils::DrmUuidToType(std::string drmUUID)
264 {
265     if (drmUUID == UUID_CHINADRM) {
266         return DrmType::CHINADRM;
267     } else if (drmUUID == UUID_WIDEVINE) {
268         return DrmType::WIDEVINE;
269     } else if (drmUUID == UUID_PLAYREADY) {
270         return DrmType::PLAYREADY;
271     }
272     return DrmType::DRM_BASE;
273 }
274 
GetCurrentActiveAccountUserId()275 int32_t Utils::GetCurrentActiveAccountUserId()
276 {
277     std::vector<int> activatedOsAccountIds;
278     OHOS::ErrCode res = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds);
279     if (res != OHOS::ERR_OK || activatedOsAccountIds.size() <= 0) {
280         CLOGE("QueryActiveOsAccountIds failed res:%{public}d", res);
281         return DEFAULT_OS_ACCOUNT_ID;
282     }
283 
284     int osAccountId = activatedOsAccountIds[0];
285     if (osAccountId != DEFAULT_OS_ACCOUNT_ID) {
286         CLOGI("currentOsAccount:%{public}d", osAccountId);
287     }
288 
289     return osAccountId;
290 }
291 
GetOhosAccountId()292 std::string Utils::GetOhosAccountId()
293 {
294     AccountSA::OhosAccountInfo accountInfo;
295     OHOS::ErrCode res = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(accountInfo);
296     if (res != OHOS::ERR_OK || accountInfo.uid_ == "") {
297         CLOGE("GetOhosAccountInfo failed res:%{public}d", res);
298         return "";
299     }
300 
301     return accountInfo.uid_;
302 }
303 
SetFirstTokenID()304 int Utils::SetFirstTokenID()
305 {
306     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
307     auto ret = SetFirstCallerTokenID(tokenId);
308     CLOGI("SetFirstCallerTokenID ret %{public}d tokenId %{public}d", ret, tokenId);
309     return ret;
310 }
311 
EnablePowerForceTimingOut()312 void Utils::EnablePowerForceTimingOut()
313 {
314     CLOGI("in");
315     if (isEnablePowerForceTimingOut.load()) {
316         CLOGI("already enable");
317         return;
318     }
319 
320     isEnablePowerForceTimingOut = true;
321     auto& powerMgrClient = PowerMgrClient::GetInstance();
322     // 强制使能超时灭屏
323     powerMgrClient.SetForceTimingOut(true);
324     // 超时锁屏,但有常亮锁时不锁屏(如华为视频播放视频时不锁屏),且不发送熄屏广播
325     powerMgrClient.LockScreenAfterTimingOut(true, true, false);
326 }
327 
ResetPowerForceTimingOut()328 void Utils::ResetPowerForceTimingOut()
329 {
330     CLOGI("in");
331 
332     if (!isEnablePowerForceTimingOut.load()) {
333         CLOGI("already reset");
334         return;
335     }
336     isEnablePowerForceTimingOut = false;
337     auto& powerMgrClient = PowerMgrClient::GetInstance();
338     // 不强制使能超时灭屏
339     powerMgrClient.SetForceTimingOut(false);
340     // 超时锁屏,不受常亮锁影响(如华为视频播放视频时也锁屏),恢复发送熄屏广播
341     powerMgrClient.LockScreenAfterTimingOut(true, false, true);
342 }
343 
LightAndLockScreen()344 void Utils::LightAndLockScreen()
345 {
346     auto& powerMgrClient = PowerMgrClient::GetInstance();
347     // 结束投屏时,如果手机是熄屏状态,要亮屏并锁屏
348     bool isScreenOn = powerMgrClient.IsScreenOn();
349     CLOGI("isScreenOn: %{public}d", isScreenOn);
350     if (!isScreenOn) {
351         PowerErrors wakeupRet = powerMgrClient.WakeupDevice(WakeupDeviceType::WAKEUP_DEVICE_APPLICATION,
352                                                             std::string("cast+ exit playing"));
353         PowerErrors suspendRet = powerMgrClient.SuspendDevice();
354         CLOGI("wakeupRet: %{public}d, suspendRet: %{public}d", wakeupRet, suspendRet);
355     }
356 }
357 
SetThreadName(const std::string & name)358 void Utils::SetThreadName(const std::string &name)
359 {
360     if (name.size() == 0) {
361         return;
362     }
363 
364     static std::atomic<unsigned int> suffix = 0;
365     std::string threadName = name + "-" + std::to_string(suffix++);
366     if (prctl(PR_SET_NAME, threadName.c_str()) < 0) {
367         CLOGE("prctl errno %d", errno);
368     }
369 }
370 
371 } // namespace CastEngineService
372 } // namespace CastEngine
373 } // namespace OHOS
374