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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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