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