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