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