• 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 "trigger_helper.h"
16 
17 #include <chrono>
18 #include <thread>
19 #ifdef SUPPORT_TELEPHONY_SERVICE
20 #include "telephony_observer_client.h"
21 #include "state_registry_errors.h"
22 #include "telephony_types.h"
23 #include "call_manager_inner_type.h"
24 #endif
25 #include "audio_policy_manager.h"
26 
27 #include "intell_voice_log.h"
28 #include "trigger_connector_mgr.h"
29 
30 #ifdef SUPPORT_WINDOW_MANAGER
31 #include "intell_voice_util.h"
32 #include "intell_voice_definitions.h"
33 #include "trigger_db_helper.h"
34 #endif
35 
36 #undef LOG_TAG
37 #define LOG_TAG "TriggerHelper"
38 
39 using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0;
40 using namespace OHOS::AudioStandard;
41 #ifdef SUPPORT_TELEPHONY_SERVICE
42 using namespace OHOS::Telephony;
43 #endif
44 #ifdef SUPPORT_WINDOW_MANAGER
45 using namespace OHOS::IntellVoiceUtils;
46 using namespace OHOS::IntellVoiceEngine;
47 #endif
48 using namespace OHOS::AudioStandard;
49 #ifdef POWER_MANAGER_ENABLE
50 using namespace OHOS::PowerMgr;
51 #endif
52 using namespace std;
53 
54 namespace OHOS {
55 namespace IntellVoiceTrigger {
56 #ifdef SUPPORT_TELEPHONY_SERVICE
57 static constexpr int32_t SIM_SLOT_ID_1 = DEFAULT_SIM_SLOT_ID + 1;
58 #endif
59 static constexpr uint32_t HIBERNATE_WAIT_TIME = 500; // 500ms
60 
TriggerModelData(int32_t uuid)61 TriggerModelData::TriggerModelData(int32_t uuid)
62 {
63     uuid_ = uuid;
64 }
65 
~TriggerModelData()66 TriggerModelData::~TriggerModelData()
67 {
68 }
69 
SetCallback(std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)70 void TriggerModelData::SetCallback(std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
71 {
72     if (callback == nullptr) {
73         INTELL_VOICE_LOG_ERROR("callback is nullptr");
74         return;
75     }
76     callback_ = callback;
77 }
78 
GetCallback()79 std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> TriggerModelData::GetCallback()
80 {
81     return callback_;
82 }
83 
SetModel(std::shared_ptr<GenericTriggerModel> model)84 void TriggerModelData::SetModel(std::shared_ptr<GenericTriggerModel> model)
85 {
86     if (SameModel(model)) {
87         INTELL_VOICE_LOG_INFO("same model not need to update");
88         return;
89     }
90     model_ = model;
91     model_->Print();
92 }
93 
GetModel()94 shared_ptr<GenericTriggerModel> TriggerModelData::GetModel()
95 {
96     return model_;
97 }
98 
SameModel(std::shared_ptr<GenericTriggerModel> model)99 bool TriggerModelData::SameModel(std::shared_ptr<GenericTriggerModel> model)
100 {
101     if (model == nullptr || model_ == nullptr) {
102         return false;
103     }
104     return model_->GetData() == model->GetData();
105 }
106 
SetState(ModelState state)107 void TriggerModelData::SetState(ModelState state)
108 {
109     state_ = state;
110 }
111 
GetState() const112 ModelState TriggerModelData::GetState() const
113 {
114     return state_;
115 }
116 
SetModelHandle(int32_t handle)117 void TriggerModelData::SetModelHandle(int32_t handle)
118 {
119     modelHandle_ = handle;
120 }
121 
GetModelHandle() const122 int32_t TriggerModelData::GetModelHandle() const
123 {
124     return modelHandle_;
125 }
126 
SetRequested(bool requested)127 void TriggerModelData::SetRequested(bool requested)
128 {
129     requested_ = requested;
130 }
131 
GetRequested() const132 bool TriggerModelData::GetRequested() const
133 {
134     return requested_;
135 }
136 
Clear()137 void TriggerModelData::Clear()
138 {
139     callback_ = nullptr;
140     state_ = MODEL_NOTLOADED;
141 }
142 
ClearCallback()143 void TriggerModelData::ClearCallback()
144 {
145     callback_ = nullptr;
146 }
147 
TriggerHelper()148 TriggerHelper::TriggerHelper()
149 {
150 }
151 
~TriggerHelper()152 TriggerHelper::~TriggerHelper()
153 {
154     modelDataMap_.clear();
155 }
156 
Create()157 std::shared_ptr<TriggerHelper> TriggerHelper::Create()
158 {
159     return std::shared_ptr<TriggerHelper>(new (std::nothrow) TriggerHelper());
160 }
161 
StartGenericRecognition(int32_t uuid,std::shared_ptr<GenericTriggerModel> model,shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)162 int32_t TriggerHelper::StartGenericRecognition(int32_t uuid, std::shared_ptr<GenericTriggerModel> model,
163     shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
164 {
165     INTELL_VOICE_LOG_INFO("enter");
166     lock_guard<std::mutex> lock(mutex_);
167 
168     auto modelData = GetTriggerModelData(uuid);
169     if (modelData == nullptr) {
170         modelData = CreateTriggerModelData((uuid));
171         if (modelData == nullptr) {
172             INTELL_VOICE_LOG_ERROR("failed to create trigger model data");
173             return -1;
174         }
175     }
176 
177     bool unload = !modelData->SameModel(model);
178     int32_t ret = InitRecognition(modelData, unload);
179     if (ret != 0) {
180         INTELL_VOICE_LOG_ERROR("failed to initialize recognition");
181         return -1;
182     }
183 
184     modelData->SetModel(model);
185     modelData->SetCallback(callback);
186     modelData->SetRequested(true);
187 
188     if (IsConflictSceneActive()) {
189         INTELL_VOICE_LOG_INFO("conflict state, no need to start");
190         return 0;
191     }
192 
193     ret = PrepareForRecognition(modelData);
194     if (ret != 0) {
195         return ret;
196     }
197 
198     return StartRecognition(modelData);
199 }
200 
StopGenericRecognition(int32_t uuid,shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)201 int32_t TriggerHelper::StopGenericRecognition(int32_t uuid, shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
202 {
203     INTELL_VOICE_LOG_INFO("enter");
204     lock_guard<std::mutex> lock(mutex_);
205     auto modelData = GetTriggerModelData(uuid);
206     if (modelData == nullptr) {
207         INTELL_VOICE_LOG_ERROR("failed to get trigger model data");
208         return -1;
209     }
210     modelData->SetRequested(false);
211     int32_t ret = StopRecognition(modelData);
212     if (ret != 0) {
213         return ret;
214     }
215     modelData->ClearCallback();
216     return ret;
217 }
218 
UnloadGenericTriggerModel(int32_t uuid)219 void TriggerHelper::UnloadGenericTriggerModel(int32_t uuid)
220 {
221     INTELL_VOICE_LOG_INFO("enter");
222     lock_guard<std::mutex> lock(mutex_);
223     auto modelData = GetTriggerModelData(uuid);
224     if (modelData == nullptr) {
225         INTELL_VOICE_LOG_WARN("no trigger model data");
226         return;
227     }
228 
229     if (modelData->GetState() == MODEL_NOTLOADED) {
230         INTELL_VOICE_LOG_INFO("model is not loaded");
231         return;
232     }
233     StopRecognition(modelData);
234     UnloadModel(modelData);
235     modelDataMap_.erase(uuid);
236 }
237 
SetParameter(const std::string & key,const std::string & value)238 int32_t TriggerHelper::SetParameter(const std::string &key, const std::string &value)
239 {
240     INTELL_VOICE_LOG_INFO("enter");
241     lock_guard<std::mutex> lock(mutex_);
242     if (!GetModule()) {
243         return -1;
244     }
245 
246     return module_->SetParams(key, value);
247 }
248 
GetParameter(const std::string & key)249 std::string TriggerHelper::GetParameter(const std::string &key)
250 {
251     INTELL_VOICE_LOG_INFO("enter");
252     lock_guard<std::mutex> lock(mutex_);
253     if (!GetModule()) {
254         return "";
255     }
256 
257     std::string value;
258 #ifdef SUPPORT_WINDOW_MANAGER
259     if (GetParameterInner(key, value)) {
260         return value;
261     }
262 #endif
263 
264     auto ret = module_->GetParams(key, value);
265     if (ret != 0) {
266         INTELL_VOICE_LOG_ERROR("failed to get parameter");
267         return "";
268     }
269 
270     return value;
271 }
272 
GetModule()273 bool TriggerHelper::GetModule()
274 {
275     if (module_ != nullptr) {
276         return true;
277     }
278     const auto &connectMgr = TriggerConnectorMgr::GetInstance();
279     if (connectMgr == nullptr) {
280         INTELL_VOICE_LOG_ERROR("connectMgr is nullptr");
281         return false;
282     }
283     moduleDesc_ = connectMgr->ListConnectorModuleDescriptors();
284     if (moduleDesc_.size() == 0) {
285         INTELL_VOICE_LOG_ERROR("moduleDesc_ is empty");
286         return false;
287     }
288 
289     module_ = connectMgr->GetConnectorModule(moduleDesc_[0].adapterName, shared_from_this());
290     if (module_ == nullptr) {
291         INTELL_VOICE_LOG_ERROR("failed to get connector module");
292         return false;
293     }
294     return true;
295 }
296 
InitRecognition(std::shared_ptr<TriggerModelData> modelData,bool unload)297 int32_t TriggerHelper::InitRecognition(std::shared_ptr<TriggerModelData> modelData, bool unload)
298 {
299     INTELL_VOICE_LOG_INFO("enter");
300     if (modelData->GetState() == MODEL_NOTLOADED) {
301         return 0;
302     }
303     int32_t ret = StopRecognition(modelData);
304     if (unload) {
305         ret = UnloadModel(modelData);
306         modelData->Clear();
307     }
308 
309     return ret;
310 }
311 
PrepareForRecognition(std::shared_ptr<TriggerModelData> modelData)312 int32_t TriggerHelper::PrepareForRecognition(std::shared_ptr<TriggerModelData> modelData)
313 {
314     INTELL_VOICE_LOG_INFO("enter");
315     if (!GetModule()) {
316         return -1;
317     }
318 
319     if (LoadModel(modelData) != 0) {
320         return -1;
321     }
322     return 0;
323 }
324 
StartRecognition(shared_ptr<TriggerModelData> modelData)325 int32_t TriggerHelper::StartRecognition(shared_ptr<TriggerModelData> modelData)
326 {
327     if (modelData == nullptr) {
328         INTELL_VOICE_LOG_ERROR("modelData is nullptr");
329         return -1;
330     }
331     if (modelData->GetState() != MODEL_LOADED) {
332         return 0;
333     }
334     INTELL_VOICE_LOG_INFO("enter");
335     if (module_ == nullptr) {
336         INTELL_VOICE_LOG_ERROR("module_ is nullptr");
337         return -1;
338     }
339 
340 #ifdef SUPPORT_WINDOW_MANAGER
341     FoldStatusOperation(modelData);
342 #endif
343 
344     auto ret = module_->Start(modelData->GetModelHandle());
345     if (ret != 0) {
346         INTELL_VOICE_LOG_ERROR("failed to start recognition");
347         return ret;
348     }
349     modelData->SetState(MODEL_STARTED);
350     return ret;
351 }
352 
StopRecognition(shared_ptr<TriggerModelData> modelData)353 int32_t TriggerHelper::StopRecognition(shared_ptr<TriggerModelData> modelData)
354 {
355     if (modelData == nullptr) {
356         INTELL_VOICE_LOG_ERROR("modelData is nullptr");
357         return -1;
358     }
359     if (modelData->GetState() != MODEL_STARTED) {
360         return 0;
361     }
362     INTELL_VOICE_LOG_INFO("enter");
363     if (module_ == nullptr) {
364         INTELL_VOICE_LOG_ERROR("module_ is nullptr");
365         return -1;
366     }
367     auto ret = module_->Stop(modelData->GetModelHandle());
368     if (ret != 0) {
369         INTELL_VOICE_LOG_ERROR("failed to stop");
370         return ret;
371     }
372 
373     modelData->SetState(MODEL_LOADED);
374     return ret;
375 }
376 
LoadModel(shared_ptr<TriggerModelData> modelData)377 int32_t TriggerHelper::LoadModel(shared_ptr<TriggerModelData> modelData)
378 {
379     INTELL_VOICE_LOG_INFO("enter");
380     if (modelData == nullptr) {
381         INTELL_VOICE_LOG_ERROR("modelData is nullptr");
382         return -1;
383     }
384     if (modelData->GetState() != MODEL_NOTLOADED) {
385         INTELL_VOICE_LOG_WARN("model is already loaded");
386         return 0;
387     }
388 
389     if (module_ == nullptr) {
390         INTELL_VOICE_LOG_ERROR("module_ is nullptr");
391         return -1;
392     }
393 
394     int32_t handle;
395     auto ret = module_->LoadModel(modelData->GetModel(), handle);
396     if (ret != 0) {
397         INTELL_VOICE_LOG_WARN("failed to load model, ret: %{public}d", ret);
398         return ret;
399     }
400     modelData->SetModelHandle(handle);
401     modelData->SetState(MODEL_LOADED);
402     INTELL_VOICE_LOG_INFO("exit, handle: %{public}d", handle);
403     return ret;
404 }
405 
UnloadModel(shared_ptr<TriggerModelData> modelData)406 int32_t TriggerHelper::UnloadModel(shared_ptr<TriggerModelData> modelData)
407 {
408     if (modelData == nullptr) {
409         INTELL_VOICE_LOG_ERROR("modelData is nullptr");
410         return -1;
411     }
412     if (modelData->GetState() != MODEL_LOADED) {
413         return 0;
414     }
415     INTELL_VOICE_LOG_INFO("enter");
416     if (module_ == nullptr) {
417         INTELL_VOICE_LOG_ERROR("module_ is nullptr");
418         return -1;
419     }
420     auto ret = module_->UnloadModel(modelData->GetModelHandle());
421     modelData->SetState(MODEL_NOTLOADED);
422     return ret;
423 }
424 
GetTriggerModelData(int32_t uuid)425 shared_ptr<TriggerModelData> TriggerHelper::GetTriggerModelData(int32_t uuid)
426 {
427     INTELL_VOICE_LOG_INFO("enter, uuid is :%{public}d", uuid);
428     auto it = modelDataMap_.find(uuid);
429     if ((it == modelDataMap_.end()) || (it->second == nullptr)) {
430         return nullptr;
431     }
432 
433     return it->second;
434 }
435 
CreateTriggerModelData(int32_t uuid)436 shared_ptr<TriggerModelData> TriggerHelper::CreateTriggerModelData(int32_t uuid)
437 {
438     INTELL_VOICE_LOG_INFO("enter, uuid is :%{public}d", uuid);
439     auto modelData = std::make_shared<TriggerModelData>(uuid);
440     if (modelData == nullptr) {
441         INTELL_VOICE_LOG_INFO("modelData is nullptr");
442         return nullptr;
443     }
444     modelDataMap_.insert(std::make_pair(uuid, modelData));
445     return modelData;
446 }
447 
OnRecognition(int32_t modelHandle,const IntellVoiceRecognitionEvent & event)448 void TriggerHelper::OnRecognition(int32_t modelHandle, const IntellVoiceRecognitionEvent &event)
449 {
450     INTELL_VOICE_LOG_INFO("enter, modelHandle:%{public}d", modelHandle);
451     lock_guard<std::mutex> lock(mutex_);
452     std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback = nullptr;
453     for (auto iter : modelDataMap_) {
454         if (iter.second == nullptr) {
455             INTELL_VOICE_LOG_ERROR("uuid: %{public}d, model data is nullptr", iter.first);
456             continue;
457         }
458 
459         if (iter.second->GetModelHandle() == modelHandle) {
460             iter.second->SetState(MODEL_LOADED);
461             callback = iter.second->GetCallback();
462             break;
463         }
464     }
465 
466     if (callback == nullptr) {
467         INTELL_VOICE_LOG_ERROR("trigger recognition callback is nullptr, modelHandle: %{public}d", modelHandle);
468         return;
469     }
470 
471     auto genericEvent = std::make_shared<GenericTriggerEvent>();
472     if (genericEvent == nullptr) {
473         INTELL_VOICE_LOG_ERROR("genericEvent is nullptr");
474         return;
475     }
476     genericEvent->modelHandle_ = modelHandle;
477     callback->OnGenericTriggerDetected(genericEvent);
478 }
479 
IsConflictSceneActive()480 bool TriggerHelper::IsConflictSceneActive()
481 {
482     INTELL_VOICE_LOG_INFO("callActive: %{public}d, audioCaptureActive: %{public}d, systemHibernate: %{public}d",
483         callActive_, audioCaptureActive_, systemHibernate_);
484     return (callActive_ || audioCaptureActive_ || systemHibernate_ || (audioScene_ != AUDIO_SCENE_DEFAULT));
485 }
486 
OnUpdateAllRecognitionState()487 void TriggerHelper::OnUpdateAllRecognitionState()
488 {
489     for (auto iter : modelDataMap_) {
490         if (iter.second == nullptr) {
491             INTELL_VOICE_LOG_ERROR("uuid: %{public}d, model data is nullptr", iter.first);
492             continue;
493         }
494         bool needStart =
495             (iter.second->GetRequested() && (!IsConflictSceneActive()));
496         if (needStart == (iter.second->GetState() == MODEL_STARTED)) {
497             INTELL_VOICE_LOG_INFO("no operation, needStart:%{public}d", needStart);
498             continue;
499         }
500         if (needStart) {
501             if (PrepareForRecognition(iter.second) != 0) {
502                 return;
503             }
504             StartRecognition(iter.second);
505         } else {
506             StopRecognition(iter.second);
507             if (systemHibernate_) {
508                 UnloadModel(iter.second);
509                 INTELL_VOICE_LOG_INFO("begin to wait");
510                 std::this_thread::sleep_for(std::chrono::milliseconds(HIBERNATE_WAIT_TIME));
511                 INTELL_VOICE_LOG_INFO("finish to wait");
512             }
513         }
514     }
515 }
516 
517 #ifdef SUPPORT_TELEPHONY_SERVICE
AttachTelephonyObserver()518 void TriggerHelper::AttachTelephonyObserver()
519 {
520     INTELL_VOICE_LOG_INFO("enter");
521     std::lock_guard<std::mutex> lock(telephonyMutex_);
522     if (isTelephonyDetached_) {
523         INTELL_VOICE_LOG_INFO("telephony is already detached");
524         return;
525     }
526     telephonyObserver0_ = std::make_unique<TelephonyStateObserver>(shared_from_this()).release();
527     if (telephonyObserver0_ == nullptr) {
528         INTELL_VOICE_LOG_ERROR("telephonyObserver0_ is nullptr");
529         return;
530     }
531     auto res = TelephonyObserverClient::GetInstance().AddStateObserver(
532         telephonyObserver0_, -1, TelephonyObserverBroker::OBSERVER_MASK_CALL_STATE, true);
533     if (res != TELEPHONY_SUCCESS) {
534         INTELL_VOICE_LOG_ERROR("telephonyObserver0_ add failed");
535     }
536 }
537 
DetachTelephonyObserver()538 void TriggerHelper::DetachTelephonyObserver()
539 {
540     INTELL_VOICE_LOG_INFO("enter");
541     std::lock_guard<std::mutex> lock(telephonyMutex_);
542     isTelephonyDetached_ = true;
543 
544     if (telephonyObserver0_ != nullptr) {
545         Telephony::TelephonyObserverClient::GetInstance().RemoveStateObserver(
546             -1, Telephony::TelephonyObserverBroker::OBSERVER_MASK_CALL_STATE);
547         telephonyObserver0_ = nullptr;
548     }
549 }
550 
OnCallStateUpdated(int32_t callState)551 void TriggerHelper::OnCallStateUpdated(int32_t callState)
552 {
553     lock_guard<std::mutex> lock(mutex_);
554     if (callState < static_cast<int32_t>(TelCallState::CALL_STATUS_UNKNOWN) ||
555         callState > static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE)) {
556         INTELL_VOICE_LOG_ERROR("callstate err: %{public}d", callState);
557         return;
558     }
559 
560     bool curCallActive = (callState != static_cast<int32_t>(TelCallState::CALL_STATUS_DISCONNECTED) &&
561           callState != static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE) &&
562           callState != static_cast<int32_t>(TelCallState::CALL_STATUS_UNKNOWN));
563     INTELL_VOICE_LOG_INFO("state: %{public}d, callActive: %{public}d, curCallActive: %{public}d",
564         callState,
565         callActive_,
566         curCallActive);
567     if (callActive_ == curCallActive) {
568         return;
569     }
570 
571     callActive_ = curCallActive;
572     OnUpdateAllRecognitionState();
573 }
574 
OnCallStateUpdated(int32_t slotId,int32_t callState,const std::u16string & phoneNumber)575 void TriggerHelper::TelephonyStateObserver::OnCallStateUpdated(
576     int32_t slotId, int32_t callState, const std::u16string &phoneNumber)
577 {
578     if (helper_ == nullptr) {
579         INTELL_VOICE_LOG_ERROR("helper is nullptr");
580         return;
581     }
582 
583     helper_->OnCallStateUpdated(callState);
584 }
585 #endif
586 
AttachAudioCaptureListener()587 void TriggerHelper::AttachAudioCaptureListener()
588 {
589     INTELL_VOICE_LOG_INFO("enter");
590 
591     audioCapturerSourceChangeCallback_ = std::make_shared<AudioCapturerSourceChangeCallback>(shared_from_this());
592     auto audioSystemManager = AudioSystemManager::GetInstance();
593     if (audioSystemManager != nullptr) {
594         audioSystemManager->SetAudioCapturerSourceCallback(audioCapturerSourceChangeCallback_);
595     } else {
596         INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
597     }
598 }
599 
DetachAudioCaptureListener()600 void TriggerHelper::DetachAudioCaptureListener()
601 {
602     INTELL_VOICE_LOG_INFO("enter");
603 
604     auto audioSystemManager = AudioSystemManager::GetInstance();
605     if (audioSystemManager != nullptr) {
606         audioSystemManager->SetAudioCapturerSourceCallback(nullptr);
607     } else {
608         INTELL_VOICE_LOG_ERROR("audioSystemManager is null");
609     }
610 }
611 
OnAudioSceneChange(const AudioScene audioScene)612 void TriggerHelper::OnAudioSceneChange(const AudioScene audioScene)
613 {
614     lock_guard<std::mutex> lock(mutex_);
615     if (audioScene_ == audioScene) {
616         return;
617     }
618 
619     audioScene_ = audioScene;
620     OnUpdateAllRecognitionState();
621 }
622 
OnAudioSceneChange(const AudioScene audioScene)623 void TriggerHelper::AudioSceneChangeCallback::OnAudioSceneChange(const AudioScene audioScene)
624 {
625     INTELL_VOICE_LOG_INFO("OnAudioScene change scene: %{public}d", audioScene);
626 
627     if (helper_ == nullptr) {
628         INTELL_VOICE_LOG_ERROR("helper is nullptr");
629         return;
630     }
631 
632     helper_->OnAudioSceneChange(audioScene);
633 }
634 
OnCapturerStateChange(bool isActive)635 void TriggerHelper::OnCapturerStateChange(bool isActive)
636 {
637     lock_guard<std::mutex> lock(mutex_);
638     if (audioCaptureActive_ == isActive) {
639         return;
640     }
641 
642     audioCaptureActive_ = isActive;
643     OnUpdateAllRecognitionState();
644 }
645 
OnCapturerState(bool isActive)646 void TriggerHelper::AudioCapturerSourceChangeCallback::OnCapturerState(bool isActive)
647 {
648     INTELL_VOICE_LOG_INFO("OnCapturerState active: %{public}d", isActive);
649 
650     if (helper_ == nullptr) {
651         INTELL_VOICE_LOG_ERROR("helper is nullptr");
652         return;
653     }
654 
655     helper_->OnCapturerStateChange(isActive);
656 }
657 
OnRendererStateChange(const std::vector<std::shared_ptr<AudioStandard::AudioRendererChangeInfo>> & audioRendererChangeInfos)658 void TriggerHelper::AudioRendererStateChangeCallbackImpl::OnRendererStateChange(
659     const std::vector<std::shared_ptr<AudioStandard::AudioRendererChangeInfo>> &audioRendererChangeInfos)
660 {
661     std::lock_guard<std::mutex> lock(mutex_);
662     if (helper_ == nullptr) {
663         INTELL_VOICE_LOG_ERROR("helper is nullptr");
664         return;
665     }
666     std::map<int32_t, bool> stateMap;
667     for (const auto &info : audioRendererChangeInfos) {
668         if (info == nullptr) {
669             INTELL_VOICE_LOG_ERROR("info is nullptr");
670             continue;
671         }
672         bool isPlaying = false;
673         if (info->rendererState == AudioStandard::RENDERER_RUNNING) {
674             isPlaying = true;
675         }
676 
677         if (stateMap.count(info->rendererInfo.streamUsage) == 0 || !stateMap[info->rendererInfo.streamUsage]) {
678             stateMap[info->rendererInfo.streamUsage] = isPlaying;
679         }
680     }
681 
682     for (auto iter : stateMap) {
683         std::string key = iter.second ? "start_stream" : "stop_stream";
684         if (rendererStateMap_.count(iter.first) == 0) {
685             rendererStateMap_[iter.first] = iter.second;
686             INTELL_VOICE_LOG_INFO("first change, usage:%{public}d, isPlaying:%{public}d",
687                 iter.first, iter.second);
688             helper_->SetParameter(key, std::to_string(iter.first));
689         } else {
690             if (rendererStateMap_[iter.first] != iter.second) {
691                 INTELL_VOICE_LOG_INFO("state change, usage:%{public}d, isPlaying:%{public}d",
692                     iter.first, iter.second);
693                 rendererStateMap_[iter.first] = iter.second;
694                 helper_->SetParameter(key, std::to_string(iter.first));
695             }
696         }
697     }
698 }
699 
700 #ifdef POWER_MANAGER_ENABLE
AttachHibernateObserver()701 void TriggerHelper::AttachHibernateObserver()
702 {
703     INTELL_VOICE_LOG_INFO("enter");
704     std::lock_guard<std::mutex> lock(hiberateMutex_);
705     if (isHibernateDetached_) {
706         INTELL_VOICE_LOG_INFO("system hibernate is already detached");
707         return;
708     }
709 
710     hibernateCallback_ = std::make_unique<HibernateCallback>(shared_from_this()).release();
711     if (hibernateCallback_ == nullptr) {
712         INTELL_VOICE_LOG_ERROR("hibernateCallback_ is nullptr");
713         return;
714     }
715     auto res =  PowerMgrClient::GetInstance().RegisterSyncHibernateCallback(hibernateCallback_);
716     if (!res) {
717         INTELL_VOICE_LOG_ERROR("hibernateCallback_ register failed");
718     }
719 
720     sleepCallback_ = std::make_unique<SleepCallback>(shared_from_this()).release();
721     if (sleepCallback_ == nullptr) {
722         INTELL_VOICE_LOG_ERROR("sleepCallback_ is nullptr");
723         return;
724     }
725     res =  PowerMgrClient::GetInstance().RegisterSyncSleepCallback(sleepCallback_, SleepPriority::DEFAULT);
726     if (!res) {
727         INTELL_VOICE_LOG_ERROR("sleepCallback_ register failed");
728     }
729 }
730 
DetachHibernateObserver()731 void TriggerHelper::DetachHibernateObserver()
732 {
733     INTELL_VOICE_LOG_INFO("enter");
734     std::lock_guard<std::mutex> lock(hiberateMutex_);
735 
736     isHibernateDetached_ = true;
737     if (hibernateCallback_ == nullptr) {
738         INTELL_VOICE_LOG_ERROR("hibernateCallback_ is nullptr");
739         return;
740     }
741     auto res =  PowerMgrClient::GetInstance().UnRegisterSyncHibernateCallback(hibernateCallback_);
742     if (!res) {
743         INTELL_VOICE_LOG_ERROR("hibernateCallback_ unregister failed");
744     }
745 
746     if (sleepCallback_ == nullptr) {
747         INTELL_VOICE_LOG_ERROR("sleepCallback_ is nullptr");
748         return;
749     }
750     res =  PowerMgrClient::GetInstance().UnRegisterSyncSleepCallback(sleepCallback_);
751     if (!res) {
752         INTELL_VOICE_LOG_ERROR("sleepCallback_ unregister failed");
753     }
754 }
755 
756 
OnSyncHibernate()757 void TriggerHelper::HibernateCallback::OnSyncHibernate()
758 {
759     if (helper_ == nullptr) {
760         INTELL_VOICE_LOG_ERROR("helper is nullptr");
761         return;
762     }
763 
764     helper_->OnHibernateStateUpdated(true);
765 }
766 
OnSyncWakeup(bool)767 void TriggerHelper::HibernateCallback::OnSyncWakeup(bool /* hibernateResult */)
768 {
769     if (helper_ == nullptr) {
770         INTELL_VOICE_LOG_ERROR("helper is nullptr");
771         return;
772     }
773 
774     helper_->OnHibernateStateUpdated(false);
775 }
776 
OnSyncSleep(bool onForceSleep)777 void TriggerHelper::SleepCallback::OnSyncSleep(bool onForceSleep)
778 {
779     if (!onForceSleep) {
780         INTELL_VOICE_LOG_INFO("not onForceSleep");
781         return;
782     }
783 
784     if (helper_ == nullptr) {
785         INTELL_VOICE_LOG_ERROR("helper is nullptr");
786         return;
787     }
788 
789     helper_->OnHibernateStateUpdated(true);
790 }
791 
OnSyncWakeup(bool onForceSleep)792 void TriggerHelper::SleepCallback::OnSyncWakeup(bool onForceSleep)
793 {
794     if (!onForceSleep) {
795         INTELL_VOICE_LOG_INFO("not onForceSleep");
796         return;
797     }
798 
799     if (helper_ == nullptr) {
800         INTELL_VOICE_LOG_ERROR("helper is nullptr");
801         return;
802     }
803 
804     helper_->OnHibernateStateUpdated(false);
805 }
806 
OnHibernateStateUpdated(bool isHibernate)807 void TriggerHelper::OnHibernateStateUpdated(bool isHibernate)
808 {
809     lock_guard<std::mutex> lock(mutex_);
810     if (systemHibernate_ == isHibernate) {
811         return;
812     }
813     systemHibernate_ = isHibernate;
814     OnUpdateAllRecognitionState();
815 }
816 #endif
817 
AttachAudioRendererEventListener()818 void TriggerHelper::AttachAudioRendererEventListener()
819 {
820     INTELL_VOICE_LOG_INFO("enter");
821     std::lock_guard<std::mutex> lock(rendererMutex_);
822     if (isRendererDetached_) {
823         INTELL_VOICE_LOG_INFO("renderer event listener is already detached");
824         return;
825     }
826     audioRendererStateChangeCallback_ = std::make_shared<AudioRendererStateChangeCallbackImpl>(shared_from_this());
827     if (audioRendererStateChangeCallback_ == nullptr) {
828         INTELL_VOICE_LOG_ERROR("Memory Allocation Failed !!");
829         return;
830     }
831 
832     auto audioStreamManager = AudioStreamManager::GetInstance();
833     if (audioStreamManager == nullptr) {
834         INTELL_VOICE_LOG_ERROR("audioStreamManager is nullptr");
835         return;
836     }
837     int32_t ret = audioStreamManager->RegisterAudioRendererEventListener(getpid(),
838         audioRendererStateChangeCallback_);
839     if (ret != 0) {
840         INTELL_VOICE_LOG_ERROR("RegisterAudioRendererEventListener failed");
841         return;
842     }
843     INTELL_VOICE_LOG_INFO("RegisterAudioRendererEventListener success");
844 
845     std::vector<std::shared_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
846     audioStreamManager->GetCurrentRendererChangeInfos(audioRendererChangeInfos);
847     audioRendererStateChangeCallback_->OnRendererStateChange(audioRendererChangeInfos);
848 }
849 
AttachAudioSceneEventListener()850 void TriggerHelper::AttachAudioSceneEventListener()
851 {
852     INTELL_VOICE_LOG_INFO("enter");
853     std::lock_guard<std::mutex> lock(sceneMutex_);
854     if (isSceneDetached_) {
855         INTELL_VOICE_LOG_INFO("csene event listener is already detached");
856         return;
857     }
858     audioSceneChangeCallback_ = std::make_shared<AudioSceneChangeCallback>(shared_from_this());
859     if (audioSceneChangeCallback_ == nullptr) {
860         INTELL_VOICE_LOG_ERROR("Memory Allocation Failed !!");
861         return;
862     }
863 
864     auto audioSystemManager = AudioSystemManager::GetInstance();
865     if (audioSystemManager == nullptr) {
866         INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
867         return;
868     }
869     int32_t ret = audioSystemManager->SetAudioSceneChangeCallback(audioSceneChangeCallback_);
870     if (ret != 0) {
871         INTELL_VOICE_LOG_ERROR("RegisterAudioSceneListener failed");
872         return;
873     }
874     INTELL_VOICE_LOG_INFO("RegisterAudioSceneListener success");
875     AudioScene audioScene = audioSystemManager->GetAudioScene();
876     audioSceneChangeCallback_->OnAudioSceneChange(audioScene);
877 }
878 
DetachAudioSceneEventListener()879 void TriggerHelper::DetachAudioSceneEventListener()
880 {
881     INTELL_VOICE_LOG_INFO("enter");
882     std::lock_guard<std::mutex> lock(sceneMutex_);
883     isSceneDetached_ = true;
884 
885     auto audioSystemManager = AudioSystemManager::GetInstance();
886     if (audioSystemManager == nullptr) {
887         INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
888         return;
889     }
890     int32_t ret = audioSystemManager->UnsetAudioSceneChangeCallback(audioSceneChangeCallback_);
891     if (ret != 0) {
892         INTELL_VOICE_LOG_ERROR("UnregisterAudioRendererEventListener failed");
893     }
894 }
895 
DetachAudioRendererEventListener()896 void TriggerHelper::DetachAudioRendererEventListener()
897 {
898     INTELL_VOICE_LOG_INFO("enter");
899     std::lock_guard<std::mutex> lock(rendererMutex_);
900     isRendererDetached_ = true;
901     auto audioStreamManager = AudioStreamManager::GetInstance();
902     if (audioStreamManager == nullptr) {
903         INTELL_VOICE_LOG_ERROR("audioStreamManager is nullptr");
904         return;
905     }
906     int32_t ret = audioStreamManager->UnregisterAudioRendererEventListener(getpid());
907     if (ret != 0) {
908         INTELL_VOICE_LOG_ERROR("UnregisterAudioRendererEventListener failed");
909     }
910 }
911 
912 #ifdef SUPPORT_WINDOW_MANAGER
GetFoldStatusInfo()913 std::string TriggerHelper::GetFoldStatusInfo()
914 {
915     std::string value = isFoldable_ ? "is_foldable=true" : "is_foldable=false";
916     value += ";";
917     value += (curFoldStatus_ == FoldStatus::FOLDED) ? "fold_status=fold" : "fold_status=expand";
918     return value;
919 }
920 
GetParameterInner(const std::string & key,std::string & value)921 bool TriggerHelper::GetParameterInner(const std::string &key, std::string &value)
922 {
923     if (key == std::string("fold_status_info")) {
924         value = GetFoldStatusInfo();
925         INTELL_VOICE_LOG_INFO("get fold_status_info:%{public}s", value.c_str());
926         return true;
927     }
928 
929     return false;
930 }
931 
StartAllRecognition()932 void TriggerHelper::StartAllRecognition()
933 {
934     for (auto iter : modelDataMap_) {
935         if (iter.second == nullptr) {
936             INTELL_VOICE_LOG_ERROR("audio_fold_status model data is null, uuid: %{public}d, ", iter.first);
937             continue;
938         }
939         bool needStart = (iter.second->GetRequested() && (!IsConflictSceneActive()));
940         if (!needStart) {
941             INTELL_VOICE_LOG_INFO("audio_fold_status no need start uuid: %{public}d", iter.first);
942             continue;
943         }
944         if (PrepareForRecognition(iter.second) != 0) {
945             return;
946         }
947         StartRecognition(iter.second);
948     }
949 }
950 
StopAllRecognition()951 void TriggerHelper::StopAllRecognition()
952 {
953     for (auto iter : modelDataMap_) {
954         if (iter.second == nullptr) {
955             INTELL_VOICE_LOG_ERROR("audio_fold_status model data is null, uuid: %{public}d, ", iter.first);
956             continue;
957         }
958         bool needStart = (iter.second->GetRequested() && (!IsConflictSceneActive()));
959         if (!needStart) {
960             INTELL_VOICE_LOG_INFO("audio_fold_status no need stop uuid: %{public}d", iter.first);
961             continue;
962         }
963 
964         StopRecognition(iter.second);
965     }
966 }
967 
RestartAllRecognition()968 void TriggerHelper::RestartAllRecognition()
969 {
970     StopAllRecognition();
971     StartAllRecognition();
972 }
973 
UpdateGenericTriggerModel(std::shared_ptr<GenericTriggerModel> model)974 void TriggerHelper::UpdateGenericTriggerModel(std::shared_ptr<GenericTriggerModel> model)
975 {
976     INTELL_VOICE_LOG_INFO("enter");
977     if (model == nullptr) {
978         INTELL_VOICE_LOG_ERROR("trigger model is null");
979         return;
980     }
981 
982     if (!TriggerDbHelper::GetInstance().UpdateGenericTriggerModel(model)) {
983         INTELL_VOICE_LOG_ERROR("failed to update generic model");
984     }
985 }
986 
ReadWhisperModel()987 std::shared_ptr<GenericTriggerModel> TriggerHelper::ReadWhisperModel()
988 {
989     std::string modelPath = (curFoldStatus_ == FoldStatus::FOLDED) ? WHISPER_MODEL_PATH_VDE : WHISPER_MODEL_PATH;
990     std::shared_ptr<uint8_t> buffer = nullptr;
991     uint32_t size = 0;
992     if (!IntellVoiceUtil::ReadFile(modelPath, buffer, size)) {
993         INTELL_VOICE_LOG_ERROR("audio_fold_status read model failed");
994         return nullptr;
995     }
996     std::vector<uint8_t> data(buffer.get(), buffer.get() + size);
997     std::shared_ptr<GenericTriggerModel> model = std::make_shared<GenericTriggerModel>(
998         OHOS::IntellVoiceEngine::PROXIMAL_WAKEUP_MODEL_UUID,
999         TriggerModel::TriggerModelVersion::MODLE_VERSION_2,
1000         TriggerModelType::PROXIMAL_WAKEUP_TYPE);
1001     if (model == nullptr) {
1002         INTELL_VOICE_LOG_ERROR("audio_fold_status model null");
1003         return nullptr;
1004     }
1005     model->SetData(data);
1006     return model;
1007 }
1008 
ReLoadWhisperModel(shared_ptr<TriggerModelData> modelData)1009 void TriggerHelper::ReLoadWhisperModel(shared_ptr<TriggerModelData> modelData)
1010 {
1011     if (modelData->uuid_ != OHOS::IntellVoiceEngine::PROXIMAL_WAKEUP_MODEL_UUID) {
1012         return;
1013     }
1014 
1015     std::shared_ptr<GenericTriggerModel> model = ReadWhisperModel();
1016     if (model == nullptr) {
1017         INTELL_VOICE_LOG_ERROR("audio_fold_status read model failed");
1018         return;
1019     }
1020     UpdateGenericTriggerModel(model);
1021     if (!modelData->SameModel(model)) {
1022         UnloadModel(modelData);
1023         modelData->SetModel(model);
1024         LoadModel(modelData);
1025     }
1026     INTELL_VOICE_LOG_INFO("audio_fold_status reload model success");
1027 }
1028 
FoldStatusOperation(shared_ptr<TriggerModelData> modelData)1029 void TriggerHelper::FoldStatusOperation(shared_ptr<TriggerModelData> modelData)
1030 {
1031     if (!isFoldable_) {
1032         return;
1033     }
1034 
1035     ReLoadWhisperModel(modelData);
1036 
1037     auto firstElement = modelDataMap_.begin();
1038     if (firstElement->second->uuid_ == modelData->uuid_) {
1039         SetFoldStatus();
1040     }
1041 }
1042 
SetFoldStatus()1043 void TriggerHelper::SetFoldStatus()
1044 {
1045     std::string key = "is_folded";
1046     std::string value = (curFoldStatus_ == FoldStatus::FOLDED) ? "true" : "false";
1047     if (!GetModule()) {
1048         INTELL_VOICE_LOG_ERROR("audio_fold_status get module failed");
1049         return;
1050     }
1051 
1052     if (module_->SetParams(key, value) != 0) {
1053         INTELL_VOICE_LOG_ERROR("audio_fold_status set failed");
1054         return;
1055     }
1056 
1057     INTELL_VOICE_LOG_INFO("audio_fold_status set to hal success is_fold:%{public}s", value.c_str());
1058 }
1059 
OnFoldStatusChanged(FoldStatus foldStatus)1060 void TriggerHelper::OnFoldStatusChanged(FoldStatus foldStatus)
1061 {
1062     std::lock_guard<std::mutex> lock(mutex_);
1063     FoldStatus newFoldStatus = foldStatus;
1064     if (foldStatus == FoldStatus::HALF_FOLD) {
1065         newFoldStatus = FoldStatus::EXPAND;
1066     }
1067     if (curFoldStatus_ == newFoldStatus) {
1068         INTELL_VOICE_LOG_INFO("audio_fold_status same, no deed set");
1069         return;
1070     }
1071     curFoldStatus_ = newFoldStatus;
1072     bool isFolded = (curFoldStatus_ == FoldStatus::FOLDED) ? true : false;
1073     RestartAllRecognition();
1074     INTELL_VOICE_LOG_INFO("audio_fold_status change, status: %{public}d, is_fold: %{public}d", foldStatus, isFolded);
1075 }
1076 
OnFoldStatusChanged(FoldStatus foldStatus)1077 void TriggerHelper::FoldStatusListener::OnFoldStatusChanged(FoldStatus foldStatus)
1078 {
1079     INTELL_VOICE_LOG_INFO("audio_fold_status on change status: %{public}d", foldStatus);
1080     if (helper_ == nullptr) {
1081         INTELL_VOICE_LOG_ERROR("helper is nullptr");
1082         return;
1083     }
1084 
1085     helper_->OnFoldStatusChanged(foldStatus);
1086 }
1087 
RegisterFoldStatusListener()1088 void TriggerHelper::RegisterFoldStatusListener()
1089 {
1090     foldStatusListener_ = std::make_unique<FoldStatusListener>(shared_from_this()).release();
1091     if (foldStatusListener_ == nullptr) {
1092         INTELL_VOICE_LOG_ERROR("audio_fold_status listener is nullptr");
1093         return;
1094     }
1095 
1096     auto ret = OHOS::Rosen::DisplayManagerLite::GetInstance().RegisterFoldStatusListener(foldStatusListener_);
1097     if (ret != OHOS::Rosen::DMError::DM_OK) {
1098         INTELL_VOICE_LOG_ERROR("audio_fold_status register listener failed");
1099         foldStatusListener_ = nullptr;
1100     } else {
1101         INTELL_VOICE_LOG_INFO("audio_fold_status register listener success");
1102     }
1103 }
1104 
AttachFoldStatusListener()1105 void TriggerHelper::AttachFoldStatusListener()
1106 {
1107     INTELL_VOICE_LOG_INFO("audio_fold_status attach enter");
1108     std::lock_guard<std::mutex> lock(foldStatusMutex_);
1109     if (isFoldStatusDetached_) {
1110         INTELL_VOICE_LOG_INFO("audio_fold_status already detached");
1111         return;
1112     }
1113 
1114     bool isFoldable = OHOS::Rosen::DisplayManagerLite::GetInstance().IsFoldable();
1115     bool isFileExist = IntellVoiceUtil::IsFileExist(WHISPER_MODEL_PATH_VDE);
1116     isFoldable_ = (isFileExist && isFoldable) ? true : false;
1117     INTELL_VOICE_LOG_INFO("audio_fold_status isFoldable:%{public}d, isFileExist:%{public}d", isFoldable, isFileExist);
1118     if (!isFoldable_) {
1119         return;
1120     }
1121 
1122     RegisterFoldStatusListener();
1123 
1124     curFoldStatus_ = OHOS::Rosen::DisplayManagerLite::GetInstance().GetFoldStatus();
1125     if (curFoldStatus_ == FoldStatus::FOLDED) {
1126         RestartAllRecognition();
1127     }
1128     INTELL_VOICE_LOG_INFO("audio_fold_status attach success");
1129 }
1130 
DetachFoldStatusListener()1131 void TriggerHelper::DetachFoldStatusListener()
1132 {
1133     INTELL_VOICE_LOG_INFO("audio_fold_status detach enter");
1134     std::lock_guard<std::mutex> lock(foldStatusMutex_);
1135     isFoldStatusDetached_ = true;
1136 
1137     if (foldStatusListener_ == nullptr) {
1138         INTELL_VOICE_LOG_ERROR("audio_fold_status listener is null");
1139         return;
1140     }
1141 
1142     auto ret = OHOS::Rosen::DisplayManagerLite::GetInstance().UnregisterFoldStatusListener(foldStatusListener_);
1143     if (ret != OHOS::Rosen::DMError::DM_OK) {
1144         INTELL_VOICE_LOG_ERROR("audio_fold_status detach failed");
1145     }
1146     foldStatusListener_ = nullptr;
1147     INTELL_VOICE_LOG_INFO("audio_fold_status detach success");
1148 }
1149 #endif
1150 }  // namespace IntellVoiceTrigger
1151 }  // namespace OHOS
1152