• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_engine_manager.h"
16 
17 #include <vector>
18 #include <fstream>
19 #include <cstdio>
20 #include "audio_system_manager.h"
21 #include "idevmgr_hdi.h"
22 #include "intell_voice_log.h"
23 #include "intell_voice_util.h"
24 #include "engine_factory.h"
25 #include "wakeup_engine.h"
26 #include "iservice_registry.h"
27 #include "intell_voice_generic_factory.h"
28 #include "memory_guard.h"
29 #include "iproxy_broker.h"
30 #include "engine_host_manager.h"
31 #include "string_util.h"
32 #include "clone_update_strategy.h"
33 #include "silence_update_strategy.h"
34 #include "whisper_update_strategy.h"
35 #include "update_engine_utils.h"
36 #include "json/json.h"
37 #include "intell_voice_sensibility.h"
38 #include "headset_wakeup_wrapper.h"
39 #include "engine_callback_message.h"
40 #include "data_operation_callback.h"
41 #include "history_info_mgr.h"
42 #include "intell_voice_definitions.h"
43 
44 #define LOG_TAG "IntellVoiceEngineManager"
45 
46 using namespace OHOS::IntellVoiceUtils;
47 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
48 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
49 
50 namespace OHOS {
51 namespace IntellVoiceEngine {
52 static const std::string XIAOYIXIAOYI = "\xE5\xB0\x8F\xE8\x89\xBA\xE5\xB0\x8F\xE8\x89\xBA";
53 static const std::string LANGUAGE_TYPE_CHN = "zh";
54 std::atomic<bool> IntellVoiceEngineManager::screenoff_{false};
55 std::atomic<bool> IntellVoiceEngineManager::g_enrollResult[ENGINE_TYPE_BUT] = {false, false, false};
56 
57 std::shared_ptr<IntellVoiceEngineManager> IntellVoiceEngineManager::instance_ = nullptr;
58 std::mutex IntellVoiceEngineManager::instanceMutex_;
59 
IntellVoiceEngineManager()60 IntellVoiceEngineManager::IntellVoiceEngineManager()
61 {
62 }
63 
~IntellVoiceEngineManager()64 IntellVoiceEngineManager::~IntellVoiceEngineManager()
65 {
66 }
67 
CreateEngine(IntellVoiceEngineType type,const std::string & param,bool reEnroll)68 sptr<IIntellVoiceEngine> IntellVoiceEngineManager::CreateEngine(IntellVoiceEngineType type,
69     const std::string &param, bool reEnroll)
70 {
71     INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
72     SetEnrollResult(type, false);
73     if (ApplyArbitration(type, engines_) != ARBITRATION_OK) {
74         INTELL_VOICE_LOG_ERROR("policy manager reject create engine, type:%{public}d", type);
75         return nullptr;
76     }
77 
78     if (type != INTELL_VOICE_WAKEUP) {
79         auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
80         if (engine != nullptr) {
81             engine->ReleaseAdapter();
82         }
83     }
84 
85     return CreateEngineInner(type, param, reEnroll);
86 }
87 
CreateEngineInner(IntellVoiceEngineType type,const std::string & param,bool reEnroll)88 sptr<IIntellVoiceEngine> IntellVoiceEngineManager::CreateEngineInner(IntellVoiceEngineType type,
89     const std::string &param, bool reEnroll)
90 {
91     INTELL_VOICE_LOG_INFO("create engine enter, type: %{public}d", type);
92     OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
93     sptr<EngineBase> engine = GetEngine(type, engines_);
94     if (engine != nullptr) {
95         return engine;
96     }
97 
98     engine = EngineFactory::CreateEngineInst(type, param, reEnroll);
99     if (engine == nullptr) {
100         INTELL_VOICE_LOG_ERROR("create engine failed, type:%{public}d", type);
101         return nullptr;
102     }
103     engines_[type] = engine;
104     INTELL_VOICE_LOG_INFO("create engine ok");
105     return engine;
106 }
107 
ReleaseEngineInner(IntellVoiceEngineType type)108 int32_t IntellVoiceEngineManager::ReleaseEngineInner(IntellVoiceEngineType type)
109 {
110     OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
111     auto it = engines_.find(type);
112     if (it == engines_.end()) {
113         INTELL_VOICE_LOG_WARN("there is no engine(%{public}d) in list", type);
114         return 0;
115     }
116 
117     if (it->second != nullptr) {
118         it->second->Detach();
119         it->second = nullptr;
120     }
121 
122     engines_.erase(type);
123     return 0;
124 }
125 
ClearUserDataInner()126 void IntellVoiceEngineManager::ClearUserDataInner()
127 {
128     UpdateEngineController::ForceRelease();
129     auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
130     if (engine != nullptr) {
131         engine->Detach();
132     }
133     auto wakeupPhrase = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WAKEUP_PHRASE);
134     if (!wakeupPhrase.empty()) {
135         if (HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_LANGUAGE)
136             == LANGUAGE_TYPE_CHN && wakeupPhrase != XIAOYIXIAOYI) {
137             wakeupPhrase = "Default";
138         }
139         EngineHostManager::GetInstance().ClearUserWakeupData(wakeupPhrase);
140     }
141 }
142 
CreateOrResetWakeupEngine()143 bool IntellVoiceEngineManager::CreateOrResetWakeupEngine()
144 {
145     auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
146     if (engine != nullptr) {
147         INTELL_VOICE_LOG_INFO("wakeup engine is existed");
148         engine->ReleaseAdapter();
149         if (!engine->ResetAdapter()) {
150             INTELL_VOICE_LOG_ERROR("failed to reset adapter");
151             return false;
152         }
153     } else {
154         if (CreateEngineInner(INTELL_VOICE_WAKEUP) == nullptr) {
155             INTELL_VOICE_LOG_ERROR("failed to create wakeup engine");
156             return false;
157         }
158     }
159     return true;
160 }
161 
ServiceStopProc()162 int32_t IntellVoiceEngineManager::ServiceStopProc()
163 {
164     sptr<EngineBase> wakeupEngine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
165     if (wakeupEngine == nullptr) {
166         INTELL_VOICE_LOG_INFO("wakeup engine is not existed");
167         return -1;
168     }
169     wakeupEngine->Detach();
170     wakeupEngine->NotifyHeadsetHostEvent(HEADSET_HOST_OFF);
171     return 0;
172 }
173 
RegisterProxyDeathRecipient(IntellVoiceEngineType type,const sptr<IRemoteObject> & object)174 bool IntellVoiceEngineManager::RegisterProxyDeathRecipient(IntellVoiceEngineType type,
175     const sptr<IRemoteObject> &object)
176 {
177     std::lock_guard<std::mutex> lock(deathMutex_);
178     INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
179     deathRecipientObj_[type] = object;
180     if (type == INTELL_VOICE_ENROLL) {
181         proxyDeathRecipient_[type] = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
182             INTELL_VOICE_LOG_INFO("receive enroll proxy death recipient, release enroll engine");
183             EngineCallbackMessage::CallFunc(HANDLE_RELEASE_ENGINE, INTELL_VOICE_ENROLL);
184         });
185     } else if (type == INTELL_VOICE_WAKEUP) {
186         proxyDeathRecipient_[type] = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
187             INTELL_VOICE_LOG_INFO("receive wakeup proxy death recipient, clear wakeup engine callback");
188             EngineCallbackMessage::CallFunc(HANDLE_CLEAR_WAKEUP_ENGINE_CB);
189         });
190     } else if (type == INTELL_VOICE_HEADSET_WAKEUP) {
191         proxyDeathRecipient_[type] = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
192             INTELL_VOICE_LOG_INFO("receive headset wakeup proxy death recipient, notify headset host off");
193             EngineCallbackMessage::CallFunc(HANDLE_HEADSET_HOST_DIE);
194         });
195     } else {
196         INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
197         return false;
198     }
199 
200     if (proxyDeathRecipient_[type] == nullptr) {
201         INTELL_VOICE_LOG_ERROR("create death recipient failed");
202         return false;
203     }
204 
205     return deathRecipientObj_[type]->AddDeathRecipient(proxyDeathRecipient_[type]);
206 }
207 
DeregisterProxyDeathRecipient(IntellVoiceEngineType type)208 bool IntellVoiceEngineManager::DeregisterProxyDeathRecipient(IntellVoiceEngineType type)
209 {
210     std::lock_guard<std::mutex> lock(deathMutex_);
211     INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
212     if (deathRecipientObj_.count(type) == 0 || deathRecipientObj_[type] == nullptr) {
213         INTELL_VOICE_LOG_ERROR("death obj is nullptr, type:%{public}d", type);
214         return false;
215     }
216     if (proxyDeathRecipient_.count(type) == 0 || proxyDeathRecipient_[type] == nullptr) {
217         INTELL_VOICE_LOG_ERROR("death recipient is nullptr, type:%{public}d", type);
218         deathRecipientObj_.erase(type);
219         return false;
220     }
221 
222     auto ret = deathRecipientObj_[type]->RemoveDeathRecipient(proxyDeathRecipient_[type]);
223     deathRecipientObj_.erase(type);
224     proxyDeathRecipient_.erase(type);
225     return ret;
226 }
227 
AnyEngineExist(const std::vector<IntellVoiceEngineType> & types)228 bool IntellVoiceEngineManager::AnyEngineExist(const std::vector<IntellVoiceEngineType> &types)
229 {
230     for (const auto &type : types) {
231         if (IsEngineExist(type)) {
232             return true;
233         }
234     }
235     return false;
236 }
237 
IsEngineExist(IntellVoiceEngineType type)238 bool IntellVoiceEngineManager::IsEngineExist(IntellVoiceEngineType type)
239 {
240     sptr<EngineBase> engine = GetEngine(type, engines_);
241     if (engine != nullptr) {
242         INTELL_VOICE_LOG_INFO("engine exist, type:%{public}d", type);
243         return true;
244     }
245 
246     if (type == INTELL_VOICE_UPDATE && GetUpdateState()) {
247         INTELL_VOICE_LOG_ERROR("update is running");
248         return true;
249     }
250 
251     return false;
252 }
253 
CreateUpdateEngine(const std::string & param,bool reEnroll)254 bool IntellVoiceEngineManager::CreateUpdateEngine(const std::string &param, bool reEnroll)
255 {
256     sptr<IIntellVoiceEngine> updateEngine = CreateEngine(INTELL_VOICE_UPDATE, param, reEnroll);
257     if (updateEngine == nullptr) {
258         INTELL_VOICE_LOG_ERROR("updateEngine is nullptr");
259         return false;
260     }
261 
262     return true;
263 }
264 
ReleaseUpdateEngine()265 void IntellVoiceEngineManager::ReleaseUpdateEngine()
266 {
267     EngineCallbackMessage::CallFunc(RELEASE_ENGINE, INTELL_VOICE_UPDATE);
268 }
269 
GetUploadFiles(int numMax,std::vector<UploadFilesFromHdi> & files)270 int32_t IntellVoiceEngineManager::GetUploadFiles(int numMax, std::vector<UploadFilesFromHdi> &files)
271 {
272     std::vector<UploadHdiFile> hdiFiles;
273     auto ret = EngineHostManager::GetInstance().GetUploadFiles(numMax, hdiFiles);
274     if (ret != 0) {
275         INTELL_VOICE_LOG_INFO("failed to get upload file, ret:%{public}d", ret);
276         return ret;
277     }
278 
279     for (auto item : hdiFiles) {
280         UploadFilesFromHdi file;
281         file.type = item.type;
282         file.filesDescription = item.filesDescription;
283         for (auto mem : item.filesContent) {
284             file.filesContent.emplace_back(mem);
285         }
286         file.type = item.type;
287         files.emplace_back(file);
288     }
289     return ret;
290 }
291 
GetParameter(const std::string & key)292 std::string IntellVoiceEngineManager::GetParameter(const std::string &key)
293 {
294     std::string val = "";
295 
296     if (key == "isEnrolled") {
297         HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
298         val = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_VESRION).empty() ? "false" : "true";
299         INTELL_VOICE_LOG_INFO("get is enroll result %{public}s", val.c_str());
300     } else if (key == "isNeedReEnroll") {
301         val = UpdateEngineUtils::IsVersionUpdate() ? "true" : "false";
302         INTELL_VOICE_LOG_INFO("get nedd reenroll result %{public}s", val.c_str());
303     } else if (key == "isWhispering") {
304         auto audioSystemManager = AudioStandard::AudioSystemManager::GetInstance();
305         if (audioSystemManager == nullptr) {
306             INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
307             return val;
308         }
309         val = std::to_string(audioSystemManager->IsWhispering());
310         INTELL_VOICE_LOG_INFO("get isWhispering result %{public}s", val.c_str());
311     }
312 
313     return val;
314 }
315 
SetParameter(const std::string & sensibility)316 int32_t IntellVoiceEngineManager::SetParameter(const std::string &sensibility)
317 {
318     auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
319     if (engine != nullptr) {
320         engine->SetParameter(SENSIBILITY_TEXT + sensibility);
321     }
322     return 0;
323 }
324 
GetWakeupSourceFilesList(std::vector<std::string> & cloneFiles)325 int32_t IntellVoiceEngineManager::GetWakeupSourceFilesList(std::vector<std::string> &cloneFiles)
326 {
327     return EngineHostManager::GetInstance().GetWakeupSourceFilesList(cloneFiles);
328 }
329 
GetWakeupSourceFile(const std::string & filePath,std::vector<uint8_t> & buffer)330 int32_t IntellVoiceEngineManager::GetWakeupSourceFile(const std::string &filePath, std::vector<uint8_t> &buffer)
331 {
332     return EngineHostManager::GetInstance().GetWakeupSourceFile(filePath, buffer);
333 }
334 
SendWakeupFile(const std::string & filePath,const std::vector<uint8_t> & buffer)335 int32_t IntellVoiceEngineManager::SendWakeupFile(const std::string &filePath, const std::vector<uint8_t> &buffer)
336 {
337     if (buffer.data() == nullptr) {
338         INTELL_VOICE_LOG_ERROR("send update callback is nullptr");
339     }
340 
341     return EngineHostManager::GetInstance().SendWakeupFile(filePath, buffer);
342 }
343 
CloneUpdate(const std::string & wakeupInfo,const sptr<IRemoteObject> & object)344 int32_t IntellVoiceEngineManager::CloneUpdate(const std::string &wakeupInfo, const sptr<IRemoteObject> &object)
345 {
346     sptr<IIntelligentVoiceUpdateCallback> updateCallback = iface_cast<IIntelligentVoiceUpdateCallback>(object);
347     if (updateCallback == nullptr) {
348         INTELL_VOICE_LOG_ERROR("update callback is nullptr");
349         return -1;
350     }
351 
352     if (wakeupInfo.empty()) {
353         INTELL_VOICE_LOG_ERROR("clone info empty");
354         return -1;
355     }
356 
357     std::shared_ptr<CloneUpdateStrategy> cloneStrategy =
358         std::make_shared<CloneUpdateStrategy>(wakeupInfo, updateCallback);
359     if (cloneStrategy == nullptr) {
360         INTELL_VOICE_LOG_ERROR("clone strategy is nullptr");
361         return -1;
362     }
363 
364     INTELL_VOICE_LOG_INFO("enter");
365     std::shared_ptr<IUpdateStrategy> strategy = std::dynamic_pointer_cast<IUpdateStrategy>(cloneStrategy);
366     return CreateUpdateEngineUntilTime(strategy);
367 }
368 
SilenceUpdate()369 int32_t IntellVoiceEngineManager::SilenceUpdate()
370 {
371     std::shared_ptr<SilenceUpdateStrategy> silenceStrategy = std::make_shared<SilenceUpdateStrategy>("");
372     if (silenceStrategy == nullptr) {
373         INTELL_VOICE_LOG_ERROR("silence strategy is nullptr");
374         return -1;
375     }
376 
377     INTELL_VOICE_LOG_INFO("enter");
378     std::shared_ptr<IUpdateStrategy> strategy = std::dynamic_pointer_cast<IUpdateStrategy>(silenceStrategy);
379     return CreateUpdateEngineUntilTime(strategy);
380 }
381 
WhisperVprUpdate(bool reEnroll)382 int32_t IntellVoiceEngineManager::WhisperVprUpdate(bool reEnroll)
383 {
384     INTELL_VOICE_LOG_INFO("enter");
385     std::shared_ptr<IUpdateStrategy> strategy = std::make_shared<WhisperUpdateStrategy>("WhisperVprUpdate");
386     if (strategy == nullptr) {
387         INTELL_VOICE_LOG_ERROR("strategy is nullptr");
388         return -1;
389     }
390 
391     return CreateUpdateEngineUntilTime(strategy, reEnroll);
392 }
393 
394 
GetDspSensibility(const std::string & sensibility,const std::string & dspFeature,const std::string & configPath)395 std::string IntellVoiceEngineManager::GetDspSensibility(const std::string &sensibility,
396     const std::string &dspFeature, const std::string &configPath)
397 {
398     return IntellVoiceSensibility::GetDspSensibility(sensibility, dspFeature, configPath);
399 }
400 
HeadsetHostDie()401 void IntellVoiceEngineManager::HeadsetHostDie()
402 {
403     auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
404     if (engine != nullptr) {
405         engine->NotifyHeadsetHostEvent(HEADSET_HOST_OFF);
406     }
407 }
408 
IsNeedUpdateComplete(int32_t result,const std::string & param)409 bool IntellVoiceEngineManager::IsNeedUpdateComplete(int32_t result, const std::string &param)
410 {
411     bool isLast = false;
412     UpdateEngineController::UpdateCompleteProc(static_cast<UpdateState>(result), param, isLast);
413     if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (!isLast)) {
414         INTELL_VOICE_LOG_INFO("enroll engine is existed, or is not last:%{public}d", isLast);
415         return false;
416     }
417     return true;
418 }
419 
IsNeedUpdateRetry()420 bool IntellVoiceEngineManager::IsNeedUpdateRetry()
421 {
422     if (UpdateEngineController::UpdateRetryProc()) {
423         INTELL_VOICE_LOG_INFO("retry to update or already force to stop");
424         return false;
425     }
426     if (IsEngineExist(INTELL_VOICE_ENROLL)) {
427         INTELL_VOICE_LOG_INFO("enroll engine is existed, do nothing");
428         return false;
429     }
430     return true;
431 }
432 
EngineOnDetected(int32_t uuid)433 void IntellVoiceEngineManager::EngineOnDetected(int32_t uuid)
434 {
435     auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
436     engine->OnDetected(uuid);
437 }
438 
ClearWakeupEngineCb()439 void IntellVoiceEngineManager::ClearWakeupEngineCb()
440 {
441     sptr<EngineBase> engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
442     if (engine != nullptr) {
443         INTELL_VOICE_LOG_INFO("clear wakeup engine callback");
444         engine->SetCallback(nullptr);
445     }
446 }
447 
GetScreenOff()448 bool IntellVoiceEngineManager::GetScreenOff()
449 {
450     return screenoff_.load();
451 }
452 
SetScreenOff(bool value)453 void IntellVoiceEngineManager::SetScreenOff(bool value)
454 {
455     screenoff_.store(value);
456 }
457 
SetDspSensibility(const std::string & sensibility)458 void IntellVoiceEngineManager::SetDspSensibility(const std::string &sensibility)
459 {
460     auto ret = EngineCallbackMessage::CallFunc(TRIGGERMGR_GET_PARAMETER, KEY_GET_WAKEUP_FEATURE);
461     std::string features = "";
462     if (ret.has_value()) {
463         try {
464             features = std::any_cast<std::string>(*ret);
465         } catch (const std::bad_any_cast&) {
466             INTELL_VOICE_LOG_ERROR("msg bus bad any cast");
467             return;
468         }
469     } else {
470         INTELL_VOICE_LOG_ERROR("msg bus return no value");
471         return;
472     }
473     auto value = GetDspSensibility(sensibility, features, WAKEUP_CONFIG_PATH);
474     if (value.empty()) {
475         INTELL_VOICE_LOG_ERROR("no sensibility value");
476         return;
477     }
478     EngineCallbackMessage::CallFunc(TRIGGERMGR_SET_PARAMETER, "WAKEUP_SENSIBILITY", value);
479 }
480 
OnServiceStart()481 void IntellVoiceEngineManager::OnServiceStart()
482 {
483     LoadIntellVoiceHost();
484 }
485 
OnServiceStop()486 void IntellVoiceEngineManager::OnServiceStop()
487 {
488     UnloadIntellVoiceHost();
489 }
490 
LoadIntellVoiceHost()491 void IntellVoiceEngineManager::LoadIntellVoiceHost()
492 {
493     auto devmgr = IDeviceManager::Get();
494     if (devmgr == nullptr) {
495         INTELL_VOICE_LOG_ERROR("Get devmgr failed");
496         return;
497     }
498     INTELL_VOICE_LOG_INFO("Get devmgr success");
499     devmgr->UnloadDevice("intell_voice_engine_manager_service");
500     devmgr->LoadDevice("intell_voice_engine_manager_service");
501 
502     if (!EngineHostManager::GetInstance().Init()) {
503         INTELL_VOICE_LOG_ERROR("init engine host failed");
504         return;
505     }
506 
507     EngineHostManager::GetInstance().RegisterEngineHDIDeathRecipient();
508     EngineHostManager::GetInstance().SetDataOprCallback();
509 }
510 
UnloadIntellVoiceHost()511 void IntellVoiceEngineManager::UnloadIntellVoiceHost()
512 {
513     auto devmgr = IDeviceManager::Get();
514     if (devmgr != nullptr) {
515         INTELL_VOICE_LOG_INFO("Get devmgr success");
516         EngineHostManager::GetInstance().DeregisterEngineHDIDeathRecipient();
517         devmgr->UnloadDevice("intell_voice_engine_manager_service");
518     } else {
519         INTELL_VOICE_LOG_ERROR("Get devmgr failed");
520     }
521 }
522 }  // namespace IntellVoiceEngine
523 }  // namespace OHOS
524