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