1 /*
2  * Copyright (c) 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  */
15 #include "intell_voice_util.h"
16 #include <sys/stat.h>
17 #include <memory>
18 #include <malloc.h>
19 #include <fcntl.h>
20 #include <cstdio>
21 #include <unistd.h>
22 #include <cinttypes>
23 #include <fstream>
24 #include "string_util.h"
25 #include "accesstoken_kit.h"
26 #include "tokenid_kit.h"
27 #include "ipc_skeleton.h"
28 #include "intell_voice_log.h"
29 
30 #define LOG_TAG "IntellVoiceUtil"
31 
32 namespace OHOS {
33 namespace IntellVoiceUtils {
34 static constexpr uint32_t VERSION_OFFSET = 8;
35 
GetHdiVersionId(uint32_t majorVer,uint32_t minorVer)36 uint32_t IntellVoiceUtil::GetHdiVersionId(uint32_t majorVer, uint32_t minorVer)
37 {
38     return ((majorVer << VERSION_OFFSET) | minorVer);
39 }
40 
DeinterleaveAudioData(const int16_t * buffer,uint32_t size,int32_t channelCnt,std::vector<std::vector<uint8_t>> & audioData)41 bool IntellVoiceUtil::DeinterleaveAudioData(const int16_t *buffer, uint32_t size, int32_t channelCnt,
42     std::vector<std::vector<uint8_t>> &audioData)
43 {
44     if (channelCnt == 0) {
45         INTELL_VOICE_LOG_ERROR("channel cnt is zero");
46         return false;
47     }
48     uint32_t channelLen = size / channelCnt;
49     std::unique_ptr<int16_t[]> channelData = std::make_unique<int16_t[]>(channelLen);
50     if (channelData == nullptr) {
51         INTELL_VOICE_LOG_ERROR("channelData is nullptr");
52         return false;
53     }
54     for (int32_t i = 0; i < channelCnt; i++) {
55         for (uint32_t j = 0; j < channelLen; j++) {
56             channelData[j] = buffer[i + j * channelCnt];
57         }
58         std::vector<uint8_t> item(reinterpret_cast<uint8_t *>(channelData.get()),
59             reinterpret_cast<uint8_t *>(channelData.get()) + channelLen * sizeof(int16_t));
60         audioData.emplace_back(item);
61     }
62     return true;
63 }
64 
ReadFile(const std::string & filePath,std::shared_ptr<uint8_t> & buffer,uint32_t & size)65 bool IntellVoiceUtil::ReadFile(const std::string &filePath, std::shared_ptr<uint8_t> &buffer, uint32_t &size)
66 {
67     std::ifstream file(filePath, std::ios::binary);
68     if (!file.good()) {
69         INTELL_VOICE_LOG_ERROR("open file failed");
70         return false;
71     }
72 
73     file.seekg(0, file.end);
74     size = static_cast<uint32_t>(file.tellg());
75     if (size == 0) {
76         INTELL_VOICE_LOG_ERROR("file is empty");
77         return false;
78     }
79     buffer = std::shared_ptr<uint8_t>(new uint8_t[size], [](uint8_t *p) { delete[] p; });
80     if (buffer == nullptr) {
81         INTELL_VOICE_LOG_ERROR("failed to allocate buffer");
82         return false;
83     }
84 
85     file.seekg(0, file.beg);
86     file.read(reinterpret_cast<char *>(buffer.get()), size);
87     file.close();
88     return true;
89 }
90 
SplitStringToKVPair(const std::string & inputStr,std::map<std::string,std::string> & kvpairs)91 void IntellVoiceUtil::SplitStringToKVPair(const std::string &inputStr, std::map<std::string, std::string> &kvpairs)
92 {
93     std::vector<std::string> paramsList;
94     StringUtil::Split(inputStr, ";", paramsList);
95     for (auto &it : paramsList) {
96         std::string key;
97         std::string value;
98         if (StringUtil::SplitLineToPair(it, key, value)) {
99             kvpairs[key] = value;
100             INTELL_VOICE_LOG_INFO("key:%{public}s, value:%{public}s", key.c_str(), value.c_str());
101         }
102     }
103 }
104 
IsFileExist(const std::string & filePath)105 bool IntellVoiceUtil::IsFileExist(const std::string &filePath)
106 {
107     struct stat sb;
108     if (stat(filePath.c_str(), &sb) != 0) {
109         INTELL_VOICE_LOG_ERROR("get file status failed");
110         return false;
111     }
112 
113     return true;
114 }
115 
VerifyClientPermission(const std::string & permissionName)116 bool IntellVoiceUtil::VerifyClientPermission(const std::string &permissionName)
117 {
118     Security::AccessToken::AccessTokenID clientTokenId = IPCSkeleton::GetCallingTokenID();
119     INTELL_VOICE_LOG_INFO("clientTokenId:%{public}d", clientTokenId);
120     int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(clientTokenId, permissionName);
121     if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
122         INTELL_VOICE_LOG_ERROR("Permission denied!");
123         return false;
124     }
125     return true;
126 }
127 
CheckIsSystemApp()128 bool IntellVoiceUtil::CheckIsSystemApp()
129 {
130     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
131     if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID()) ==
132     Security::AccessToken::TOKEN_NATIVE) {
133         INTELL_VOICE_LOG_INFO("calling by native");
134         return true;
135     }
136 
137     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
138         INTELL_VOICE_LOG_INFO("Not system app, permission reject tokenid: %{public}" PRIu64 "", fullTokenId);
139         return false;
140     }
141 
142     INTELL_VOICE_LOG_INFO("System app, fullTokenId:%{public}" PRIu64 "", fullTokenId);
143     return true;
144 }
145 
VerifySystemPermission(const std::string & permissionName)146 bool IntellVoiceUtil::VerifySystemPermission(const std::string &permissionName)
147 {
148 #ifdef INTELL_VOICE_BUILD_VARIANT_ROOT
149     if (IPCSkeleton::GetCallingUid() == 0) { // 0 for root uid
150         INTELL_VOICE_LOG_INFO("callingUid is root");
151         return true;
152     }
153 #endif
154 
155     if (!CheckIsSystemApp()) {
156         return false;
157     }
158 
159     if (!VerifyClientPermission(permissionName)) {
160         return false;
161     }
162 
163     return true;
164 }
165 }
166 }
167