• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "privacy_kit.h"
27 #include "tokenid_kit.h"
28 #include "ipc_skeleton.h"
29 #include "privacy_error.h"
30 #include "intell_voice_log.h"
31 #include "intell_voice_info.h"
32 #include "ability_manager_client.h"
33 #include "history_info_mgr.h"
34 
35 #define LOG_TAG "IntellVoiceUtil"
36 
37 using namespace OHOS::IntellVoice;
38 
39 namespace OHOS {
40 namespace IntellVoiceUtils {
41 static constexpr uint32_t VERSION_OFFSET = 8;
42 
GetHdiVersionId(uint32_t majorVer,uint32_t minorVer)43 uint32_t IntellVoiceUtil::GetHdiVersionId(uint32_t majorVer, uint32_t minorVer)
44 {
45     return ((majorVer << VERSION_OFFSET) | minorVer);
46 }
47 
DeinterleaveAudioData(const int16_t * buffer,uint32_t size,int32_t channelCnt,std::vector<std::vector<uint8_t>> & audioData)48 bool IntellVoiceUtil::DeinterleaveAudioData(const int16_t *buffer, uint32_t size, int32_t channelCnt,
49     std::vector<std::vector<uint8_t>> &audioData)
50 {
51     if (channelCnt == 0) {
52         INTELL_VOICE_LOG_ERROR("channel cnt is zero");
53         return false;
54     }
55     uint32_t channelLen = size / channelCnt;
56     std::unique_ptr<int16_t[]> channelData = std::make_unique<int16_t[]>(channelLen);
57     if (channelData == nullptr) {
58         INTELL_VOICE_LOG_ERROR("channelData is nullptr");
59         return false;
60     }
61     for (int32_t i = 0; i < channelCnt; i++) {
62         for (uint32_t j = 0; j < channelLen; j++) {
63             channelData[j] = buffer[i + j * channelCnt];
64         }
65         std::vector<uint8_t> item(reinterpret_cast<uint8_t *>(channelData.get()),
66             reinterpret_cast<uint8_t *>(channelData.get()) + channelLen * sizeof(int16_t));
67         audioData.emplace_back(item);
68     }
69     return true;
70 }
71 
ReadFile(const std::string & filePath,std::shared_ptr<uint8_t> & buffer,uint32_t & size)72 bool IntellVoiceUtil::ReadFile(const std::string &filePath, std::shared_ptr<uint8_t> &buffer, uint32_t &size)
73 {
74     std::ifstream file(filePath, std::ios::binary);
75     if (!file.good()) {
76         INTELL_VOICE_LOG_ERROR("open file failed");
77         return false;
78     }
79 
80     file.seekg(0, file.end);
81     size = static_cast<uint32_t>(file.tellg());
82     if (size == 0) {
83         INTELL_VOICE_LOG_ERROR("file is empty");
84         return false;
85     }
86     buffer = std::shared_ptr<uint8_t>(new uint8_t[size], [](uint8_t *p) { delete[] p; });
87     if (buffer == nullptr) {
88         INTELL_VOICE_LOG_ERROR("failed to allocate buffer");
89         return false;
90     }
91 
92     file.seekg(0, file.beg);
93     file.read(reinterpret_cast<char *>(buffer.get()), size);
94     file.close();
95     return true;
96 }
97 
SplitStringToKVPair(const std::string & inputStr,std::map<std::string,std::string> & kvpairs)98 void IntellVoiceUtil::SplitStringToKVPair(const std::string &inputStr, std::map<std::string, std::string> &kvpairs)
99 {
100     std::vector<std::string> paramsList;
101     StringUtil::Split(inputStr, ";", paramsList);
102     for (const auto &it : paramsList) {
103         std::string key;
104         std::string value;
105         if (StringUtil::SplitLineToPair(it, key, value)) {
106             kvpairs[key] = value;
107             INTELL_VOICE_LOG_INFO("key:%{public}s, value:%{public}s", key.c_str(), value.c_str());
108         }
109     }
110 }
111 
IsFileExist(const std::string & filePath)112 bool IntellVoiceUtil::IsFileExist(const std::string &filePath)
113 {
114     struct stat sb;
115     if (stat(filePath.c_str(), &sb) != 0) {
116         INTELL_VOICE_LOG_ERROR("get file status failed");
117         return false;
118     }
119 
120     return true;
121 }
122 
VerifyClientPermission(const std::string & permissionName)123 bool IntellVoiceUtil::VerifyClientPermission(const std::string &permissionName)
124 {
125     Security::AccessToken::AccessTokenID clientTokenId = IPCSkeleton::GetCallingTokenID();
126     INTELL_VOICE_LOG_INFO("clientTokenId:%{public}d, permission name:%{public}s", clientTokenId,
127         permissionName.c_str());
128     int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(clientTokenId, permissionName);
129     if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
130         INTELL_VOICE_LOG_ERROR("Permission denied");
131         return false;
132     }
133     return true;
134 }
135 
CheckIsSystemApp()136 bool IntellVoiceUtil::CheckIsSystemApp()
137 {
138     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
139     if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID()) ==
140         Security::AccessToken::TOKEN_NATIVE) {
141         INTELL_VOICE_LOG_INFO("calling by native");
142         return true;
143     }
144 
145     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
146         INTELL_VOICE_LOG_INFO("Not system app, permission reject tokenid: %{public}" PRIu64 "", fullTokenId);
147         return false;
148     }
149 
150     INTELL_VOICE_LOG_INFO("System app, fullTokenId:%{public}" PRIu64 "", fullTokenId);
151     return true;
152 }
153 
VerifySystemPermission(const std::string & permissionName)154 int32_t IntellVoiceUtil::VerifySystemPermission(const std::string &permissionName)
155 {
156 #ifdef INTELL_VOICE_BUILD_VARIANT_ROOT
157     if (IPCSkeleton::GetCallingUid() == 0) { // 0 for root uid
158         INTELL_VOICE_LOG_INFO("callingUid is root");
159         return INTELLIGENT_VOICE_SUCCESS;
160     }
161 #endif
162 
163     if (!CheckIsSystemApp()) {
164         return INTELLIGENT_VOICE_NOT_SYSTEM_APPLICATION;
165     }
166 
167     if (!VerifyClientPermission(permissionName)) {
168         return INTELLIGENT_VOICE_PERMISSION_DENIED;
169     }
170     return INTELLIGENT_VOICE_SUCCESS;
171 }
172 
RecordPermissionPrivacy(const std::string & permissionName,uint32_t targetTokenId,IntellVoicePermissionState state)173 bool IntellVoiceUtil::RecordPermissionPrivacy(const std::string &permissionName, uint32_t targetTokenId,
174     IntellVoicePermissionState state)
175 {
176     INTELL_VOICE_LOG_INFO("permissionName:%{public}s, tokenId:%{public}u, state:%{public}d", permissionName.c_str(),
177         targetTokenId, state);
178     if (state == INTELL_VOICE_PERMISSION_START) {
179         auto ret = Security::AccessToken::PrivacyKit::StartUsingPermission(targetTokenId, permissionName);
180         if (ret != 0 && ret != Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING) {
181             INTELL_VOICE_LOG_ERROR("StartUsingPermission for tokenId %{public}u, ret is %{public}d",
182                 targetTokenId, ret);
183             return false;
184         }
185         ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(targetTokenId, permissionName, 1, 0);
186         if (ret != 0 && ret != Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING) {
187             INTELL_VOICE_LOG_ERROR("AddPermissionUsedRecord for tokenId %{public}u! The PrivacyKit error code is "
188                 "%{public}d", targetTokenId, ret);
189             return false;
190         }
191     } else if (state == INTELL_VOICE_PERMISSION_STOP) {
192         auto ret = Security::AccessToken::PrivacyKit::StopUsingPermission(targetTokenId, permissionName);
193         if (ret != 0) {
194             INTELL_VOICE_LOG_ERROR("StopUsingPermission for tokenId %{public}u, ret is %{public}d",
195                 targetTokenId, ret);
196             return false;
197         }
198     } else {
199         INTELL_VOICE_LOG_WARN("invalid state");
200         return false;
201     }
202 
203     return true;
204 }
205 
StartAbility(const std::string & event)206 void IntellVoiceUtil::StartAbility(const std::string &event)
207 {
208     AAFwk::Want want;
209     HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
210 
211     std::string bundleName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_BUNDLE_NAME);
212     std::string abilityName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_ABILITY_NAME);
213     INTELL_VOICE_LOG_INFO("bundleName:%{public}s, abilityName:%{public}s", bundleName.c_str(), abilityName.c_str());
214     if (bundleName.empty() || abilityName.empty()) {
215         INTELL_VOICE_LOG_ERROR("bundle name is empty or ability name is empty");
216         return;
217     }
218     want.SetElementName(bundleName, abilityName);
219     want.SetParam("serviceName", std::string("intell_voice"));
220     want.SetParam("servicePid", getpid());
221     want.SetParam("eventType", event);
222     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
223     if (abilityManagerClient == nullptr) {
224         INTELL_VOICE_LOG_ERROR("abilityManagerClient is nullptr");
225         return;
226     }
227     abilityManagerClient->StartAbility(want);
228 }
229 }
230 }
231