• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <any>
21 #include "intell_voice_log.h"
22 #include "intell_voice_util.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "intell_voice_generic_factory.h"
26 #include "memory_guard.h"
27 #include "string_util.h"
28 #include "history_info_mgr.h"
29 
30 #define LOG_TAG "IntellVoiceServiceManager"
31 
32 using namespace OHOS::IntellVoiceTrigger;
33 using namespace OHOS::IntellVoiceEngine;
34 using namespace OHOS::IntellVoiceUtils;
35 
36 namespace OHOS {
37 namespace IntellVoiceEngine {
38 static constexpr int32_t WAIT_AUDIO_HAL_INTERVAL = 500; //500ms
39 static constexpr uint32_t MAX_TASK_NUM = 2048;
40 static constexpr uint32_t WAIT_SWICTH_ON_TIME = 2000;  // 2000ms
41 static constexpr uint32_t WAIT_RECORD_START_TIME = 10000; // 10s
42 static const std::string STOP_ALL_RECOGNITION = "stop_all_recognition";
43 static const std::string SHORT_WORD_SWITCH = "short_word_switch";
44 template<typename T, typename E>
IntellVoiceServiceManager()45 IntellVoiceServiceManager<T, E>::IntellVoiceServiceManager() : TaskExecutor("ServMgrThread", MAX_TASK_NUM)
46 {
47     TaskExecutor::StartThread();
48 #if defined(ENGINE_ENABLE) || defined(FIRST_STAGE_ONESHOT_ENABLE)
49     RegisterEngineCallbacks();
50 #endif
51 #ifdef TRIGGER_ENABLE
52     RegisterTriggerCallbacks();
53 #endif
54 #ifdef USE_FFRT
55     taskQueue_ = std::make_shared<ffrt::queue>("ServMgrQueue");
56 #endif
57 }
58 
59 template<typename T, typename E>
~IntellVoiceServiceManager()60 IntellVoiceServiceManager<T, E>::~IntellVoiceServiceManager()
61 {
62     INTELL_VOICE_LOG_INFO("enter");
63 #ifdef USE_FFRT
64     if (taskQueue_ != nullptr) {
65         taskQueue_.reset();
66     }
67 #endif
68     TaskExecutor::StopThread();
69 }
70 
71 template<typename T, typename E>
CreateSwitchProvider()72 void IntellVoiceServiceManager<T, E>::CreateSwitchProvider()
73 {
74     INTELL_VOICE_LOG_INFO("enter");
75     std::lock_guard<std::mutex> lock(switchMutex_);
76     switchProvider_ = UniquePtrFactory<SwitchProvider>::CreateInstance();
77     if (switchProvider_ == nullptr) {
78         INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
79         return;
80     }
81     RegisterObserver(WAKEUP_KEY);
82     RegisterObserver(WHISPER_KEY);
83     RegisterObserver(SHORTWORD_KEY);
84 }
85 
86 template<typename T, typename E>
RegisterObserver(const std::string & switchKey)87 void IntellVoiceServiceManager<T, E>::RegisterObserver(const std::string &switchKey)
88 {
89     switchObserver_[switchKey] = sptr<SwitchObserver>(new (std::nothrow) SwitchObserver());
90     if (switchObserver_[switchKey] == nullptr) {
91         INTELL_VOICE_LOG_ERROR("switchObserver_ is nullptr");
92         return;
93     }
94     switchObserver_[switchKey]->SetUpdateFunc([this, switchKey]() {
95         OnSwitchChange(switchKey);
96     });
97 
98     switchProvider_->RegisterObserver(switchObserver_[switchKey], switchKey);
99 }
100 
101 template<typename T, typename E>
ReleaseSwitchProvider()102 void IntellVoiceServiceManager<T, E>::ReleaseSwitchProvider()
103 {
104     std::lock_guard<std::mutex> lock(switchMutex_);
105     if (switchProvider_ == nullptr) {
106         INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
107         return;
108     }
109 
110     for (auto it : switchObserver_) {
111         if (it.second != nullptr) {
112             switchProvider_->UnregisterObserver(it.second, it.first);
113         }
114     }
115     switchProvider_ = nullptr;
116 }
117 
118 template<typename T, typename E>
StartDetection(int32_t uuid)119 bool IntellVoiceServiceManager<T, E>::StartDetection(int32_t uuid)
120 {
121     if (E::AnyEngineExist({INTELL_VOICE_ENROLL, INTELL_VOICE_UPDATE})) {
122         INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
123         return false;
124     }
125     if (!QuerySwitchByUuid(uuid)) {
126         INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
127         return false;
128     }
129 
130     int32_t ret = T::StartDetection(uuid);
131     if (ret == 1) {
132         isStarted_[uuid] = true;
133         return true;
134     }
135 
136     if (ret == 0) {
137         return AddStartDetectionTask(uuid);
138     }
139 
140     return false;
141 }
142 
143 template<typename T, typename E>
StopDetection(int32_t uuid)144 void IntellVoiceServiceManager<T, E>::StopDetection(int32_t uuid)
145 {
146     T::StopDetection(uuid);
147 }
148 
149 template<typename T, typename E>
QuerySwitchStatus(const std::string & key)150 bool IntellVoiceServiceManager<T, E>::QuerySwitchStatus(const std::string &key)
151 {
152     std::lock_guard<std::mutex> lock(switchMutex_);
153     if (!IsSwitchKeyValid(key)) {
154         INTELL_VOICE_LOG_ERROR("invalid key :%{public}s", key.c_str());
155         return false;
156     }
157 
158     if (switchProvider_ == nullptr) {
159         INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
160         return false;
161     }
162     return switchProvider_->QuerySwitchStatus(key);
163 }
164 
165 template<typename T, typename E>
IsSwitchError(const std::string & key)166 bool IntellVoiceServiceManager<T, E>::IsSwitchError(const std::string &key)
167 {
168     std::lock_guard<std::mutex> lock(switchMutex_);
169     if (switchProvider_ == nullptr) {
170         INTELL_VOICE_LOG_ERROR("switchProvider_ is nullptr");
171         return true;
172     }
173 
174     return switchProvider_->IsSwitchError(key);
175 }
176 
177 template<typename T, typename E>
OnSwitchChange(const std::string & switchKey)178 void IntellVoiceServiceManager<T, E>::OnSwitchChange(const std::string &switchKey)
179 {
180     if (switchKey == WAKEUP_KEY) {
181         if (QuerySwitchStatus(switchKey)) {
182             NoiftySwitchOnToPowerChange();
183             HandleSwitchOn(false, VOICE_WAKEUP_MODEL_UUID, false);
184         } else {
185             HandleSwitchOff(false, VOICE_WAKEUP_MODEL_UUID);
186             INTELL_VOICE_LOG_INFO("switch off process finish");
187             HandleUnloadIntellVoiceService(false);
188         }
189     } else if (switchKey == WHISPER_KEY) {
190         if (QuerySwitchStatus(switchKey)) {
191             NoiftySwitchOnToPowerChange();
192             HandleSwitchOn(false, PROXIMAL_WAKEUP_MODEL_UUID, false);
193         } else {
194             HandleSwitchOff(false, PROXIMAL_WAKEUP_MODEL_UUID);
195             HandleUnloadIntellVoiceService(false);
196         }
197     } else if (switchKey == SHORTWORD_KEY) {
198         TaskExecutor::AddSyncTask([this]() -> int32_t {
199             INTELL_VOICE_LOG_INFO("short word switch change");
200             if (E::AnyEngineExist({INTELL_VOICE_ENROLL, INTELL_VOICE_UPDATE})) {
201                 INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
202                 return 0;
203             }
204             StopDetection(VOICE_WAKEUP_MODEL_UUID);
205             StopDetection(PROXIMAL_WAKEUP_MODEL_UUID);
206             E::CreateOrResetWakeupEngine();
207             SetShortWordStatus();
208             StartDetection(VOICE_WAKEUP_MODEL_UUID);
209             StartDetection(PROXIMAL_WAKEUP_MODEL_UUID);
210             return 0;
211         });
212     }
213 }
214 
215 template<typename T, typename E>
SetShortWordStatus()216 void IntellVoiceServiceManager<T, E>::SetShortWordStatus()
217 {
218     INTELL_VOICE_LOG_INFO("enter");
219     if (QuerySwitchStatus(SHORTWORD_KEY)) {
220         INTELL_VOICE_LOG_INFO("short_word_switch true");
221         T::SetParameter(SHORT_WORD_SWITCH, "1");
222     } else {
223         INTELL_VOICE_LOG_INFO("short_word_switch false");
224         T::SetParameter(SHORT_WORD_SWITCH, "0");
225     }
226 }
227 
228 template<typename T, typename E>
ProcBreathModel()229 void IntellVoiceServiceManager<T, E>::ProcBreathModel()
230 {
231     INTELL_VOICE_LOG_INFO("enter");
232     std::shared_ptr<uint8_t> buffer = nullptr;
233     uint32_t size = 0;
234     if (!IntellVoiceUtil::ReadFile(WHISPER_MODEL_PATH, buffer, size)) {
235         return;
236     }
237     std::vector<uint8_t> data(buffer.get(), buffer.get() + size);
238     T::UpdateModel(data, PROXIMAL_WAKEUP_MODEL_UUID, TriggerModelType::PROXIMAL_WAKEUP_TYPE);
239 }
240 
241 template<typename T, typename E>
ClearUserData()242 int32_t IntellVoiceServiceManager<T, E>::ClearUserData()
243 {
244     INTELL_VOICE_LOG_INFO("enter");
245     T::DeleteModel(VOICE_WAKEUP_MODEL_UUID);
246     T::DeleteModel(PROXIMAL_WAKEUP_MODEL_UUID);
247     return TaskExecutor::AddSyncTask([this]() -> int32_t {
248         E::ClearUserDataInner();
249         HistoryInfoMgr::GetInstance().DeleteKey({KEY_WAKEUP_ENGINE_BUNDLE_NAME, KEY_WAKEUP_ENGINE_ABILITY_NAME,
250             KEY_WAKEUP_VESRION, KEY_LANGUAGE, KEY_AREA, KEY_WAKEUP_PHRASE, KEY_WHISPER_VPR});
251         return UnloadIntellVoiceService();
252     });
253 }
254 
255 template<typename T, typename E>
IsNeedToUnloadService()256 bool IntellVoiceServiceManager<T, E>::IsNeedToUnloadService()
257 {
258     if (E::AnyEngineExist({INTELL_VOICE_ENROLL, INTELL_VOICE_UPDATE})) {
259         INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, no need to unload service");
260         return false;
261     }
262     if ((QuerySwitchStatus(WAKEUP_KEY)) || (QuerySwitchStatus(WHISPER_KEY))) {
263         INTELL_VOICE_LOG_INFO("switch is on, no need to unload service");
264         return false;
265     }
266 
267     return true;
268 }
269 
270 template<typename T, typename E>
UnloadIntellVoiceService()271 int32_t IntellVoiceServiceManager<T, E>::UnloadIntellVoiceService()
272 {
273     INTELL_VOICE_LOG_INFO("enter");
274     if (!IsNeedToUnloadService()) {
275         return 0;
276     }
277 
278     std::thread([]() {
279         auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
280         if (systemAbilityMgr == nullptr) {
281             INTELL_VOICE_LOG_ERROR("failed to get systemabilitymanager");
282             return;
283         }
284 
285         int32_t ret = systemAbilityMgr->UnloadSystemAbility(INTELL_VOICE_SERVICE_ID);
286         if (ret != 0) {
287             INTELL_VOICE_LOG_ERROR("failed to unload intellvoice service, ret: %{public}d", ret);
288             return;
289         }
290         INTELL_VOICE_LOG_INFO("success to notify samgr to unload intell voice service");
291     }).detach();
292 
293     return 0;
294 }
295 
296 template<typename T, typename E>
HandleUnloadIntellVoiceService(bool isAsync)297 void IntellVoiceServiceManager<T, E>::HandleUnloadIntellVoiceService(bool isAsync)
298 {
299     INTELL_VOICE_LOG_INFO("enter");
300     if (isAsync) {
301         TaskExecutor::AddAsyncTask([this]() { UnloadIntellVoiceService(); });
302     } else {
303         TaskExecutor::AddSyncTask([this]() -> int32_t { return UnloadIntellVoiceService(); });
304     }
305 }
306 
307 template<typename T, typename E>
HandleOnIdle()308 bool IntellVoiceServiceManager<T, E>::HandleOnIdle()
309 {
310     return TaskExecutor::AddSyncTask([this]() -> bool { return IsNeedToUnloadService(); });
311 }
312 
313 template<typename T, typename E>
NoiftySwitchOnToPowerChange()314 void IntellVoiceServiceManager<T, E>::NoiftySwitchOnToPowerChange()
315 {
316     {
317         std::unique_lock<std::mutex> lock(powerModeChangeMutex_);
318         if (!notifyPowerModeChange_) {
319             INTELL_VOICE_LOG_INFO("no need to notify");
320             return;
321         }
322     }
323 
324     powerModeChangeCv_.notify_all();
325 }
326 
327 template<typename T, typename E>
HandlePowerSaveModeChange()328 void IntellVoiceServiceManager<T, E>::HandlePowerSaveModeChange()
329 {
330     if ((QuerySwitchStatus(WAKEUP_KEY)) || (QuerySwitchStatus(WHISPER_KEY))) {
331         INTELL_VOICE_LOG_INFO("switch is on, no need to process");
332         return;
333     }
334 
335     std::thread([&]() {
336         std::unique_lock<std::mutex> lock(powerModeChangeMutex_);
337         if ((QuerySwitchStatus(WAKEUP_KEY)) || (QuerySwitchStatus(WHISPER_KEY))) {
338             INTELL_VOICE_LOG_INFO("switch is on, no need to process");
339             return;
340         }
341         notifyPowerModeChange_ = true;
342         if (powerModeChangeCv_.wait_for(lock, std::chrono::milliseconds(WAIT_SWICTH_ON_TIME),
343             [this] { return ((this->QuerySwitchStatus(WAKEUP_KEY)) || (this->QuerySwitchStatus(WHISPER_KEY))); })) {
344             INTELL_VOICE_LOG_INFO("switch is on, do nothing");
345             notifyPowerModeChange_ = false;
346             return;
347         }
348         INTELL_VOICE_LOG_WARN("wait time out, switch is off, need to unload service");
349         notifyPowerModeChange_ = false;
350         HandleUnloadIntellVoiceService(true);
351     }).detach();
352 }
353 
354 template<typename T, typename E>
OnTriggerConnectServiceStart()355 void IntellVoiceServiceManager<T, E>::OnTriggerConnectServiceStart()
356 {
357     INTELL_VOICE_LOG_INFO("enter");
358     TaskExecutor::AddAsyncTask([this]() { SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, false); },
359         "IntellVoiceServiceManager::OnTriggerConnectServiceStart::start wakeup", false);
360     TaskExecutor::AddAsyncTask([this]() { SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, false); },
361         "IntellVoiceServiceManager::OnTriggerConnectServiceStart::start proximal", false);
362 }
363 
364 template<typename T, typename E>
HandleCreateEngine(IntellVoiceEngineType type)365 sptr<IIntellVoiceEngine> IntellVoiceServiceManager<T, E>::HandleCreateEngine(IntellVoiceEngineType type)
366 {
367     return TaskExecutor::AddSyncTask([this, type]() -> sptr<IIntellVoiceEngine> {
368             if (type == INTELL_VOICE_ENROLL) {
369                 StopDetection(VOICE_WAKEUP_MODEL_UUID);
370                 StopDetection(PROXIMAL_WAKEUP_MODEL_UUID);
371             }
372             return E::CreateEngine(type);
373     });
374 }
375 
376 template<typename T, typename E>
HandleReleaseEngine(IntellVoiceEngineType type)377 int32_t IntellVoiceServiceManager<T, E>::HandleReleaseEngine(IntellVoiceEngineType type)
378 {
379     return TaskExecutor::AddSyncTask([this, type]() -> int32_t {return ReleaseEngine(type); });
380 }
381 
382 template<typename T, typename E>
ReleaseEngine(IntellVoiceEngineType type)383 int32_t IntellVoiceServiceManager<T, E>::ReleaseEngine(IntellVoiceEngineType type)
384 {
385     INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
386     auto ret = E::ReleaseEngineInner(type);
387     if (ret != 0) {
388         return ret;
389     }
390 
391     if (type != INTELL_VOICE_ENROLL) {
392         return 0;
393     }
394 
395     if (E::GetEnrollResult(type)) {
396         if (IntellVoiceUtil::IsFileExist(WHISPER_VPR_CONFIG_PATH)) {
397             HandleWhisperVprUpdate();
398         } else {
399             SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
400             SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
401             SwitchOffProc(PROXIMAL_WAKEUP_MODEL_UUID);
402         }
403     } else {
404         SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
405         SwitchOffProc(VOICE_WAKEUP_MODEL_UUID);
406         SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
407         SwitchOffProc(PROXIMAL_WAKEUP_MODEL_UUID);
408         UnloadIntellVoiceService();
409     }
410 
411     return 0;
412 }
413 
414 template<typename T, typename E>
SwitchOnProc(int32_t uuid,bool needUpdateAdapter)415 int32_t IntellVoiceServiceManager<T, E>::SwitchOnProc(int32_t uuid, bool needUpdateAdapter)
416 {
417     INTELL_VOICE_LOG_INFO("enter, uuid:%{public}d", uuid);
418     if (E::AnyEngineExist({INTELL_VOICE_ENROLL, INTELL_VOICE_UPDATE})) {
419         INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
420         return 0;
421     }
422     if (!QuerySwitchByUuid(uuid)) {
423         INTELL_VOICE_LOG_INFO("switch is off, do nothing, uuid is %{public}d", uuid);
424         return 0;
425     }
426 
427     CreateAndStartServiceObject(uuid, needUpdateAdapter);
428     INTELL_VOICE_LOG_INFO("exit");
429     return 0;
430 }
431 
432 template<typename T, typename E>
CreateAndStartServiceObject(int32_t uuid,bool needResetAdapter)433 void IntellVoiceServiceManager<T, E>::CreateAndStartServiceObject(int32_t uuid, bool needResetAdapter)
434 {
435 #ifdef TRIGGER_ENABLE
436     if (!T::IsModelExist(uuid)) {
437         INTELL_VOICE_LOG_INFO("no model");
438         return;
439     }
440 #endif
441 
442     if (!QuerySwitchByUuid(uuid)) {
443         INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
444         return;
445     }
446 
447 #if defined(ENGINE_ENABLE) || defined(FIRST_STAGE_ONESHOT_ENABLE)
448         INTELL_VOICE_LOG_INFO("is not single wakeup level");
449         if (!needResetAdapter) {
450             E::CreateEngine(INTELL_VOICE_WAKEUP);
451         } else {
452             E::CreateOrResetWakeupEngine();
453         }
454         T::CreateDetector(uuid, [this, uuid]() { OnDetected(uuid); });
455 #else
456         T::CreateDetector(uuid, [this, uuid]() { OnSingleLevelDetected(); });
457 #endif
458 
459     if (uuid == VOICE_WAKEUP_MODEL_UUID) {
460         SetShortWordStatus();
461     }
462 
463     if (!StartDetection(uuid)) {
464         INTELL_VOICE_LOG_ERROR("failed to start detection");
465     }
466 }
467 
468 template<typename T, typename E>
SwitchOffProc(int32_t uuid)469 int32_t IntellVoiceServiceManager<T, E>::SwitchOffProc(int32_t uuid)
470 {
471     INTELL_VOICE_LOG_INFO("enter, uuid:%{public}d", uuid);
472     if (E::AnyEngineExist({INTELL_VOICE_ENROLL, INTELL_VOICE_UPDATE})) {
473         INTELL_VOICE_LOG_INFO("enroll engine or update engine exist, do nothing");
474         return 0;
475     }
476     if (QuerySwitchByUuid(uuid)) {
477         INTELL_VOICE_LOG_INFO("switch is on, do nothing, uuid is %{public}d", uuid);
478         return 0;
479     }
480 
481     DelStartDetectionTask(uuid);
482     ReleaseServiceObject(uuid);
483     INTELL_VOICE_LOG_INFO("exit, uuid:%{public}d", uuid);
484     return 0;
485 }
486 
487 template<typename T, typename E>
AddStartDetectionTask(int32_t uuid)488 bool IntellVoiceServiceManager<T, E>::AddStartDetectionTask(int32_t uuid)
489 {
490 #ifdef USE_FFRT
491     INTELL_VOICE_LOG_INFO("enter");
492     if (taskQueue_ == nullptr) {
493         INTELL_VOICE_LOG_ERROR("task queue is nullptr");
494         return false;
495     }
496 
497     if ((taskHandle_.count(uuid) != 0) && (taskHandle_[uuid] != nullptr)) {
498         INTELL_VOICE_LOG_INFO("task handle is exist, uuid is %{public}d", uuid);
499         return true;
500     }
501 
502     taskHandle_[uuid] = taskQueue_->submit_h(std::bind([uuid, this]() {
503         if (!QuerySwitchByUuid(uuid)) {
504             INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
505             return;
506         }
507 
508         INTELL_VOICE_LOG_INFO("begin to wait");
509         while (T::GetParameter("audio_hal_status") != "true") {
510             ffrt::this_task::sleep_for(std::chrono::milliseconds(WAIT_AUDIO_HAL_INTERVAL));
511             if (!QuerySwitchByUuid(uuid)) {
512                 INTELL_VOICE_LOG_INFO("switch is off, uuid is %{public}d", uuid);
513                 return;
514             }
515         }
516         INTELL_VOICE_LOG_INFO("end to wait");
517         TaskExecutor::AddAsyncTask([uuid, this]() {
518             if (isStarted_.count(uuid) != 0 && isStarted_[uuid]) {
519                 INTELL_VOICE_LOG_INFO("already start, uuid is %{public}d", uuid);
520                 return;
521             }
522             StartDetection(uuid);
523         });
524     }));
525 #endif
526     return true;
527 }
528 
529 template<typename T, typename E>
DelStartDetectionTask(int32_t uuid)530 void IntellVoiceServiceManager<T, E>::DelStartDetectionTask(int32_t uuid)
531 {
532 #ifdef USE_FFRT
533     INTELL_VOICE_LOG_INFO("enter");
534     if (taskQueue_ == nullptr) {
535         INTELL_VOICE_LOG_ERROR("task queue is nullptr");
536         return;
537     }
538 
539     if ((taskHandle_.count(uuid) != 0) && (taskHandle_[uuid] != nullptr)) {
540         taskQueue_->cancel(taskHandle_[uuid]);
541         taskHandle_.erase(uuid);
542         INTELL_VOICE_LOG_INFO("task is canceled");
543     }
544 #endif
545 
546     if (isStarted_.count(uuid)) {
547         isStarted_.erase(uuid);
548     }
549 }
550 
551 template<typename T, typename E>
ReleaseServiceObject(int32_t uuid)552 void IntellVoiceServiceManager<T, E>::ReleaseServiceObject(int32_t uuid)
553 {
554     T::ReleaseTriggerDetector(uuid);
555 }
556 
557 template<typename T, typename E>
HandleSilenceUpdate()558 void IntellVoiceServiceManager<T, E>::HandleSilenceUpdate()
559 {
560     TaskExecutor::AddAsyncTask([this]() {
561         int32_t ret = E::SilenceUpdate();
562         if (ret != 0 && IntellVoiceUtil::IsFileExist(WHISPER_VPR_CONFIG_PATH)
563             && HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WHISPER_VPR) == "false") {
564             E::WhisperVprUpdate();
565         }
566     });
567 }
568 
569 template<typename T, typename E>
HandleWhisperVprUpdate()570 void IntellVoiceServiceManager<T, E>::HandleWhisperVprUpdate()
571 {
572     INTELL_VOICE_LOG_INFO("enter");
573     TaskExecutor::AddAsyncTask([this]() {
574         E::WhisperVprUpdate();
575     });
576 }
577 
578 template<typename T, typename E>
HandleCloneUpdate(const std::string & wakeupInfo,const sptr<IRemoteObject> & object)579 int32_t IntellVoiceServiceManager<T, E>::HandleCloneUpdate(const std::string &wakeupInfo,
580     const sptr<IRemoteObject> &object)
581 {
582     return TaskExecutor::AddSyncTask([this, wakeupInfo, object = std::move(object)]() -> int32_t {
583         return E::CloneUpdate(wakeupInfo, object);
584     });
585 }
586 
587 template<typename T, typename E>
StopWakeupSource()588 void IntellVoiceServiceManager<T, E>::StopWakeupSource()
589 {
590     INTELL_VOICE_LOG_INFO("enter, stop all recognition");
591     TaskExecutor::AddAsyncTask([this]() {
592         T::SetParameter(STOP_ALL_RECOGNITION, "true");
593         }, "IntellVoiceServiceManager::StopWakeupSource", false);
594 }
595 
596 template<typename T, typename E>
HandleCloseWakeupSource(bool isNeedStop)597 void IntellVoiceServiceManager<T, E>::HandleCloseWakeupSource(bool isNeedStop)
598 {
599     INTELL_VOICE_LOG_INFO("enter, isNeedStop:%{public}d", isNeedStop);
600     TaskExecutor::AddAsyncTask([this, isNeedStop]() {
601         if (isNeedStop) {
602             T::SetParameter(STOP_ALL_RECOGNITION, "true");
603         }
604         StartDetection(VOICE_WAKEUP_MODEL_UUID);
605         StartDetection(PROXIMAL_WAKEUP_MODEL_UUID);
606         }, "IntellVoiceServiceManager::HandleCloseWakeupSource", false);
607 }
608 
609 template<typename T, typename E>
HandleServiceStop()610 void IntellVoiceServiceManager<T, E>::HandleServiceStop()
611 {
612     TaskExecutor::AddSyncTask([this]() -> int32_t {
613         return E::ServiceStopProc();
614     });
615     if (IsSwitchError(WAKEUP_KEY)) {
616         INTELL_VOICE_LOG_WARN("db is abnormal, can not find wakeup switch, notify db error");
617         IntellVoiceUtil::StartAbility("db_error");
618     }
619 }
620 
621 template<typename T, typename E>
HandleHeadsetHostDie()622 void IntellVoiceServiceManager<T, E>::HandleHeadsetHostDie()
623 {
624     TaskExecutor::AddSyncTask([this]() -> int32_t {
625         E::HeadsetHostDie();
626         return 0;
627     });
628 }
629 
630 template<typename T, typename E>
HandleClearWakeupEngineCb()631 void IntellVoiceServiceManager<T, E>::HandleClearWakeupEngineCb()
632 {
633     TaskExecutor::AddSyncTask([this]() -> int32_t {
634         E::ClearWakeupEngineCb();
635         return 0;
636     });
637 }
638 
639 template<typename T, typename E>
HandleSwitchOff(bool isAsync,int32_t uuid)640 void IntellVoiceServiceManager<T, E>::HandleSwitchOff(bool isAsync, int32_t uuid)
641 {
642     INTELL_VOICE_LOG_INFO("enter, isAsync:%{public}d, uuid:%{public}d", isAsync, uuid);
643     if (!isAsync) {
644         TaskExecutor::AddSyncTask([this, uuid]() -> int32_t { return SwitchOffProc(uuid); });
645     } else {
646         TaskExecutor::AddAsyncTask([this, uuid]() { SwitchOffProc(uuid); });
647     }
648 }
649 
650 template<typename T, typename E>
HandleSwitchOn(bool isAsync,int32_t uuid,bool needUpdateAdapter)651 void IntellVoiceServiceManager<T, E>::HandleSwitchOn(bool isAsync, int32_t uuid, bool needUpdateAdapter)
652 {
653     INTELL_VOICE_LOG_INFO("enter, isAsync:%{public}d, uuid:%{public}d, needUpdateAdapter:%{public}d",
654         isAsync, uuid, needUpdateAdapter);
655     if (isAsync) {
656         TaskExecutor::AddAsyncTask([this, uuid, needUpdateAdapter]() { SwitchOnProc(uuid, needUpdateAdapter); });
657     } else {
658         TaskExecutor::AddSyncTask([this, uuid, needUpdateAdapter]() -> int32_t {
659             return SwitchOnProc(uuid, needUpdateAdapter);
660         });
661     }
662     INTELL_VOICE_LOG_INFO("exit");
663 }
664 
665 template<typename T, typename E>
HandleUpdateComplete(int32_t result,const std::string & param)666 void IntellVoiceServiceManager<T, E>::HandleUpdateComplete(int32_t result, const std::string &param)
667 {
668     TaskExecutor::AddAsyncTask([this, result, param]() {
669             bool isNeedUpdateComplete = E::IsNeedUpdateComplete(result, param);
670             INTELL_VOICE_LOG_INFO("isNeedUpdateComplete:%{public}d", isNeedUpdateComplete);
671             if (isNeedUpdateComplete && IntellVoiceUtil::IsFileExist(WHISPER_VPR_CONFIG_PATH)
672                 && param != "WhisperVprUpdate") {
673                 E::WhisperVprUpdate(true);
674                 return;
675             }
676 
677             if (isNeedUpdateComplete) {
678                 SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
679                 SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
680                 UnloadIntellVoiceService();
681             }
682         }, "IntellVoiceServiceManager::HandleUpdateComplete", false);
683 }
684 
685 template<typename T, typename E>
HandleUpdateRetry()686 void IntellVoiceServiceManager<T, E>::HandleUpdateRetry()
687 {
688     TaskExecutor::AddAsyncTask([this]() {
689         if (E::IsNeedUpdateRetry()) {
690             SwitchOnProc(VOICE_WAKEUP_MODEL_UUID, true);
691             SwitchOnProc(PROXIMAL_WAKEUP_MODEL_UUID, true);
692             UnloadIntellVoiceService();
693         }
694         }, "IntellVoiceServiceManager::HandleUpdateRetry", false);
695 }
696 
697 template<typename T, typename E>
OnDetected(int32_t uuid)698 void IntellVoiceServiceManager<T, E>::OnDetected(int32_t uuid)
699 {
700     TaskExecutor::AddAsyncTask([uuid, this]() {
701         if (!E::IsEngineExist(INTELL_VOICE_WAKEUP)) {
702             INTELL_VOICE_LOG_WARN("wakeup engine is nullptr");
703             HandleCloseWakeupSource(true);
704             return;
705         }
706         E::EngineOnDetected(uuid);
707         }, "IntellVoiceServiceManager::OnDetected", false);
708 }
709 
710 template<typename T, typename E>
OnServiceStart(std::map<int32_t,std::function<void (bool)>> & saChangeFuncMap)711 void IntellVoiceServiceManager<T, E>::OnServiceStart(std::map<int32_t, std::function<void(bool)>> &saChangeFuncMap)
712 {
713     saChangeFuncMap[TELEPHONY_STATE_REGISTRY_SYS_ABILITY_ID] = [this](bool isAdded) {
714         T::OnTelephonyStateRegistryServiceChange(isAdded);
715     };
716     saChangeFuncMap[AUDIO_DISTRIBUTED_SERVICE_ID] = [this](bool isAdded) {
717         T::OnAudioDistributedServiceChange(isAdded);
718     };
719     saChangeFuncMap[AUDIO_POLICY_SERVICE_ID] = [this](bool isAdded) {
720         T::OnAudioPolicyServiceChange(isAdded);
721     };
722 #ifdef POWER_MANAGER_ENABLE
723     saChangeFuncMap[POWER_MANAGER_SERVICE_ID] = [this](bool isAdded) {
724         T::OnPowerManagerServiceChange(isAdded);
725     };
726 #endif
727     saChangeFuncMap[DISPLAY_MANAGER_SERVICE_ID] = [this](bool isAdded) {
728         T::OnDisplayManagerServiceChange(isAdded);
729     };
730     T::OnServiceStart();
731     E::OnServiceStart();
732 }
733 
734 template<typename T, typename E>
OnServiceStop()735 void IntellVoiceServiceManager<T, E>::OnServiceStop()
736 {
737     T::OnServiceStop();
738     E::OnServiceStop();
739 }
740 
741 template<typename T, typename E>
TriggerGetParameter(const std::string & key)742 std::string IntellVoiceServiceManager<T, E>::TriggerGetParameter(const std::string &key)
743 {
744     return T::GetParameter(key);
745 }
746 
747 template<typename T, typename E>
TriggerSetParameter(const std::string & key,const std::string & value)748 int32_t IntellVoiceServiceManager<T, E>::TriggerSetParameter(const std::string &key, const std::string &value)
749 {
750     return T::SetParameter(key, value);
751 }
752 
753 template<typename T, typename E>
TriggerMgrUpdateModel(std::vector<uint8_t> buffer,int32_t uuid,TriggerModelType type)754 void IntellVoiceServiceManager<T, E>::TriggerMgrUpdateModel(std::vector<uint8_t> buffer, int32_t uuid,
755     TriggerModelType type)
756 {
757     T::UpdateModel(buffer, uuid, type);
758 }
759 
760 template<typename T, typename E>
RegisterProxyDeathRecipient(IntellVoiceEngineType type,const sptr<IRemoteObject> & object)761 bool IntellVoiceServiceManager<T, E>::RegisterProxyDeathRecipient(IntellVoiceEngineType type,
762     const sptr<IRemoteObject> &object)
763 {
764     return E::RegisterProxyDeathRecipient(type, object);
765 }
766 
767 template<typename T, typename E>
DeregisterProxyDeathRecipient(IntellVoiceEngineType type)768 bool IntellVoiceServiceManager<T, E>::DeregisterProxyDeathRecipient(IntellVoiceEngineType type)
769 {
770     return E::DeregisterProxyDeathRecipient(type);
771 }
772 
773 template<typename T, typename E>
GetUploadFiles(int numMax,std::vector<UploadFilesFromHdi> & files)774 int32_t IntellVoiceServiceManager<T, E>::GetUploadFiles(int numMax, std::vector<UploadFilesFromHdi> &files)
775 {
776     return E::GetUploadFiles(numMax, files);
777 }
778 
779 template<typename T, typename E>
EngineSetParameter(const std::string & keyValueList)780 int32_t IntellVoiceServiceManager<T, E>::EngineSetParameter(const std::string &keyValueList)
781 {
782     INTELL_VOICE_LOG_INFO("enter");
783     HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
784     std::map<std::string, std::string> kvpairs;
785     IntellVoiceUtil::SplitStringToKVPair(keyValueList, kvpairs);
786     for (auto it : kvpairs) {
787         if (it.first == std::string("Sensibility")) {
788             INTELL_VOICE_LOG_INFO("set Sensibility:%{public}s", it.second.c_str());
789             std::string sensibility = it.second;
790             historyInfoMgr.SetStringKVPair(KEY_SENSIBILITY, sensibility);
791             TaskExecutor::AddSyncTask([this, sensibility]() -> int32_t {
792                 E::SetDspSensibility(sensibility);
793                 return E::SetParameter(sensibility);
794             });
795         } else if (it.first == std::string("wakeup_bundle_name")) {
796             INTELL_VOICE_LOG_INFO("set wakeup bundle name:%{public}s", it.second.c_str());
797             historyInfoMgr.SetStringKVPair(KEY_WAKEUP_ENGINE_BUNDLE_NAME, it.second);
798         } else if (it.first == std::string("wakeup_ability_name")) {
799             INTELL_VOICE_LOG_INFO("set wakeup ability name:%{public}s", it.second.c_str());
800             historyInfoMgr.SetStringKVPair(KEY_WAKEUP_ENGINE_ABILITY_NAME, it.second);
801 #ifdef ONLY_FIRST_STAGE
802         } else if (it.first == std::string("record_start")) {
803 #ifndef FIRST_STAGE_ONESHOT_ENABLE
804             ResetSingleLevelWakeup(it.second);
805 #else
806             std::string keyValue = it.first;
807             keyValue.append("=").append(it.second);
808             E::SetParameter(keyValue);
809 #endif
810 #endif
811         } else {
812             INTELL_VOICE_LOG_INFO("no need to process, key:%{public}s", it.first.c_str());
813         }
814     }
815     return 0;
816 }
817 
818 template<typename T, typename E>
EngineGetParameter(const std::string & key)819 std::string IntellVoiceServiceManager<T, E>::EngineGetParameter(const std::string &key)
820 {
821     return E::GetParameter(key);
822 }
823 
824 template<typename T, typename E>
GetWakeupSourceFilesList(std::vector<std::string> & cloneFiles)825 int32_t IntellVoiceServiceManager<T, E>::GetWakeupSourceFilesList(std::vector<std::string>& cloneFiles)
826 {
827     return E::GetWakeupSourceFilesList(cloneFiles);
828 }
829 
830 template<typename T, typename E>
GetWakeupSourceFile(const std::string & filePath,std::vector<uint8_t> & buffer)831 int32_t IntellVoiceServiceManager<T, E>::GetWakeupSourceFile(const std::string &filePath,
832     std::vector<uint8_t> &buffer)
833 {
834     return E::GetWakeupSourceFile(filePath, buffer);
835 }
836 
837 template<typename T, typename E>
SendWakeupFile(const std::string & filePath,const std::vector<uint8_t> & buffer)838 int32_t IntellVoiceServiceManager<T, E>::SendWakeupFile(const std::string &filePath,
839     const std::vector<uint8_t> &buffer)
840 {
841     return E::SendWakeupFile(filePath, buffer);
842 }
843 
844 template<typename T, typename E>
SetScreenOff(bool value)845 void IntellVoiceServiceManager<T, E>::SetScreenOff(bool value)
846 {
847     return E::SetScreenOff(value);
848 }
849 
850 template<typename T, typename E>
OnSingleLevelDetected()851 void IntellVoiceServiceManager<T, E>::OnSingleLevelDetected()
852 {
853     INTELL_VOICE_LOG_INFO("single level detected");
854     recordStart_ = -1;
855     StopWakeupSource();
856     IntellVoiceUtil::StartAbility("single_level_event");
857     HandleRecordStartInfoChange();
858     return;
859 }
860 
861 template<typename T, typename E>
ProcSingleLevelModel()862 void IntellVoiceServiceManager<T, E>::ProcSingleLevelModel()
863 {
864 #ifdef ONLY_FIRST_STAGE
865     INTELL_VOICE_LOG_INFO("enter");
866     std::shared_ptr<uint8_t> buffer = nullptr;
867     uint32_t size = 0;
868     if (!IntellVoiceUtil::ReadFile(SINGLE_LEVEL_MODEL_PATH, buffer, size)) {
869         INTELL_VOICE_LOG_ERROR("read model failed!");
870         return;
871     }
872     std::vector<uint8_t> data(buffer.get(), buffer.get() + size);
873     T::UpdateModel(data, VOICE_WAKEUP_MODEL_UUID, TriggerModelType::VOICE_WAKEUP_TYPE);
874 #endif
875 }
876 
877 template<typename T, typename E>
ResetSingleLevelWakeup(const std::string & value)878 void IntellVoiceServiceManager<T, E>::ResetSingleLevelWakeup(const std::string &value)
879 {
880     INTELL_VOICE_LOG_INFO("record_start:%{public}s", value.c_str());
881     if (value != std::string("true") && value != std::string("false")) {
882         return;
883     }
884 
885     recordStart_ = (value == std::string("true")) ? 1 : 0;
886     NoiftyRecordStartInfoChange();
887     if (recordStart_ == 0) {
888         HandleCloseWakeupSource(true);
889     }
890 }
891 
892 template<typename T, typename E>
HasReceviedRecordStartMsg()893 bool IntellVoiceServiceManager<T, E>::HasReceviedRecordStartMsg()
894 {
895     return (recordStart_ == 1 || recordStart_ == 0);
896 }
897 
898 template<typename T, typename E>
NoiftyRecordStartInfoChange()899 void IntellVoiceServiceManager<T, E>::NoiftyRecordStartInfoChange()
900 {
901     {
902         std::unique_lock<std::mutex> lock(recordStartInfoChangeMutex_);
903         if (!notifyRecordStartInfoChange_) {
904             INTELL_VOICE_LOG_INFO("no need to notify");
905             return;
906         }
907     }
908 
909     recordStartInfoChangeCv_.notify_all();
910 }
911 
912 template<typename T, typename E>
HandleRecordStartInfoChange()913 void IntellVoiceServiceManager<T, E>::HandleRecordStartInfoChange()
914 {
915     if (HasReceviedRecordStartMsg()) {
916         INTELL_VOICE_LOG_INFO("record start info has received, no need to process");
917         return;
918     }
919 
920     std::thread([&]() {
921         std::unique_lock<std::mutex> lock(recordStartInfoChangeMutex_);
922         if (HasReceviedRecordStartMsg()) {
923             INTELL_VOICE_LOG_INFO("record start info has received, no need to process");
924             return;
925         }
926         notifyRecordStartInfoChange_ = true;
927         if (recordStartInfoChangeCv_.wait_for(lock, std::chrono::milliseconds(WAIT_RECORD_START_TIME),
928             [this] { return HasReceviedRecordStartMsg(); })) {
929             INTELL_VOICE_LOG_INFO("record start info has received, do nothing");
930             notifyRecordStartInfoChange_ = false;
931             return;
932         }
933         INTELL_VOICE_LOG_WARN("wait time out, need to reset wakeup");
934         notifyRecordStartInfoChange_ = false;
935         HandleCloseWakeupSource(true);
936     }).detach();
937 }
938 
939 template class IntellVoiceServiceManager<TriggerManagerType, EngineManagerType>;
940 }  // namespace IntellVoiceEngine
941 } // namespace OHOS