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_manager.h"
16
17 #include <chrono>
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20 #include "memory_guard.h"
21 #include "scope_guard.h"
22 #include "intell_voice_log.h"
23 #include "intell_voice_service_proxy.h"
24
25 #define LOG_TAG "IntellVoiceManager"
26
27 using namespace std;
28 using namespace OHOS::IntellVoiceEngine;
29
30 namespace OHOS {
31 namespace IntellVoice {
32 constexpr int32_t LOAD_SA_TIMEOUT_S = 4; // 4s
33
IntellVoiceManager()34 IntellVoiceManager::IntellVoiceManager()
35 {
36 INTELL_VOICE_LOG_INFO("enter");
37 }
38
~IntellVoiceManager()39 IntellVoiceManager::~IntellVoiceManager()
40 {
41 INTELL_VOICE_LOG_INFO("enter");
42 }
43
GetInstance()44 IntellVoiceManager *IntellVoiceManager::GetInstance()
45 {
46 static IntellVoiceManager manager;
47 if (!manager.Init()) {
48 return nullptr;
49 }
50 return &manager;
51 }
52
Init()53 bool IntellVoiceManager::Init()
54 {
55 INTELL_VOICE_LOG_INFO("enter");
56 std::unique_lock<std::mutex> lock(mutex_);
57
58 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59 if (samgr == nullptr) {
60 INTELL_VOICE_LOG_ERROR("get sa manager failed");
61 return false;
62 }
63
64 auto object = samgr->LoadSystemAbility(INTELL_VOICE_SERVICE_ID, LOAD_SA_TIMEOUT_S);
65 if (object == nullptr) {
66 INTELL_VOICE_LOG_ERROR("Failed to load systemAbility");
67 return false;
68 }
69
70 g_sProxy = iface_cast<IIntellVoiceService>(object);
71 if (g_sProxy != nullptr) {
72 INTELL_VOICE_LOG_INFO("init Service Proxy success");
73 }
74 INTELL_VOICE_LOG_INFO("Load systemAbility success");
75 return true;
76 }
77
CreateIntellVoiceEngine(IntellVoiceEngineType type,sptr<IIntellVoiceEngine> & inst)78 int32_t IntellVoiceManager::CreateIntellVoiceEngine(IntellVoiceEngineType type, sptr<IIntellVoiceEngine> &inst)
79 {
80 INTELL_VOICE_LOG_INFO("enter");
81 if (g_sProxy == nullptr) {
82 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
83 return -1;
84 }
85 return g_sProxy->CreateIntellVoiceEngine(type, inst);
86 }
87
ReleaseIntellVoiceEngine(IntellVoiceEngineType type)88 int32_t IntellVoiceManager::ReleaseIntellVoiceEngine(IntellVoiceEngineType type)
89 {
90 INTELL_VOICE_LOG_INFO("enter");
91 if (g_sProxy == nullptr) {
92 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
93 return -1;
94 }
95 return g_sProxy->ReleaseIntellVoiceEngine(type);
96 }
97
RegisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)98 int32_t IntellVoiceManager::RegisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)
99 {
100 INTELL_VOICE_LOG_INFO("enter");
101 if (g_sProxy == nullptr) {
102 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
103 return -1;
104 }
105
106 if (callback == nullptr) {
107 INTELL_VOICE_LOG_ERROR("service death recipient is null");
108 return -1;
109 }
110
111 bool ret = g_sProxy->AsObject()->AddDeathRecipient(callback);
112 if (!ret) {
113 INTELL_VOICE_LOG_ERROR("failed to add death recipient");
114 return -1;
115 }
116 return 0;
117 }
118
DeregisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)119 int32_t IntellVoiceManager::DeregisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)
120 {
121 INTELL_VOICE_LOG_INFO("enter");
122 if (g_sProxy == nullptr) {
123 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
124 return -1;
125 }
126
127 if (callback == nullptr) {
128 INTELL_VOICE_LOG_ERROR("service death recipient is null");
129 return -1;
130 }
131
132 bool ret = g_sProxy->AsObject()->RemoveDeathRecipient(callback);
133 if (!ret) {
134 INTELL_VOICE_LOG_ERROR("failed to remove death recipient");
135 return -1;
136 }
137 return 0;
138 }
139
GetUploadFiles(int numMax,std::vector<UploadFilesInfo> & files)140 int32_t IntellVoiceManager::GetUploadFiles(int numMax, std::vector<UploadFilesInfo> &files)
141 {
142 INTELL_VOICE_LOG_INFO("enter, numMax: %{public}d", numMax);
143 CHECK_CONDITION_RETURN_RET(g_sProxy == nullptr, -1, "IntellVoiceService Proxy is null");
144 std::vector<UploadHdiFile> hdiFiles;
145 int32_t ret = g_sProxy->GetUploadFiles(numMax, hdiFiles);
146 if (ret != 0) {
147 INTELL_VOICE_LOG_ERROR("Get upload files failed, ret:%{public}d", ret);
148 return ret;
149 }
150
151 if (hdiFiles.empty()) {
152 INTELL_VOICE_LOG_ERROR("no upload files");
153 return -1;
154 }
155 INTELL_VOICE_LOG_INFO("upload files size:%{public}u", static_cast<uint32_t>(hdiFiles.size()));
156 for (auto hdiFile : hdiFiles) {
157 UploadFilesInfo filesInfo;
158 filesInfo.type = hdiFile.type;
159 filesInfo.filesDescription = hdiFile.filesDescription;
160 for (auto content : hdiFile.filesContent) {
161 if (content == nullptr) {
162 INTELL_VOICE_LOG_ERROR("fileContent is nullptr");
163 continue;
164 }
165 std::vector<uint8_t> fileData;
166 if (GetFileDataFromAshmem(content, fileData) != 0) {
167 INTELL_VOICE_LOG_ERROR("failed to file data from ashmem");
168 continue;
169 }
170 filesInfo.filesContent.push_back(fileData);
171 }
172 files.push_back(filesInfo);
173 }
174 std::vector<UploadHdiFile>().swap(hdiFiles);
175 return 0;
176 }
177
GetFileDataFromAshmem(sptr<Ashmem> ashmem,std::vector<uint8_t> & fileData)178 int32_t IntellVoiceManager::GetFileDataFromAshmem(sptr<Ashmem> ashmem, std::vector<uint8_t> &fileData)
179 {
180 if (ashmem == nullptr) {
181 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
182 return -1;
183 }
184
185 ON_SCOPE_EXIT {
186 ashmem->UnmapAshmem();
187 ashmem->CloseAshmem();
188 };
189
190 uint32_t size = static_cast<uint32_t>(ashmem->GetAshmemSize());
191 if (size == 0) {
192 INTELL_VOICE_LOG_ERROR("size is zero");
193 return -1;
194 }
195
196 if (!ashmem->MapReadOnlyAshmem()) {
197 INTELL_VOICE_LOG_ERROR("map ashmem failed");
198 return -1;
199 }
200
201 const uint8_t *buffer = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
202 if (buffer == nullptr) {
203 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
204 return -1;
205 }
206
207 fileData.insert(fileData.begin(), buffer, buffer + size);
208 return 0;
209 }
210
SetParameter(const std::string & key,const std::string & value)211 int32_t IntellVoiceManager::SetParameter(const std::string &key, const std::string &value)
212 {
213 INTELL_VOICE_LOG_INFO("enter, key:%{public}s, value:%{public}s", key.c_str(), value.c_str());
214 if (g_sProxy == nullptr) {
215 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
216 return -1;
217 }
218 string keyValueList = key + "=" + value;
219 return g_sProxy->SetParameter(keyValueList);
220 }
221
GetParameter(const std::string & key)222 std::string IntellVoiceManager::GetParameter(const std::string &key)
223 {
224 INTELL_VOICE_LOG_INFO("enter");
225 if (g_sProxy == nullptr) {
226 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
227 return "";
228 }
229
230 if (key.empty()) {
231 INTELL_VOICE_LOG_ERROR("key empty");
232 return "";
233 }
234
235 return g_sProxy->GetParameter(key);
236 }
237
GetWakeupSourceFiles(std::vector<WakeupSourceFile> & cloneFileInfo)238 int32_t IntellVoiceManager::GetWakeupSourceFiles(std::vector<WakeupSourceFile> &cloneFileInfo)
239 {
240 INTELL_VOICE_LOG_INFO("enter");
241 if (g_sProxy == nullptr) {
242 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
243 return -1;
244 }
245
246 std::vector<std::string> cloneFiles;
247 int ret = g_sProxy->GetWakeupSourceFilesList(cloneFiles);
248 if (ret != 0) {
249 INTELL_VOICE_LOG_ERROR("get clone list err");
250 return -1;
251 }
252
253 WakeupSourceFile fileInfo;
254 size_t fileCount = cloneFiles.size();
255 cloneFiles.reserve(fileCount);
256
257 for (size_t index = 0; index < fileCount; ++index) {
258 fileInfo.filePath = cloneFiles[index];
259 ret = g_sProxy->GetWakeupSourceFile(cloneFiles[index], fileInfo.fileContent);
260 if (ret != 0) {
261 INTELL_VOICE_LOG_ERROR("get clone file err");
262 return -1;
263 }
264 cloneFileInfo.push_back(fileInfo);
265 }
266
267 return 0;
268 }
269
EnrollWithWakeupFilesForResult(const std::vector<WakeupSourceFile> & cloneFileInfo,const std::string & wakeupInfo,const shared_ptr<IIntellVoiceUpdateCallback> callback)270 int32_t IntellVoiceManager::EnrollWithWakeupFilesForResult(const std::vector<WakeupSourceFile> &cloneFileInfo,
271 const std::string &wakeupInfo, const shared_ptr<IIntellVoiceUpdateCallback> callback)
272 {
273 INTELL_VOICE_LOG_INFO("enter");
274
275 if (g_sProxy == nullptr) {
276 INTELL_VOICE_LOG_ERROR("IntellVoiceService proxy is null");
277 return -1;
278 }
279
280 size_t fileCount = cloneFileInfo.size();
281 for (size_t index = 0; index < fileCount; ++index) {
282 int ret = g_sProxy->SendWakeupFile(cloneFileInfo[index].filePath, cloneFileInfo[index].fileContent);
283 if (ret != 0) {
284 INTELL_VOICE_LOG_ERROR("send clone file err, index:%{public}zu, size:%{public}zu, ret:%{public}d",
285 index, fileCount, ret);
286 return -1;
287 }
288 }
289
290 callback_ = sptr<UpdateCallbackInner>(new (std::nothrow) UpdateCallbackInner());
291 if (callback_ == nullptr) {
292 INTELL_VOICE_LOG_ERROR("callback_ is nullptr");
293 return -1;
294 }
295 callback_->SetUpdateCallback(callback);
296
297 return g_sProxy->EnrollWithWakeupFilesForResult(wakeupInfo, callback_->AsObject());
298 }
299
ClearUserData()300 void IntellVoiceManager::ClearUserData()
301 {
302 INTELL_VOICE_LOG_INFO("enter");
303
304 if (g_sProxy == nullptr) {
305 INTELL_VOICE_LOG_ERROR("IntellVoiceService proxy is nullptr");
306 return;
307 }
308
309 g_sProxy->ClearUserData();
310 }
311 } // namespace IntellVoice
312 } // namespace OHOS