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_service_manager.h"
16
17 #include <vector>
18 #include <fstream>
19 #include <cstdio>
20 #include "audio_system_manager.h"
21 #include "intell_voice_log.h"
22 #include "intell_voice_util.h"
23 #include "engine_factory.h"
24 #include "wakeup_engine.h"
25 #include "trigger_manager.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 #include "intell_voice_generic_factory.h"
29 #include "trigger_detector_callback.h"
30 #include "memory_guard.h"
31 #include "iproxy_broker.h"
32 #include "engine_host_manager.h"
33 #include "string_util.h"
34 #include "clone_update_strategy.h"
35 #include "silence_update_strategy.h"
36 #include "update_engine_utils.h"
37 #include "json/json.h"
38
39 #define LOG_TAG "IntellVoiceServiceManager"
40
41 using namespace OHOS::IntellVoiceTrigger;
42 using namespace OHOS::IntellVoiceUtils;
43 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
44
45 namespace OHOS {
46 namespace IntellVoiceEngine {
47 static constexpr int32_t MAX_ATTEMPT_CNT = 10;
48 static constexpr uint32_t MAX_TASK_NUM = 200;
49 static const std::string SERVICE_MANAGER_THREAD_NAME = "ServMgrThread";
50 static const std::string SENSIBILITY_TEXT = "sensibility=";
51 static const std::string WHISPER_MODEL_PATH =
52 "/sys_prod/variant/region_comm/china/etc/intellvoice/wakeup/dsp/whisper_wakeup_dsp_config";
53 static const std::string VAD_MODEL_PATH =
54 "/sys_prod/variant/region_comm/china/etc/intellvoice/wakeup/ap/kws2_acousticsModel6.pb";
55 static const std::string WAKEUP_CONFIG_USER_PATH =
56 "/sys_prod/variant/region_comm/china/etc/intellvoice/wakeup/ap/wakeup_config_user.json";
57 static const std::string WAKEUP_CONFIG_PATH =
58 "/sys_prod/variant/region_comm/china/etc/intellvoice/wakeup/ap/wakeup_config.json";
59
60 std::atomic<bool> IntellVoiceServiceManager::g_enrollResult[ENGINE_TYPE_BUT] = {false, false, false};
61 std::vector<int32_t> IntellVoiceServiceManager::g_defaultDspSentenceThresholds = {101, 101, 101};
62 std::unique_ptr<IntellVoiceServiceManager> IntellVoiceServiceManager::g_intellVoiceServiceMgr =
63 std::unique_ptr<IntellVoiceServiceManager>(new (std::nothrow) IntellVoiceServiceManager());
64
IntellVoiceServiceManager()65 IntellVoiceServiceManager::IntellVoiceServiceManager() : TaskExecutor(SERVICE_MANAGER_THREAD_NAME, MAX_TASK_NUM)
66 {
67 TaskExecutor::StartThread();
68 }
69
~IntellVoiceServiceManager()70 IntellVoiceServiceManager::~IntellVoiceServiceManager()
71 {
72 engines_.clear();
73 TaskExecutor::StopThread();
74 }
75
GetInstance()76 std::unique_ptr<IntellVoiceServiceManager> &IntellVoiceServiceManager::GetInstance()
77 {
78 return g_intellVoiceServiceMgr;
79 }
80
CreateEngine(IntellVoiceEngineType type,const std::string & param)81 sptr<IIntellVoiceEngine> IntellVoiceServiceManager::CreateEngine(IntellVoiceEngineType type, const std::string ¶m)
82 {
83 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
84 if (type == INTELL_VOICE_ENROLL) {
85 StopDetection(VOICE_WAKEUP_MODEL_UUID);
86 StopDetection(PROXIMAL_WAKEUP_MODEL_UUID);
87 }
88
89 SetEnrollResult(type, false);
90 if (ApplyArbitration(type, engines_) != ARBITRATION_OK) {
91 INTELL_VOICE_LOG_ERROR("policy manager reject create engine, type:%{public}d", type);
92 return nullptr;
93 }
94
95 if (type != INTELL_VOICE_WAKEUP) {
96 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
97 if (engine != nullptr) {
98 engine->ReleaseAdapter();
99 }
100 }
101
102 return CreateEngineInner(type, param);
103 }
104
CreateEngineInner(IntellVoiceEngineType type,const std::string & param)105 sptr<IIntellVoiceEngine> IntellVoiceServiceManager::CreateEngineInner(IntellVoiceEngineType type,
106 const std::string ¶m)
107 {
108 INTELL_VOICE_LOG_INFO("create engine enter, type: %{public}d", type);
109 OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
110 sptr<EngineBase> engine = GetEngine(type, engines_);
111 if (engine != nullptr) {
112 return engine;
113 }
114
115 engine = EngineFactory::CreateEngineInst(type, param);
116 if (engine == nullptr) {
117 INTELL_VOICE_LOG_ERROR("create engine failed, type:%{public}d", type);
118 return nullptr;
119 }
120
121 SetImproveParam(engine);
122 engines_[type] = engine;
123 INTELL_VOICE_LOG_INFO("create engine ok");
124 return engine;
125 }
126
ReleaseEngine(IntellVoiceEngineType type)127 int32_t IntellVoiceServiceManager::ReleaseEngine(IntellVoiceEngineType type)
128 {
129 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
130 auto ret = ReleaseEngineInner(type);
131 if (ret != 0) {
132 return ret;
133 }
134
135 if (type != INTELL_VOICE_ENROLL) {
136 return 0;
137 }
138
139 if (GetEnrollResult(type)) {
140 SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
141 SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
142 SwitchOffProc(PROXIMAL_WAKEUP_MODEL_UUID);
143 } else {
144 SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
145 SwitchOffProc(VOICE_WAKEUP_MODEL_UUID);
146 SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
147 SwitchOffProc(PROXIMAL_WAKEUP_MODEL_UUID);
148 UnloadIntellVoiceService();
149 }
150
151 return 0;
152 }
153
ReleaseEngineInner(IntellVoiceEngineType type)154 int32_t IntellVoiceServiceManager::ReleaseEngineInner(IntellVoiceEngineType type)
155 {
156 OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
157 auto it = engines_.find(type);
158 if (it == engines_.end()) {
159 INTELL_VOICE_LOG_WARN("there is no engine(%{public}d) in list", type);
160 return 0;
161 }
162
163 if (it->second != nullptr) {
164 it->second->Detach();
165 it->second = nullptr;
166 }
167
168 engines_.erase(type);
169 return 0;
170 }
171
CreateOrResetWakeupEngine()172 bool IntellVoiceServiceManager::CreateOrResetWakeupEngine()
173 {
174 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
175 if (engine != nullptr) {
176 INTELL_VOICE_LOG_INFO("wakeup engine is existed");
177 engine->ReleaseAdapter();
178 if (!engine->ResetAdapter()) {
179 INTELL_VOICE_LOG_ERROR("failed to reset adapter");
180 return false;
181 }
182 SetImproveParam(engine);
183 } else {
184 if (CreateEngineInner(INTELL_VOICE_WAKEUP) == nullptr) {
185 INTELL_VOICE_LOG_ERROR("failed to create wakeup engine");
186 return false;
187 }
188 }
189 return true;
190 }
191
CreateSwitchProvider()192 void IntellVoiceServiceManager::CreateSwitchProvider()
193 {
194 INTELL_VOICE_LOG_INFO("enter");
195 std::lock_guard<std::mutex> lock(switchMutex_);
196 switchProvider_ = UniquePtrFactory<SwitchProvider>::CreateInstance();
197 if (switchProvider_ == nullptr) {
198 INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
199 return;
200 }
201 RegisterObserver(WAKEUP_KEY);
202 RegisterObserver(WHISPER_KEY);
203 RegisterObserver(IMPROVE_KEY);
204 RegisterObserver(SHORTWORD_KEY);
205 }
206
RegisterObserver(const std::string & switchKey)207 void IntellVoiceServiceManager::RegisterObserver(const std::string &switchKey)
208 {
209 switchObserver_[switchKey] = sptr<SwitchObserver>(new (std::nothrow) SwitchObserver());
210 if (switchObserver_[switchKey] == nullptr) {
211 INTELL_VOICE_LOG_ERROR("switchObserver_ is nullptr");
212 return;
213 }
214 switchObserver_[switchKey]->SetUpdateFunc([switchKey]() {
215 const auto &manager = IntellVoiceServiceManager::GetInstance();
216 if (manager != nullptr) {
217 manager->OnSwitchChange(switchKey);
218 }
219 });
220
221 switchProvider_->RegisterObserver(switchObserver_[switchKey], switchKey);
222 }
223
ReleaseSwitchProvider()224 void IntellVoiceServiceManager::ReleaseSwitchProvider()
225 {
226 std::lock_guard<std::mutex> lock(switchMutex_);
227 if (switchProvider_ == nullptr) {
228 INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
229 return;
230 }
231
232 for (auto it : switchObserver_) {
233 if (it.second != nullptr) {
234 switchProvider_->UnregisterObserver(it.second, it.first);
235 }
236 }
237 switchProvider_ = nullptr;
238 }
239
CreateDetector(int32_t uuid)240 void IntellVoiceServiceManager::CreateDetector(int32_t uuid)
241 {
242 std::lock_guard<std::mutex> lock(detectorMutex_);
243 if (!QuerySwitchByUuid(uuid)) {
244 INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
245 return;
246 }
247
248 if (detector_.count(uuid) != 0 && detector_[uuid] != nullptr) {
249 INTELL_VOICE_LOG_INFO("detector is already existed, no need to create, uuid:%{public}d", uuid);
250 return;
251 }
252
253 auto cb = std::make_shared<TriggerDetectorCallback>([&, uuid]() { OnDetected(uuid); });
254 if (cb == nullptr) {
255 INTELL_VOICE_LOG_ERROR("cb is nullptr");
256 return;
257 }
258
259 auto triggerMgr = TriggerManager::GetInstance();
260 if (triggerMgr == nullptr) {
261 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
262 return;
263 }
264
265 auto detector = triggerMgr->CreateTriggerDetector(uuid, cb);
266 if (detector == nullptr) {
267 INTELL_VOICE_LOG_ERROR("detector is nullptr");
268 return;
269 }
270
271 detector_[uuid] = detector;
272 }
273
StartDetection(int32_t uuid)274 bool IntellVoiceServiceManager::StartDetection(int32_t uuid)
275 {
276 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (IsEngineExist(INTELL_VOICE_UPDATE))) {
277 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
278 return false;
279 }
280
281 for (uint32_t cnt = 1; cnt <= MAX_ATTEMPT_CNT; ++cnt) {
282 {
283 std::lock_guard<std::mutex> lock(detectorMutex_);
284 if ((detector_.count(uuid) == 0) || (detector_[uuid] == nullptr)) {
285 INTELL_VOICE_LOG_INFO("detector is not existed, uuid:%{public}d", uuid);
286 return false;
287 }
288
289 if (!QuerySwitchByUuid(uuid)) {
290 INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
291 return false;
292 }
293
294 auto triggerMgr = TriggerManager::GetInstance();
295 if (triggerMgr == nullptr) {
296 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
297 return false;
298 }
299
300 if (triggerMgr->GetParameter("audio_hal_status") == "true") {
301 INTELL_VOICE_LOG_INFO("audio hal is ready");
302 detector_[uuid]->StartRecognition();
303 return true;
304 }
305 }
306 INTELL_VOICE_LOG_INFO("begin to wait");
307 std::this_thread::sleep_for(std::chrono::seconds(cnt));
308 INTELL_VOICE_LOG_INFO("end to wait");
309 }
310 INTELL_VOICE_LOG_ERROR("failed to start recognition");
311 return false;
312 }
313
StopDetection(int32_t uuid)314 void IntellVoiceServiceManager::StopDetection(int32_t uuid)
315 {
316 std::lock_guard<std::mutex> lock(detectorMutex_);
317 if ((detector_.count(uuid) == 0) || (detector_[uuid] == nullptr)) {
318 INTELL_VOICE_LOG_INFO("detector is not existed, uuid:%{public}d", uuid);
319 return;
320 }
321 detector_[uuid]->StopRecognition();
322 }
323
OnDetected(int32_t uuid)324 void IntellVoiceServiceManager::OnDetected(int32_t uuid)
325 {
326 TaskExecutor::AddAsyncTask([uuid, this]() {
327 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
328 if (engine == nullptr) {
329 INTELL_VOICE_LOG_WARN("wakeup engine is nullptr");
330 StartDetection(VOICE_WAKEUP_MODEL_UUID);
331 StartDetection(PROXIMAL_WAKEUP_MODEL_UUID);
332 return;
333 }
334 engine->OnDetected(uuid);
335 });
336 }
337
CreateAndStartServiceObject(int32_t uuid,bool needResetAdapter)338 void IntellVoiceServiceManager::CreateAndStartServiceObject(int32_t uuid, bool needResetAdapter)
339 {
340 auto triggerMgr = TriggerManager::GetInstance();
341 if (triggerMgr == nullptr) {
342 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
343 return;
344 }
345 auto model = triggerMgr->GetModel(uuid);
346 if (model == nullptr) {
347 INTELL_VOICE_LOG_INFO("no model");
348 return;
349 }
350
351 if (!QuerySwitchByUuid(uuid)) {
352 INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
353 return;
354 }
355
356 CreateDetector(uuid);
357 if (!StartDetection(uuid)) {
358 INTELL_VOICE_LOG_ERROR("failed to start detection");
359 return;
360 }
361
362 if (!needResetAdapter) {
363 CreateEngine(INTELL_VOICE_WAKEUP);
364 } else {
365 CreateOrResetWakeupEngine();
366 }
367 }
368
SetDspSensibility(const std::string & sensibility)369 void IntellVoiceServiceManager::SetDspSensibility(const std::string &sensibility)
370 {
371 auto triggerMgr = TriggerManager::GetInstance();
372 if (triggerMgr == nullptr) {
373 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
374 return;
375 }
376
377 int32_t index = std::stoi(sensibility) - 1;
378 if ((index < 0) || (index >= static_cast<int32_t>(g_defaultDspSentenceThresholds.size()))) {
379 INTELL_VOICE_LOG_WARN("invalid index:%{public}d", index);
380 return;
381 }
382
383 triggerMgr->SetParameter("WAKEUP_SENSIBILITY", std::to_string(g_defaultDspSentenceThresholds[index]));
384 }
385
ReleaseServiceObject(int32_t uuid)386 void IntellVoiceServiceManager::ReleaseServiceObject(int32_t uuid)
387 {
388 std::lock_guard<std::mutex> lock(detectorMutex_);
389 auto it = detector_.find(uuid);
390 if (it != detector_.end()) {
391 if (it->second != nullptr) {
392 it->second->UnloadTriggerModel();
393 }
394 detector_.erase(it);
395 }
396
397 auto triggerMgr = TriggerManager::GetInstance();
398 if (triggerMgr == nullptr) {
399 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
400 return;
401 }
402 triggerMgr->ReleaseTriggerDetector(uuid);
403 }
404
ServiceStopProc()405 int32_t IntellVoiceServiceManager::ServiceStopProc()
406 {
407 sptr<EngineBase> wakeupEngine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
408 if (wakeupEngine == nullptr) {
409 INTELL_VOICE_LOG_INFO("wakeup engine is not existed");
410 return -1;
411 }
412 wakeupEngine->Detach();
413 return 0;
414 }
415
QuerySwitchStatus(const std::string & key)416 bool IntellVoiceServiceManager::QuerySwitchStatus(const std::string &key)
417 {
418 std::lock_guard<std::mutex> lock(switchMutex_);
419 if (!IsSwitchKeyValid(key)) {
420 INTELL_VOICE_LOG_ERROR("invalid key :%{public}s", key.c_str());
421 return false;
422 }
423
424 if (switchProvider_ == nullptr) {
425 INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
426 return false;
427 }
428 return switchProvider_->QuerySwitchStatus(key);
429 }
430
OnSwitchChange(const std::string & switchKey)431 void IntellVoiceServiceManager::OnSwitchChange(const std::string &switchKey)
432 {
433 if (switchKey == WAKEUP_KEY) {
434 if (QuerySwitchStatus(switchKey)) {
435 HandleSwitchOn(false, VOICE_WAKEUP_MODEL_UUID, false);
436 } else {
437 HandleSwitchOff(false, VOICE_WAKEUP_MODEL_UUID);
438 INTELL_VOICE_LOG_INFO("switch off process finish");
439 HandleUnloadIntellVoiceService(false);
440 }
441 } else if (switchKey == WHISPER_KEY) {
442 if (QuerySwitchStatus(switchKey)) {
443 HandleSwitchOn(false, PROXIMAL_WAKEUP_MODEL_UUID, false);
444 } else {
445 HandleSwitchOff(false, PROXIMAL_WAKEUP_MODEL_UUID);
446 HandleUnloadIntellVoiceService(false);
447 }
448 } else if (switchKey == IMPROVE_KEY) {
449 TaskExecutor::AddSyncTask([this]() -> int32_t {
450 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
451 if (engine != nullptr) {
452 SetImproveParam(engine);
453 }
454 return 0;
455 });
456 } else if (switchKey == SHORTWORD_KEY) {
457 TaskExecutor::AddSyncTask([this]() -> int32_t {
458 INTELL_VOICE_LOG_INFO("short word switch change");
459 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (IsEngineExist(INTELL_VOICE_UPDATE))) {
460 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
461 return 0;
462 }
463 StopDetection(VOICE_WAKEUP_MODEL_UUID);
464 StopDetection(PROXIMAL_WAKEUP_MODEL_UUID);
465 CreateOrResetWakeupEngine();
466 StartDetection(VOICE_WAKEUP_MODEL_UUID);
467 StartDetection(PROXIMAL_WAKEUP_MODEL_UUID);
468 return 0;
469 });
470 }
471 }
472
RegisterProxyDeathRecipient(IntellVoiceEngineType type,const sptr<IRemoteObject> & object)473 bool IntellVoiceServiceManager::RegisterProxyDeathRecipient(IntellVoiceEngineType type,
474 const sptr<IRemoteObject> &object)
475 {
476 std::lock_guard<std::mutex> lock(deathMutex_);
477 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
478 deathRecipientObj_[type] = object;
479 if (type == INTELL_VOICE_ENROLL) {
480 proxyDeathRecipient_[type] = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
481 INTELL_VOICE_LOG_INFO("receive enroll proxy death recipient, release enroll engine");
482 HandleReleaseEngine(INTELL_VOICE_ENROLL);
483 });
484 if (proxyDeathRecipient_[type] == nullptr) {
485 INTELL_VOICE_LOG_ERROR("create death recipient failed");
486 return false;
487 }
488 } else if (type == INTELL_VOICE_WAKEUP) {
489 proxyDeathRecipient_[type] = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
490 INTELL_VOICE_LOG_INFO("receive wakeup proxy death recipient, clear wakeup engine callback");
491 TaskExecutor::AddSyncTask([&]() -> int32_t {
492 sptr<EngineBase> engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
493 if (engine != nullptr) {
494 INTELL_VOICE_LOG_INFO("clear wakeup engine callback");
495 engine->SetCallback(nullptr);
496 }
497 return 0;
498 });
499 });
500 if (proxyDeathRecipient_[type] == nullptr) {
501 INTELL_VOICE_LOG_ERROR("create death recipient failed");
502 return false;
503 }
504 } else {
505 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
506 return false;
507 }
508
509 return deathRecipientObj_[type]->AddDeathRecipient(proxyDeathRecipient_[type]);
510 }
511
DeregisterProxyDeathRecipient(IntellVoiceEngineType type)512 bool IntellVoiceServiceManager::DeregisterProxyDeathRecipient(IntellVoiceEngineType type)
513 {
514 std::lock_guard<std::mutex> lock(deathMutex_);
515 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
516 if (deathRecipientObj_.count(type) == 0 || deathRecipientObj_[type] == nullptr) {
517 INTELL_VOICE_LOG_ERROR("death obj is nullptr, type:%{public}d", type);
518 return false;
519 }
520 if (proxyDeathRecipient_.count(type) == 0 || proxyDeathRecipient_[type] == nullptr) {
521 INTELL_VOICE_LOG_ERROR("death recipient is nullptr, type:%{public}d", type);
522 deathRecipientObj_.erase(type);
523 return false;
524 }
525
526 auto ret = deathRecipientObj_[type]->RemoveDeathRecipient(proxyDeathRecipient_[type]);
527 deathRecipientObj_.erase(type);
528 proxyDeathRecipient_.erase(type);
529 return ret;
530 }
531
IsEngineExist(IntellVoiceEngineType type)532 bool IntellVoiceServiceManager::IsEngineExist(IntellVoiceEngineType type)
533 {
534 sptr<EngineBase> engine = GetEngine(type, engines_);
535 if (engine != nullptr) {
536 INTELL_VOICE_LOG_INFO("engine exist, type:%{public}d", type);
537 return true;
538 }
539
540 if (type == INTELL_VOICE_UPDATE && GetUpdateState()) {
541 INTELL_VOICE_LOG_ERROR("update is running");
542 return true;
543 }
544
545 return false;
546 }
547
ProcBreathModel()548 void IntellVoiceServiceManager::ProcBreathModel()
549 {
550 INTELL_VOICE_LOG_INFO("enter");
551 auto triggerMgr = TriggerManager::GetInstance();
552 if (triggerMgr == nullptr) {
553 INTELL_VOICE_LOG_WARN("trigger manager is nullptr");
554 return;
555 }
556
557 std::shared_ptr<uint8_t> buffer = nullptr;
558 uint32_t size = 0;
559 if (!IntellVoiceUtil::ReadFile(WHISPER_MODEL_PATH, buffer, size)) {
560 return;
561 }
562
563 auto model = std::make_shared<GenericTriggerModel>(PROXIMAL_WAKEUP_MODEL_UUID,
564 TriggerModel::TriggerModelVersion::MODLE_VERSION_2, TriggerModel::TriggerModelType::PROXIMAL_WAKEUP_TYPE);
565 if (model == nullptr) {
566 INTELL_VOICE_LOG_ERROR("model is nullptr");
567 return;
568 }
569
570 model->SetData(buffer.get(), size);
571 triggerMgr->UpdateModel(model);
572 }
573
CreateUpdateEngine(const std::string & param)574 bool IntellVoiceServiceManager::CreateUpdateEngine(const std::string ¶m)
575 {
576 sptr<IIntellVoiceEngine> updateEngine = CreateEngine(INTELL_VOICE_UPDATE, param);
577 if (updateEngine == nullptr) {
578 INTELL_VOICE_LOG_ERROR("updateEngine is nullptr");
579 return false;
580 }
581
582 return true;
583 }
584
ReleaseUpdateEngine()585 void IntellVoiceServiceManager::ReleaseUpdateEngine()
586 {
587 ReleaseEngine(INTELL_VOICE_UPDATE);
588 }
589
HandleUpdateComplete(UpdateState result,const std::string & param)590 void IntellVoiceServiceManager::HandleUpdateComplete(UpdateState result, const std::string ¶m)
591 {
592 TaskExecutor::AddAsyncTask([this, result, param]() {
593 bool isLast = false;
594 UpdateEngineController::UpdateCompleteProc(result, param, isLast);
595 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (!isLast)) {
596 INTELL_VOICE_LOG_INFO("enroll engine is existed, or is not last:%{public}d", isLast);
597 return;
598 }
599 SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
600 SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
601 UnloadIntellVoiceService();
602 });
603 }
604
HandleUpdateRetry()605 void IntellVoiceServiceManager::HandleUpdateRetry()
606 {
607 TaskExecutor::AddAsyncTask([this]() {
608 if (UpdateEngineController::UpdateRetryProc()) {
609 INTELL_VOICE_LOG_INFO("retry to update or already force to stop");
610 return;
611 }
612 if (IsEngineExist(INTELL_VOICE_ENROLL)) {
613 INTELL_VOICE_LOG_INFO("enroll engine is existed, do nothing");
614 return;
615 }
616 SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
617 SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
618 UnloadIntellVoiceService();
619 });
620 }
621
SetImproveParam(sptr<EngineBase> engine)622 void IntellVoiceServiceManager::SetImproveParam(sptr<EngineBase> engine)
623 {
624 if (engine == nullptr) {
625 return;
626 }
627
628 // std::string status = QuerySwitchStatus(IMPROVE_KEY) ? "true" : "false";
629 std::string status = "true";
630 engine->SetParameter("userImproveOn=" + status);
631 }
632
GetParameter(const std::string & key)633 std::string IntellVoiceServiceManager::GetParameter(const std::string &key)
634 {
635 std::string val = "";
636
637 if (key == "isEnrolled") {
638 HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
639 val = historyInfoMgr.GetWakeupVesion().empty() ? "false" : "true";
640 INTELL_VOICE_LOG_INFO("get is enroll result %{public}s", val.c_str());
641 } else if (key == "isNeedReEnroll") {
642 val = UpdateEngineUtils::IsVersionUpdate() ? "true" : "false";
643 INTELL_VOICE_LOG_INFO("get nedd reenroll result %{public}s", val.c_str());
644 } else if (key == "wakeup_capability") {
645 val = GetWakeupCapability();
646 INTELL_VOICE_LOG_INFO("get wakeup capability result %{public}s", val.c_str());
647 } else if (key == "isWhispering") {
648 auto audioSystemManager = AudioStandard::AudioSystemManager::GetInstance();
649 if (audioSystemManager == nullptr) {
650 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
651 return val;
652 }
653 val = std::to_string(audioSystemManager->IsWhispering());
654 INTELL_VOICE_LOG_INFO("get isWhispering result %{public}s", val.c_str());
655 }
656
657 return val;
658 }
659
SetParameter(const std::string & keyValueList)660 int32_t IntellVoiceServiceManager::SetParameter(const std::string &keyValueList)
661 {
662 INTELL_VOICE_LOG_INFO("enter");
663 HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
664 std::map<std::string, std::string> kvpairs;
665 IntellVoiceUtil::SplitStringToKVPair(keyValueList, kvpairs);
666 for (auto it : kvpairs) {
667 if (it.first == std::string("Sensibility")) {
668 INTELL_VOICE_LOG_INFO("set Sensibility:%{public}s", it.second.c_str());
669 std::string sensibility = it.second;
670 historyInfoMgr.SetSensibility(sensibility);
671 SetDspSensibility(sensibility);
672 TaskExecutor::AddSyncTask([this, sensibility]() -> int32_t {
673 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
674 if (engine != nullptr) {
675 engine->SetParameter(SENSIBILITY_TEXT + sensibility);
676 }
677 return 0;
678 });
679 break;
680 }
681 }
682 return 0;
683 }
684
GetWakeupCapability()685 std::string IntellVoiceServiceManager::GetWakeupCapability()
686 {
687 INTELL_VOICE_LOG_INFO("enter");
688 Json::Value root;
689 if (IntellVoiceUtil::IsFileExist(VAD_MODEL_PATH)) {
690 root["SupportWhisperWakeup"] = true;
691 } else {
692 root["SupportWhisperWakeup"] = false;
693 }
694
695 if (IntellVoiceUtil::IsFileExist(WAKEUP_CONFIG_USER_PATH)) {
696 root["SupportUserDefinedWakeupPhrase"] = true;
697 } else {
698 root["SupportUserDefinedWakeupPhrase"] = false;
699 }
700
701 auto isSupportShortWordFunc = []() -> bool {
702 std::ifstream jsonStrm(WAKEUP_CONFIG_PATH);
703 if (!jsonStrm.is_open()) {
704 INTELL_VOICE_LOG_ERROR("open file faile!");
705 return false;
706 }
707 Json::Value wakeupJson;
708 Json::CharReaderBuilder reader;
709 reader["collectComments"] = false;
710 std::string errs;
711 if (!parseFromStream(reader, jsonStrm, &wakeupJson, &errs)) {
712 INTELL_VOICE_LOG_ERROR("parseFromStream json faile!");
713 return false;
714 }
715 Json::Value features = wakeupJson["Features"];
716 for (uint32_t i = 0; i < features.size(); i++) {
717 if (features[i].asString() == "short_phrase") {
718 return true;
719 }
720 }
721 return false;
722 };
723 root["SupportShortWord"] = isSupportShortWordFunc();
724 return root.toStyledString();
725 }
726
GetWakeupSourceFilesList(std::vector<std::string> & cloneFiles)727 int32_t IntellVoiceServiceManager::GetWakeupSourceFilesList(std::vector<std::string>& cloneFiles)
728 {
729 return EngineHostManager::GetInstance().GetWakeupSourceFilesList(cloneFiles);
730 }
731
GetWakeupSourceFile(const std::string & filePath,std::vector<uint8_t> & buffer)732 int32_t IntellVoiceServiceManager::GetWakeupSourceFile(const std::string &filePath, std::vector<uint8_t> &buffer)
733 {
734 return EngineHostManager::GetInstance().GetWakeupSourceFile(filePath, buffer);
735 }
736
SendWakeupFile(const std::string & filePath,const std::vector<uint8_t> & buffer)737 int32_t IntellVoiceServiceManager::SendWakeupFile(const std::string &filePath, const std::vector<uint8_t> &buffer)
738 {
739 if (buffer.data() == nullptr) {
740 INTELL_VOICE_LOG_ERROR("send update callback is nullptr");
741 }
742
743 return EngineHostManager::GetInstance().SendWakeupFile(filePath, buffer);
744 }
745
ClearUserData()746 int32_t IntellVoiceServiceManager::ClearUserData()
747 {
748 INTELL_VOICE_LOG_INFO("enter");
749 auto triggerMgr = TriggerManager::GetInstance();
750 if (triggerMgr == nullptr) {
751 INTELL_VOICE_LOG_WARN("trigger manager is nullptr");
752 return -1;
753 }
754
755 triggerMgr->DeleteModel(VOICE_WAKEUP_MODEL_UUID);
756 triggerMgr->DeleteModel(PROXIMAL_WAKEUP_MODEL_UUID);
757 return TaskExecutor::AddSyncTask([this]() -> int32_t {
758 UpdateEngineController::ForceRelease();
759 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
760 if (engine != nullptr) {
761 engine->Detach();
762 }
763 auto wakeupPhrase = HistoryInfoMgr::GetInstance().GetWakeupPhrase();
764 if (!wakeupPhrase.empty()) {
765 EngineHostManager::GetInstance().ClearUserWakeupData(wakeupPhrase);
766 }
767 HistoryInfoMgr::GetInstance().DeleteKey({KEY_WAKEUP_ENGINE_BUNDLE_NAME, KEY_WAKEUP_ENGINE_ABILITY_NAME,
768 KEY_WAKEUP_VESRION, KEY_LANGUAGE, KEY_AREA, KEY_WAKEUP_PHRASE});
769 return UnloadIntellVoiceService();
770 });
771 }
772
HandleCreateEngine(IntellVoiceEngineType type)773 sptr<IIntellVoiceEngine> IntellVoiceServiceManager::HandleCreateEngine(IntellVoiceEngineType type)
774 {
775 return TaskExecutor::AddSyncTask([this, type]() -> sptr<IIntellVoiceEngine> {
776 return CreateEngine(type);
777 });
778 }
779
HandleReleaseEngine(IntellVoiceEngineType type)780 int32_t IntellVoiceServiceManager::HandleReleaseEngine(IntellVoiceEngineType type)
781 {
782 return TaskExecutor::AddSyncTask([this, type]() -> int32_t { return ReleaseEngine(type); });
783 }
784
CloneUpdate(const std::string & wakeupInfo,const sptr<IRemoteObject> & object)785 int32_t IntellVoiceServiceManager::CloneUpdate(const std::string &wakeupInfo, const sptr<IRemoteObject> &object)
786 {
787 sptr<IIntelligentVoiceUpdateCallback> updateCallback = iface_cast<IIntelligentVoiceUpdateCallback>(object);
788 if (updateCallback == nullptr) {
789 INTELL_VOICE_LOG_ERROR("update callback is nullptr");
790 return -1;
791 }
792
793 if (wakeupInfo.empty()) {
794 INTELL_VOICE_LOG_ERROR("clone info empty");
795 return -1;
796 }
797
798 std::shared_ptr<CloneUpdateStrategy> cloneStrategy =
799 std::make_shared<CloneUpdateStrategy>(wakeupInfo, updateCallback);
800 if (cloneStrategy == nullptr) {
801 INTELL_VOICE_LOG_ERROR("clone strategy is nullptr");
802 return -1;
803 }
804
805 INTELL_VOICE_LOG_INFO("enter");
806 std::shared_ptr<IUpdateStrategy> strategy = std::dynamic_pointer_cast<IUpdateStrategy>(cloneStrategy);
807 return CreateUpdateEngineUntilTime(strategy);
808 }
809
HandleCloneUpdate(const std::string & wakeupInfo,const sptr<IRemoteObject> & object)810 int32_t IntellVoiceServiceManager::HandleCloneUpdate(const std::string &wakeupInfo, const sptr<IRemoteObject> &object)
811 {
812 return TaskExecutor::AddSyncTask([this, wakeupInfo, object = std::move(object)]() -> int32_t {
813 return CloneUpdate(wakeupInfo, object);
814 });
815 }
816
SilenceUpdate()817 int32_t IntellVoiceServiceManager::SilenceUpdate()
818 {
819 std::shared_ptr<SilenceUpdateStrategy> silenceStrategy = std::make_shared<SilenceUpdateStrategy>("");
820 if (silenceStrategy == nullptr) {
821 INTELL_VOICE_LOG_ERROR("silence strategy is nullptr");
822 return -1;
823 }
824
825 INTELL_VOICE_LOG_INFO("enter");
826 std::shared_ptr<IUpdateStrategy> strategy = std::dynamic_pointer_cast<IUpdateStrategy>(silenceStrategy);
827 return CreateUpdateEngineUntilTime(strategy);
828 }
829
HandleSilenceUpdate()830 void IntellVoiceServiceManager::HandleSilenceUpdate()
831 {
832 TaskExecutor::AddAsyncTask([this]() { SilenceUpdate(); });
833 }
834
SwitchOnProc(int32_t uuid,bool needUpdateAdapter)835 int32_t IntellVoiceServiceManager::SwitchOnProc(int32_t uuid, bool needUpdateAdapter)
836 {
837 INTELL_VOICE_LOG_INFO("enter, uuid:%{public}d", uuid);
838 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (IsEngineExist(INTELL_VOICE_UPDATE))) {
839 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
840 return 0;
841 }
842
843 if (!QuerySwitchByUuid(uuid)) {
844 INTELL_VOICE_LOG_INFO("switch is off, do nothing, uuid is %{public}d", uuid);
845 return 0;
846 }
847
848 CreateAndStartServiceObject(uuid, needUpdateAdapter);
849 INTELL_VOICE_LOG_INFO("exit");
850 return 0;
851 }
852
HandleSwitchOn(bool isAsync,int32_t uuid,bool needUpdateAdapter)853 void IntellVoiceServiceManager::HandleSwitchOn(bool isAsync, int32_t uuid, bool needUpdateAdapter)
854 {
855 INTELL_VOICE_LOG_INFO("enter, isAsync:%{public}d, uuid:%{public}d, needUpdateAdapter:%{public}d",
856 isAsync, uuid, needUpdateAdapter);
857 if (isAsync) {
858 TaskExecutor::AddAsyncTask([this, uuid, needUpdateAdapter]() { SwitchOnProc(uuid, needUpdateAdapter); });
859 } else {
860 TaskExecutor::AddSyncTask([this, uuid, needUpdateAdapter]() -> int32_t {
861 return SwitchOnProc(uuid, needUpdateAdapter);
862 });
863 }
864 INTELL_VOICE_LOG_INFO("exit");
865 }
866
SwitchOffProc(int32_t uuid)867 int32_t IntellVoiceServiceManager::SwitchOffProc(int32_t uuid)
868 {
869 INTELL_VOICE_LOG_INFO("enter, uuid:%{public}d", uuid);
870 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (IsEngineExist(INTELL_VOICE_UPDATE))) {
871 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
872 return 0;
873 }
874
875 if (QuerySwitchByUuid(uuid)) {
876 INTELL_VOICE_LOG_INFO("switch is on, do nothing, uuid is %{public}d", uuid);
877 return 0;
878 }
879
880 ReleaseServiceObject(uuid);
881 INTELL_VOICE_LOG_INFO("exit, uuid:%{public}d", uuid);
882 return 0;
883 }
884
HandleSwitchOff(bool isAsync,int32_t uuid)885 void IntellVoiceServiceManager::HandleSwitchOff(bool isAsync, int32_t uuid)
886 {
887 INTELL_VOICE_LOG_INFO("enter, isAsync:%{public}d, uuid:%{public}d", isAsync, uuid);
888 if (!isAsync) {
889 TaskExecutor::AddSyncTask([this, uuid]() -> int32_t { return SwitchOffProc(uuid); });
890 } else {
891 TaskExecutor::AddAsyncTask([this, uuid]() { SwitchOffProc(uuid); });
892 }
893 }
894
HandleCloseWakeupSource()895 void IntellVoiceServiceManager::HandleCloseWakeupSource()
896 {
897 INTELL_VOICE_LOG_INFO("enter");
898 TaskExecutor::AddAsyncTask([this]() { StartDetection(VOICE_WAKEUP_MODEL_UUID); });
899 TaskExecutor::AddAsyncTask([this]() { StartDetection(PROXIMAL_WAKEUP_MODEL_UUID); });
900 }
901
IsNeedToUnloadService()902 bool IntellVoiceServiceManager::IsNeedToUnloadService()
903 {
904 if ((IsEngineExist(INTELL_VOICE_ENROLL)) || (IsEngineExist(INTELL_VOICE_UPDATE))) {
905 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, no need to unload service");
906 return false;
907 }
908
909 if ((QuerySwitchStatus(WAKEUP_KEY)) || (QuerySwitchStatus(WHISPER_KEY))) {
910 INTELL_VOICE_LOG_INFO("switch is on, no need to unload service");
911 return false;
912 }
913
914 return true;
915 }
916
UnloadIntellVoiceService()917 int32_t IntellVoiceServiceManager::UnloadIntellVoiceService()
918 {
919 INTELL_VOICE_LOG_INFO("enter");
920 if (!IsNeedToUnloadService()) {
921 return 0;
922 }
923
924 std::thread([]() {
925 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
926 if (systemAbilityMgr == nullptr) {
927 INTELL_VOICE_LOG_ERROR("failed to get systemabilitymanager");
928 return;
929 }
930
931 int32_t ret = systemAbilityMgr->UnloadSystemAbility(INTELL_VOICE_SERVICE_ID);
932 if (ret != 0) {
933 INTELL_VOICE_LOG_ERROR("failed to unload intellvoice service, ret: %{public}d", ret);
934 return;
935 }
936 INTELL_VOICE_LOG_INFO("success to notify samgr to unload intell voice service");
937 }).detach();
938
939 return 0;
940 }
941
HandleUnloadIntellVoiceService(bool isAsync)942 void IntellVoiceServiceManager::HandleUnloadIntellVoiceService(bool isAsync)
943 {
944 INTELL_VOICE_LOG_INFO("enter");
945 if (isAsync) {
946 TaskExecutor::AddAsyncTask([this]() { UnloadIntellVoiceService(); });
947 } else {
948 TaskExecutor::AddSyncTask([this]() -> int32_t { return UnloadIntellVoiceService(); });
949 }
950 }
951
HandleOnIdle()952 bool IntellVoiceServiceManager::HandleOnIdle()
953 {
954 return TaskExecutor::AddSyncTask([this]() -> bool { return IsNeedToUnloadService(); });
955 }
956
HandleServiceStop()957 void IntellVoiceServiceManager::HandleServiceStop()
958 {
959 TaskExecutor::AddSyncTask([this]() -> int32_t { return ServiceStopProc(); });
960 }
961
HandleHeadsetHostDie()962 void IntellVoiceServiceManager::HandleHeadsetHostDie()
963 {
964 TaskExecutor::AddAsyncTask([this]() {
965 auto engine = GetEngine(INTELL_VOICE_WAKEUP, engines_);
966 if (engine != nullptr) {
967 engine->NotifyHeadsetHostEvent(HEADSET_HOST_ON);
968 }
969 });
970 }
971
OnTriggerConnectServiceStart()972 void IntellVoiceServiceManager::OnTriggerConnectServiceStart()
973 {
974 HandleSwitchOn(true, VOICE_WAKEUP_MODEL_UUID, false);
975 HandleSwitchOn(true, PROXIMAL_WAKEUP_MODEL_UUID, false);
976 }
977 } // namespace IntellVoiceEngine
978 } // namespace OHOS
979