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