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
CreateHeadsetWakeupEngine()88 std::shared_ptr<WakeupIntellVoiceEngine> IntellVoiceManager::CreateHeadsetWakeupEngine()
89 {
90 INTELL_VOICE_LOG_INFO("enter");
91 WakeupIntelligentVoiceEngineDescriptor descriptor = {false, "小艺小艺"};
92 return std::make_shared<WakeupIntellVoiceEngine>(descriptor, INTELL_VOICE_HEADSET_WAKEUP);
93 }
94
ReleaseIntellVoiceEngine(IntellVoiceEngineType type)95 int32_t IntellVoiceManager::ReleaseIntellVoiceEngine(IntellVoiceEngineType type)
96 {
97 INTELL_VOICE_LOG_INFO("enter");
98 if (g_sProxy == nullptr) {
99 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
100 return -1;
101 }
102 return g_sProxy->ReleaseIntellVoiceEngine(type);
103 }
104
RegisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)105 int32_t IntellVoiceManager::RegisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)
106 {
107 INTELL_VOICE_LOG_INFO("enter");
108 if (g_sProxy == nullptr) {
109 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
110 return -1;
111 }
112
113 if (callback == nullptr) {
114 INTELL_VOICE_LOG_ERROR("service death recipient is null");
115 return -1;
116 }
117
118 bool ret = g_sProxy->AsObject()->AddDeathRecipient(callback);
119 if (!ret) {
120 INTELL_VOICE_LOG_ERROR("failed to add death recipient");
121 return -1;
122 }
123 return 0;
124 }
125
DeregisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)126 int32_t IntellVoiceManager::DeregisterServiceDeathRecipient(sptr<OHOS::IRemoteObject::DeathRecipient> callback)
127 {
128 INTELL_VOICE_LOG_INFO("enter");
129 if (g_sProxy == nullptr) {
130 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
131 return -1;
132 }
133
134 if (callback == nullptr) {
135 INTELL_VOICE_LOG_ERROR("service death recipient is null");
136 return -1;
137 }
138
139 bool ret = g_sProxy->AsObject()->RemoveDeathRecipient(callback);
140 if (!ret) {
141 INTELL_VOICE_LOG_ERROR("failed to remove death recipient");
142 return -1;
143 }
144 return 0;
145 }
146
GetUploadFiles(int numMax, std::vector<UploadFilesInfo> &files)147 int32_t IntellVoiceManager::GetUploadFiles(int numMax, std::vector<UploadFilesInfo> &files)
148 {
149 INTELL_VOICE_LOG_INFO("enter, numMax: %{public}d", numMax);
150 CHECK_CONDITION_RETURN_RET(g_sProxy == nullptr, -1, "IntellVoiceService Proxy is null");
151 std::vector<UploadHdiFile> hdiFiles;
152 int32_t ret = g_sProxy->GetUploadFiles(numMax, hdiFiles);
153 if (ret != 0) {
154 INTELL_VOICE_LOG_ERROR("Get upload files failed, ret:%{public}d", ret);
155 return ret;
156 }
157
158 if (hdiFiles.empty()) {
159 INTELL_VOICE_LOG_ERROR("no upload files");
160 return -1;
161 }
162 INTELL_VOICE_LOG_INFO("upload files size:%{public}u", static_cast<uint32_t>(hdiFiles.size()));
163 for (auto hdiFile : hdiFiles) {
164 UploadFilesInfo filesInfo;
165 filesInfo.type = hdiFile.type;
166 filesInfo.filesDescription = hdiFile.filesDescription;
167 for (auto content : hdiFile.filesContent) {
168 if (content == nullptr) {
169 INTELL_VOICE_LOG_ERROR("fileContent is nullptr");
170 continue;
171 }
172 std::vector<uint8_t> fileData;
173 if (GetFileDataFromAshmem(content, fileData) != 0) {
174 INTELL_VOICE_LOG_ERROR("failed to file data from ashmem");
175 continue;
176 }
177 filesInfo.filesContent.push_back(fileData);
178 }
179 files.push_back(filesInfo);
180 }
181 std::vector<UploadHdiFile>().swap(hdiFiles);
182 return 0;
183 }
184
GetFileDataFromAshmem(sptr<Ashmem> ashmem, std::vector<uint8_t> &fileData)185 int32_t IntellVoiceManager::GetFileDataFromAshmem(sptr<Ashmem> ashmem, std::vector<uint8_t> &fileData)
186 {
187 if (ashmem == nullptr) {
188 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
189 return -1;
190 }
191
192 ON_SCOPE_EXIT {
193 ashmem->UnmapAshmem();
194 ashmem->CloseAshmem();
195 };
196
197 uint32_t size = static_cast<uint32_t>(ashmem->GetAshmemSize());
198 if (size == 0) {
199 INTELL_VOICE_LOG_ERROR("size is zero");
200 return -1;
201 }
202
203 if (!ashmem->MapReadOnlyAshmem()) {
204 INTELL_VOICE_LOG_ERROR("map ashmem failed");
205 return -1;
206 }
207
208 const uint8_t *buffer = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
209 if (buffer == nullptr) {
210 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
211 return -1;
212 }
213
214 fileData.insert(fileData.begin(), buffer, buffer + size);
215 return 0;
216 }
217
SetParameter(const std::string &key, const std::string &value)218 int32_t IntellVoiceManager::SetParameter(const std::string &key, const std::string &value)
219 {
220 INTELL_VOICE_LOG_INFO("enter, key:%{public}s, value:%{public}s", key.c_str(), value.c_str());
221 if (g_sProxy == nullptr) {
222 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
223 return -1;
224 }
225 string keyValueList = key + "=" + value;
226 return g_sProxy->SetParameter(keyValueList);
227 }
228
GetParameter(const std::string &key)229 std::string IntellVoiceManager::GetParameter(const std::string &key)
230 {
231 INTELL_VOICE_LOG_INFO("enter");
232 if (g_sProxy == nullptr) {
233 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
234 return "";
235 }
236
237 if (key.empty()) {
238 INTELL_VOICE_LOG_ERROR("key empty");
239 return "";
240 }
241
242 return g_sProxy->GetParameter(key);
243 }
244
GetWakeupSourceFiles(std::vector<WakeupSourceFile> &cloneFileInfo)245 int32_t IntellVoiceManager::GetWakeupSourceFiles(std::vector<WakeupSourceFile> &cloneFileInfo)
246 {
247 INTELL_VOICE_LOG_INFO("enter");
248 if (g_sProxy == nullptr) {
249 INTELL_VOICE_LOG_ERROR("IntellVoiceService Proxy is null");
250 return -1;
251 }
252
253 std::vector<std::string> cloneFiles;
254 int ret = g_sProxy->GetWakeupSourceFilesList(cloneFiles);
255 if (ret != 0) {
256 INTELL_VOICE_LOG_ERROR("get clone list err");
257 return -1;
258 }
259
260 WakeupSourceFile fileInfo;
261 size_t fileCount = cloneFiles.size();
262 cloneFiles.reserve(fileCount);
263
264 for (size_t index = 0; index < fileCount; ++index) {
265 fileInfo.filePath = cloneFiles[index];
266 ret = g_sProxy->GetWakeupSourceFile(cloneFiles[index], fileInfo.fileContent);
267 if (ret != 0) {
268 INTELL_VOICE_LOG_ERROR("get clone file err");
269 return -1;
270 }
271 cloneFileInfo.push_back(fileInfo);
272 }
273
274 return 0;
275 }
276
EnrollWithWakeupFilesForResult(const std::vector<WakeupSourceFile> &cloneFileInfo, const std::string &wakeupInfo, const shared_ptr<IIntellVoiceUpdateCallback> callback)277 int32_t IntellVoiceManager::EnrollWithWakeupFilesForResult(const std::vector<WakeupSourceFile> &cloneFileInfo,
278 const std::string &wakeupInfo, const shared_ptr<IIntellVoiceUpdateCallback> callback)
279 {
280 INTELL_VOICE_LOG_INFO("enter");
281
282 if (g_sProxy == nullptr) {
283 INTELL_VOICE_LOG_ERROR("IntellVoiceService proxy is null");
284 return -1;
285 }
286
287 size_t fileCount = cloneFileInfo.size();
288 for (size_t index = 0; index < fileCount; ++index) {
289 int ret = g_sProxy->SendWakeupFile(cloneFileInfo[index].filePath, cloneFileInfo[index].fileContent);
290 if (ret != 0) {
291 INTELL_VOICE_LOG_ERROR("send clone file err, index:%{public}zu, size:%{public}zu, ret:%{public}d",
292 index, fileCount, ret);
293 return -1;
294 }
295 }
296
297 callback_ = sptr<UpdateCallbackInner>(new (std::nothrow) UpdateCallbackInner());
298 if (callback_ == nullptr) {
299 INTELL_VOICE_LOG_ERROR("callback_ is nullptr");
300 return -1;
301 }
302 callback_->SetUpdateCallback(callback);
303
304 return g_sProxy->EnrollWithWakeupFilesForResult(wakeupInfo, callback_->AsObject());
305 }
306
ClearUserData()307 int32_t IntellVoiceManager::ClearUserData()
308 {
309 INTELL_VOICE_LOG_INFO("enter");
310
311 if (g_sProxy == nullptr) {
312 INTELL_VOICE_LOG_ERROR("IntellVoiceService proxy is nullptr");
313 return -1;
314 }
315
316 return g_sProxy->ClearUserData();
317 }
318 } // namespace IntellVoice
319 } // namespace OHOS