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 &param)
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 &param)
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 &param)
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 &param)
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