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