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