15490a39dSopenharmony_ci/* 25490a39dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 35490a39dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45490a39dSopenharmony_ci * you may not use this file except in compliance with the License. 55490a39dSopenharmony_ci * You may obtain a copy of the License at 65490a39dSopenharmony_ci * 75490a39dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85490a39dSopenharmony_ci * 95490a39dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105490a39dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115490a39dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125490a39dSopenharmony_ci * See the License for the specific language governing permissions and 135490a39dSopenharmony_ci * limitations under the License. 145490a39dSopenharmony_ci */ 155490a39dSopenharmony_ci#include "intell_voice_util.h" 165490a39dSopenharmony_ci#include <sys/stat.h> 175490a39dSopenharmony_ci#include <memory> 185490a39dSopenharmony_ci#include <malloc.h> 195490a39dSopenharmony_ci#include <fcntl.h> 205490a39dSopenharmony_ci#include <cstdio> 215490a39dSopenharmony_ci#include <unistd.h> 225490a39dSopenharmony_ci#include <cinttypes> 235490a39dSopenharmony_ci#include <fstream> 245490a39dSopenharmony_ci#include "string_util.h" 255490a39dSopenharmony_ci#include "accesstoken_kit.h" 265490a39dSopenharmony_ci#include "privacy_kit.h" 275490a39dSopenharmony_ci#include "tokenid_kit.h" 285490a39dSopenharmony_ci#include "ipc_skeleton.h" 295490a39dSopenharmony_ci#include "privacy_error.h" 305490a39dSopenharmony_ci#include "intell_voice_log.h" 315490a39dSopenharmony_ci#include "intell_voice_info.h" 325490a39dSopenharmony_ci 335490a39dSopenharmony_ci#define LOG_TAG "IntellVoiceUtil" 345490a39dSopenharmony_ci 355490a39dSopenharmony_ciusing namespace OHOS::IntellVoice; 365490a39dSopenharmony_ci 375490a39dSopenharmony_cinamespace OHOS { 385490a39dSopenharmony_cinamespace IntellVoiceUtils { 395490a39dSopenharmony_cistatic constexpr uint32_t VERSION_OFFSET = 8; 405490a39dSopenharmony_ci 415490a39dSopenharmony_ciuint32_t IntellVoiceUtil::GetHdiVersionId(uint32_t majorVer, uint32_t minorVer) 425490a39dSopenharmony_ci{ 435490a39dSopenharmony_ci return ((majorVer << VERSION_OFFSET) | minorVer); 445490a39dSopenharmony_ci} 455490a39dSopenharmony_ci 465490a39dSopenharmony_cibool IntellVoiceUtil::DeinterleaveAudioData(const int16_t *buffer, uint32_t size, int32_t channelCnt, 475490a39dSopenharmony_ci std::vector<std::vector<uint8_t>> &audioData) 485490a39dSopenharmony_ci{ 495490a39dSopenharmony_ci if (channelCnt == 0) { 505490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("channel cnt is zero"); 515490a39dSopenharmony_ci return false; 525490a39dSopenharmony_ci } 535490a39dSopenharmony_ci uint32_t channelLen = size / channelCnt; 545490a39dSopenharmony_ci std::unique_ptr<int16_t[]> channelData = std::make_unique<int16_t[]>(channelLen); 555490a39dSopenharmony_ci if (channelData == nullptr) { 565490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("channelData is nullptr"); 575490a39dSopenharmony_ci return false; 585490a39dSopenharmony_ci } 595490a39dSopenharmony_ci for (int32_t i = 0; i < channelCnt; i++) { 605490a39dSopenharmony_ci for (uint32_t j = 0; j < channelLen; j++) { 615490a39dSopenharmony_ci channelData[j] = buffer[i + j * channelCnt]; 625490a39dSopenharmony_ci } 635490a39dSopenharmony_ci std::vector<uint8_t> item(reinterpret_cast<uint8_t *>(channelData.get()), 645490a39dSopenharmony_ci reinterpret_cast<uint8_t *>(channelData.get()) + channelLen * sizeof(int16_t)); 655490a39dSopenharmony_ci audioData.emplace_back(item); 665490a39dSopenharmony_ci } 675490a39dSopenharmony_ci return true; 685490a39dSopenharmony_ci} 695490a39dSopenharmony_ci 705490a39dSopenharmony_cibool IntellVoiceUtil::ReadFile(const std::string &filePath, std::shared_ptr<uint8_t> &buffer, uint32_t &size) 715490a39dSopenharmony_ci{ 725490a39dSopenharmony_ci std::ifstream file(filePath, std::ios::binary); 735490a39dSopenharmony_ci if (!file.good()) { 745490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("open file failed"); 755490a39dSopenharmony_ci return false; 765490a39dSopenharmony_ci } 775490a39dSopenharmony_ci 785490a39dSopenharmony_ci file.seekg(0, file.end); 795490a39dSopenharmony_ci size = static_cast<uint32_t>(file.tellg()); 805490a39dSopenharmony_ci if (size == 0) { 815490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("file is empty"); 825490a39dSopenharmony_ci return false; 835490a39dSopenharmony_ci } 845490a39dSopenharmony_ci buffer = std::shared_ptr<uint8_t>(new uint8_t[size], [](uint8_t *p) { delete[] p; }); 855490a39dSopenharmony_ci if (buffer == nullptr) { 865490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("failed to allocate buffer"); 875490a39dSopenharmony_ci return false; 885490a39dSopenharmony_ci } 895490a39dSopenharmony_ci 905490a39dSopenharmony_ci file.seekg(0, file.beg); 915490a39dSopenharmony_ci file.read(reinterpret_cast<char *>(buffer.get()), size); 925490a39dSopenharmony_ci file.close(); 935490a39dSopenharmony_ci return true; 945490a39dSopenharmony_ci} 955490a39dSopenharmony_ci 965490a39dSopenharmony_civoid IntellVoiceUtil::SplitStringToKVPair(const std::string &inputStr, std::map<std::string, std::string> &kvpairs) 975490a39dSopenharmony_ci{ 985490a39dSopenharmony_ci std::vector<std::string> paramsList; 995490a39dSopenharmony_ci StringUtil::Split(inputStr, ";", paramsList); 1005490a39dSopenharmony_ci for (const auto &it : paramsList) { 1015490a39dSopenharmony_ci std::string key; 1025490a39dSopenharmony_ci std::string value; 1035490a39dSopenharmony_ci if (StringUtil::SplitLineToPair(it, key, value)) { 1045490a39dSopenharmony_ci kvpairs[key] = value; 1055490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("key:%{public}s, value:%{public}s", key.c_str(), value.c_str()); 1065490a39dSopenharmony_ci } 1075490a39dSopenharmony_ci } 1085490a39dSopenharmony_ci} 1095490a39dSopenharmony_ci 1105490a39dSopenharmony_cibool IntellVoiceUtil::IsFileExist(const std::string &filePath) 1115490a39dSopenharmony_ci{ 1125490a39dSopenharmony_ci struct stat sb; 1135490a39dSopenharmony_ci if (stat(filePath.c_str(), &sb) != 0) { 1145490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("get file status failed"); 1155490a39dSopenharmony_ci return false; 1165490a39dSopenharmony_ci } 1175490a39dSopenharmony_ci 1185490a39dSopenharmony_ci return true; 1195490a39dSopenharmony_ci} 1205490a39dSopenharmony_ci 1215490a39dSopenharmony_cibool IntellVoiceUtil::VerifyClientPermission(const std::string &permissionName) 1225490a39dSopenharmony_ci{ 1235490a39dSopenharmony_ci Security::AccessToken::AccessTokenID clientTokenId = IPCSkeleton::GetCallingTokenID(); 1245490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("clientTokenId:%{public}d, permission name:%{public}s", clientTokenId, 1255490a39dSopenharmony_ci permissionName.c_str()); 1265490a39dSopenharmony_ci int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(clientTokenId, permissionName); 1275490a39dSopenharmony_ci if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 1285490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("Permission denied"); 1295490a39dSopenharmony_ci return false; 1305490a39dSopenharmony_ci } 1315490a39dSopenharmony_ci return true; 1325490a39dSopenharmony_ci} 1335490a39dSopenharmony_ci 1345490a39dSopenharmony_cibool IntellVoiceUtil::CheckIsSystemApp() 1355490a39dSopenharmony_ci{ 1365490a39dSopenharmony_ci uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID(); 1375490a39dSopenharmony_ci if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID()) == 1385490a39dSopenharmony_ci Security::AccessToken::TOKEN_NATIVE) { 1395490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("calling by native"); 1405490a39dSopenharmony_ci return true; 1415490a39dSopenharmony_ci } 1425490a39dSopenharmony_ci 1435490a39dSopenharmony_ci if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) { 1445490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("Not system app, permission reject tokenid: %{public}" PRIu64 "", fullTokenId); 1455490a39dSopenharmony_ci return false; 1465490a39dSopenharmony_ci } 1475490a39dSopenharmony_ci 1485490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("System app, fullTokenId:%{public}" PRIu64 "", fullTokenId); 1495490a39dSopenharmony_ci return true; 1505490a39dSopenharmony_ci} 1515490a39dSopenharmony_ci 1525490a39dSopenharmony_ciint32_t IntellVoiceUtil::VerifySystemPermission(const std::string &permissionName) 1535490a39dSopenharmony_ci{ 1545490a39dSopenharmony_ci#ifdef INTELL_VOICE_BUILD_VARIANT_ROOT 1555490a39dSopenharmony_ci if (IPCSkeleton::GetCallingUid() == 0) { // 0 for root uid 1565490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("callingUid is root"); 1575490a39dSopenharmony_ci return INTELLIGENT_VOICE_SUCCESS; 1585490a39dSopenharmony_ci } 1595490a39dSopenharmony_ci#endif 1605490a39dSopenharmony_ci 1615490a39dSopenharmony_ci if (!CheckIsSystemApp()) { 1625490a39dSopenharmony_ci return INTELLIGENT_VOICE_NOT_SYSTEM_APPLICATION; 1635490a39dSopenharmony_ci } 1645490a39dSopenharmony_ci 1655490a39dSopenharmony_ci if (!VerifyClientPermission(permissionName)) { 1665490a39dSopenharmony_ci return INTELLIGENT_VOICE_PERMISSION_DENIED; 1675490a39dSopenharmony_ci } 1685490a39dSopenharmony_ci 1695490a39dSopenharmony_ci return INTELLIGENT_VOICE_SUCCESS; 1705490a39dSopenharmony_ci} 1715490a39dSopenharmony_ci 1725490a39dSopenharmony_cibool IntellVoiceUtil::RecordPermissionPrivacy(const std::string &permissionName, uint32_t targetTokenId, 1735490a39dSopenharmony_ci IntellVoicePermissionState state) 1745490a39dSopenharmony_ci{ 1755490a39dSopenharmony_ci INTELL_VOICE_LOG_INFO("permissionName:%{public}s, tokenId:%{public}u, state:%{public}d", permissionName.c_str(), 1765490a39dSopenharmony_ci targetTokenId, state); 1775490a39dSopenharmony_ci if (state == INTELL_VOICE_PERMISSION_START) { 1785490a39dSopenharmony_ci auto ret = Security::AccessToken::PrivacyKit::StartUsingPermission(targetTokenId, permissionName); 1795490a39dSopenharmony_ci if (ret != 0 && ret != Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING) { 1805490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("StartUsingPermission for tokenId %{public}u, ret is %{public}d", 1815490a39dSopenharmony_ci targetTokenId, ret); 1825490a39dSopenharmony_ci return false; 1835490a39dSopenharmony_ci } 1845490a39dSopenharmony_ci ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(targetTokenId, permissionName, 1, 0); 1855490a39dSopenharmony_ci if (ret != 0 && ret != Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING) { 1865490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("AddPermissionUsedRecord for tokenId %{public}u! The PrivacyKit error code is " 1875490a39dSopenharmony_ci "%{public}d", targetTokenId, ret); 1885490a39dSopenharmony_ci return false; 1895490a39dSopenharmony_ci } 1905490a39dSopenharmony_ci } else if (state == INTELL_VOICE_PERMISSION_STOP) { 1915490a39dSopenharmony_ci auto ret = Security::AccessToken::PrivacyKit::StopUsingPermission(targetTokenId, permissionName); 1925490a39dSopenharmony_ci if (ret != 0) { 1935490a39dSopenharmony_ci INTELL_VOICE_LOG_ERROR("StopUsingPermission for tokenId %{public}u, ret is %{public}d", 1945490a39dSopenharmony_ci targetTokenId, ret); 1955490a39dSopenharmony_ci return false; 1965490a39dSopenharmony_ci } 1975490a39dSopenharmony_ci } else { 1985490a39dSopenharmony_ci INTELL_VOICE_LOG_WARN("invalid state"); 1995490a39dSopenharmony_ci return false; 2005490a39dSopenharmony_ci } 2015490a39dSopenharmony_ci 2025490a39dSopenharmony_ci return true; 2035490a39dSopenharmony_ci} 2045490a39dSopenharmony_ci} 2055490a39dSopenharmony_ci} 206