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