• 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 "wakeup_engine.h"
16 #include "idevmgr_hdi.h"
17 #include "intell_voice_engine_manager.h"
18 #include "intell_voice_log.h"
19 #include "headset_host_manager.h"
20 #include "headset_wakeup_wrapper.h"
21 #include "engine_callback_message.h"
22 #include "intell_voice_util.h"
23 #include "ability_manager_client.h"
24 #include "history_info_mgr.h"
25 
26 #define LOG_TAG "WakeupEngine"
27 
28 using namespace OHOS::IntellVoiceUtils;
29 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
30 
31 namespace OHOS {
32 namespace IntellVoiceEngine {
WakeupEngine()33 WakeupEngine::WakeupEngine()
34 {
35     INTELL_VOICE_LOG_INFO("enter");
36 }
37 
~WakeupEngine()38 WakeupEngine::~WakeupEngine()
39 {
40     INTELL_VOICE_LOG_INFO("enter");
41 }
42 
OnDetected(int32_t uuid)43 void WakeupEngine::OnDetected(int32_t uuid)
44 {
45     INTELL_VOICE_LOG_INFO("enter, uuid is %{public}d", uuid);
46     {
47         std::lock_guard<std::mutex> lock(headsetMutex_);
48         if ((headsetImpl_ != nullptr) && (HeadsetWakeupWrapper::GetInstance().GetHeadsetAwakeState() == 1)) {
49             INTELL_VOICE_LOG_INFO("headset wakeup is exist");
50             EngineCallbackMessage::CallFunc(HANDLE_CLOSE_WAKEUP_SOURCE, true);
51             return;
52         }
53     }
54     detectDeviceType_.store(DETECT_TYPE_PHONE);
55 
56     std::thread([uuid]() { IntellVoiceUtil::StartAbility(GetEventValue(uuid)); }).detach();
57     StateMsg msg(START_RECOGNIZE, &uuid, sizeof(int32_t));
58     if (ROLE(WakeupEngineImpl).Handle(msg) != 0) {
59         INTELL_VOICE_LOG_WARN("start failed");
60         EngineCallbackMessage::CallFunc(HANDLE_CLOSE_WAKEUP_SOURCE, true);
61     }
62 }
63 
Init(const std::string &,bool reEnroll)64 bool WakeupEngine::Init(const std::string & /* param */, bool reEnroll)
65 {
66     StateMsg msg(INIT);
67     if (ROLE(WakeupEngineImpl).Handle(msg) != 0) {
68         return false;
69     }
70     return true;
71 }
72 
SetCallback(sptr<IRemoteObject> object)73 void WakeupEngine::SetCallback(sptr<IRemoteObject> object)
74 {
75     sptr<IIntelligentVoiceEngineCallback> callback = iface_cast<IIntelligentVoiceEngineCallback>(object);
76     if (callback == nullptr) {
77         INTELL_VOICE_LOG_WARN("clear callback");
78     }
79     callback_ = callback;
80     SetListenerMsg listenerMsg(callback);
81     StateMsg msg(SET_LISTENER, &listenerMsg, sizeof(SetListenerMsg));
82     ROLE(WakeupEngineImpl).Handle(msg);
83     {
84         std::lock_guard<std::mutex> lock(headsetMutex_);
85         if (headsetImpl_ != nullptr) {
86             headsetImpl_->Handle(msg);
87         }
88     }
89 }
90 
Attach(const IntellVoiceEngineInfo &)91 int32_t WakeupEngine::Attach(const IntellVoiceEngineInfo & /* info */)
92 {
93     return 0;
94 }
95 
StartCapturer(int32_t channels)96 int32_t WakeupEngine::StartCapturer(int32_t channels)
97 {
98     StateMsg msg(START_CAPTURER, &channels, sizeof(int32_t));
99     return HandleCapturerMsg(msg);
100 }
101 
Read(std::vector<uint8_t> & data)102 int32_t WakeupEngine::Read(std::vector<uint8_t> &data)
103 {
104     CapturerData capturerData;
105     StateMsg msg(READ, nullptr, 0, reinterpret_cast<void *>(&capturerData));
106     int32_t ret = HandleCapturerMsg(msg);
107     if (ret != 0) {
108         INTELL_VOICE_LOG_ERROR("read failed, ret:%{public}d", ret);
109         return -1;
110     }
111 
112     data.swap(capturerData.data);
113     return 0;
114 }
115 
StopCapturer()116 int32_t WakeupEngine::StopCapturer()
117 {
118     StateMsg msg(STOP_CAPTURER);
119     return HandleCapturerMsg(msg);
120 }
121 
HandleCapturerMsg(StateMsg & msg)122 int32_t WakeupEngine::HandleCapturerMsg(StateMsg &msg)
123 {
124     int32_t ret = -1;
125     if (detectDeviceType_.load() == DETECT_TYPE_PHONE) {
126         ret = ROLE(WakeupEngineImpl).Handle(msg);
127     } else if (detectDeviceType_.load() == DETECT_TYPE_HEADSET) {
128         std::lock_guard<std::mutex> lock(headsetMutex_);
129         if (headsetImpl_ != nullptr) {
130             ret = headsetImpl_->Handle(msg);
131         }
132     } else {
133         INTELL_VOICE_LOG_ERROR("unknow detectDeviceType");
134     }
135     return ret;
136 }
137 
NotifyHeadsetWakeEvent()138 int32_t WakeupEngine::NotifyHeadsetWakeEvent()
139 {
140     INTELL_VOICE_LOG_INFO("enter");
141     std::lock_guard<std::mutex> lock(headsetMutex_);
142     if (headsetImpl_ == nullptr) {
143         INTELL_VOICE_LOG_ERROR("headset impl is nullptr");
144         return -1;
145     }
146 
147     std::thread([]() { StartAbility("headset_event"); }).detach();
148     detectDeviceType_.store(DETECT_TYPE_HEADSET);
149 
150     StateMsg msg(START_RECOGNIZE);
151     return headsetImpl_->Handle(msg);
152 }
153 
StartAbility(const std::string & event)154 void WakeupEngine::StartAbility(const std::string &event)
155 {
156     AAFwk::Want want;
157     HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
158 
159     std::string bundleName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_BUNDLE_NAME);
160     std::string abilityName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_ABILITY_NAME);
161     INTELL_VOICE_LOG_INFO("bundleName:%{public}s, abilityName:%{public}s", bundleName.c_str(), abilityName.c_str());
162     if (bundleName.empty() || abilityName.empty()) {
163         INTELL_VOICE_LOG_ERROR("bundle name is empty or ability name is empty");
164         return;
165     }
166     want.SetElementName(bundleName, abilityName);
167     want.SetParam("serviceName", std::string("intell_voice"));
168     want.SetParam("servicePid", getpid());
169     want.SetParam("eventType", event);
170     want.SetParam("supportOneShot", true);
171     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
172     if (abilityManagerClient == nullptr) {
173         INTELL_VOICE_LOG_ERROR("abilityManagerClient is nullptr");
174         return;
175     }
176     abilityManagerClient->StartAbility(want);
177 }
178 
HandleHeadsetOff()179 int32_t WakeupEngine::HandleHeadsetOff()
180 {
181     {
182         std::lock_guard<std::mutex> lock(headsetMutex_);
183         if (headsetImpl_ != nullptr) {
184             StateMsg msg(RELEASE);
185             if (headsetImpl_->Handle(msg) != 0) {
186                 INTELL_VOICE_LOG_ERROR("release headset wakeup engine impl failed");
187             }
188             headsetImpl_ = nullptr;
189         }
190     }
191     HeadsetHostManager::GetInstance().DeregisterEngineHDIDeathRecipient();
192     auto devmgr = IDeviceManager::Get();
193     if (devmgr == nullptr) {
194         INTELL_VOICE_LOG_ERROR("get devmgr failed");
195         return -1;
196     }
197     devmgr->UnloadDevice("tws_kws_service");
198     return 0;
199 }
200 
HandleHeadsetOn()201 int32_t WakeupEngine::HandleHeadsetOn()
202 {
203     auto devmgr = IDeviceManager::Get();
204     if (devmgr == nullptr) {
205         INTELL_VOICE_LOG_ERROR("get devmgr failed");
206         return -1;
207     }
208     devmgr->LoadDevice("tws_kws_service");
209     if (!HeadsetHostManager::GetInstance().Init()) {
210         INTELL_VOICE_LOG_ERROR("init headset host failed");
211         return -1;
212     }
213     HeadsetHostManager::GetInstance().RegisterEngineHDIDeathRecipient();
214 
215     std::lock_guard<std::mutex> lock(headsetMutex_);
216     if (headsetImpl_ != nullptr) {
217         INTELL_VOICE_LOG_WARN("headsetImpl already exist");
218         return 0;
219     }
220 
221     headsetImpl_ = UniquePtrFactory<HeadsetWakeupEngineImpl>::CreateInstance();
222     if (headsetImpl_ == nullptr) {
223         INTELL_VOICE_LOG_ERROR("failed to allocate headset impl");
224         return -1;
225     }
226 
227     SetListenerMsg listenerMsg(callback_);
228     StateMsg msgCb(SET_LISTENER, &listenerMsg, sizeof(SetListenerMsg));
229     if (headsetImpl_ != nullptr) {
230         headsetImpl_->Handle(msgCb);
231     }
232 
233     StateMsg msg(INIT);
234     if (headsetImpl_->Handle(msg) != 0) {
235         INTELL_VOICE_LOG_ERROR("init headset wakeup engine impl failed");
236         headsetImpl_ = nullptr;
237         return -1;
238     }
239     return 0;
240 }
241 
NotifyHeadsetHostEvent(HeadsetHostEventType event)242 int32_t WakeupEngine::NotifyHeadsetHostEvent(HeadsetHostEventType event)
243 {
244     INTELL_VOICE_LOG_INFO("enter, event:%{public}d", event);
245     if (event == HEADSET_HOST_OFF) {
246         return HandleHeadsetOff();
247     } else if (event == HEADSET_HOST_ON) {
248         HandleHeadsetOff();
249         return HandleHeadsetOn();
250     }
251 
252     INTELL_VOICE_LOG_WARN("invalid event:%{public}d", event);
253     return 0;
254 }
255 
Detach(void)256 int32_t WakeupEngine::Detach(void)
257 {
258     StateMsg msg(RELEASE);
259     return ROLE(WakeupEngineImpl).Handle(msg);
260 }
261 
Start(bool)262 int32_t WakeupEngine::Start(bool /* isLast */)
263 {
264     return 0;
265 }
266 
SetParameter(const std::string & keyValueList)267 int32_t WakeupEngine::SetParameter(const std::string &keyValueList)
268 {
269     StringParam param(keyValueList);
270     StateMsg msg(SET_PARAM, &param, sizeof(param));
271     return ROLE(WakeupEngineImpl).Handle(msg);
272 }
273 
GetParameter(const std::string & key)274 std::string WakeupEngine::GetParameter(const std::string &key)
275 {
276     StringParam keyParam(key);
277     StringParam valueParam;
278     StateMsg msg(GET_PARAM, &keyParam, sizeof(keyParam), &valueParam);
279     if (ROLE(WakeupEngineImpl).Handle(msg) != 0) {
280         INTELL_VOICE_LOG_ERROR("failed to get parameter, key:%{public}s", key.c_str());
281         return "";
282     }
283 
284     return valueParam.strParam;
285 }
286 
Stop()287 int32_t WakeupEngine::Stop()
288 {
289     StateMsg msg(STOP_RECOGNIZE);
290     return ROLE(WakeupEngineImpl).Handle(msg);
291 }
292 
GetWakeupPcm(std::vector<uint8_t> & data)293 int32_t WakeupEngine::GetWakeupPcm(std::vector<uint8_t> &data)
294 {
295     CapturerData capturerData;
296     StateMsg msg(GET_WAKEUP_PCM, nullptr, 0, reinterpret_cast<void *>(&capturerData));
297     int32_t ret = ROLE(WakeupEngineImpl).Handle(msg);
298     if (ret != 0) {
299         INTELL_VOICE_LOG_ERROR("get wakeup pcm failed, ret:%{public}d", ret);
300         return -1;
301     }
302 
303     data.swap(capturerData.data);
304     return 0;
305 }
306 
GetEventValue(int32_t uuid)307 std::string WakeupEngine::GetEventValue(int32_t uuid)
308 {
309     if (uuid == PROXIMAL_WAKEUP_MODEL_UUID) {
310         return "whisper_event";
311     }
312 
313     return "recognition_event";
314 }
315 
ResetAdapter()316 bool WakeupEngine::ResetAdapter()
317 {
318     StateMsg msg(RESET_ADAPTER);
319     return (ROLE(WakeupEngineImpl).Handle(msg) == 0 ? true : false);
320 }
321 
ReleaseAdapter()322 void WakeupEngine::ReleaseAdapter()
323 {
324     StateMsg msg(RELEASE_ADAPTER);
325     ROLE(WakeupEngineImpl).Handle(msg);
326 }
327 }  // namespace IntellVoice
328 }  // namespace OHOS
329