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