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 #include "intell_voice_log.h"
17
18 #include "trigger_connector_mgr.h"
19
20 using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0;
21 using namespace std;
22 #define LOG_TAG "TriggerHelper"
23
24 namespace OHOS {
25 namespace IntellVoiceTrigger {
TriggerModelData(int32_t uuid)26 TriggerModelData::TriggerModelData(int32_t uuid)
27 {
28 uuid_ = uuid;
29 }
30
~TriggerModelData()31 TriggerModelData::~TriggerModelData()
32 {
33 }
34
SetCallback(std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)35 void TriggerModelData::SetCallback(std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
36 {
37 if (callback == nullptr) {
38 INTELL_VOICE_LOG_ERROR("callback is nullptr");
39 return;
40 }
41 callback_ = callback;
42 }
43
GetCallback()44 std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> TriggerModelData::GetCallback()
45 {
46 return callback_;
47 }
48
SetModel(std::shared_ptr<GenericTriggerModel> model)49 void TriggerModelData::SetModel(std::shared_ptr<GenericTriggerModel> model)
50 {
51 if (SameModel(model)) {
52 INTELL_VOICE_LOG_INFO("same model not need to update");
53 return;
54 }
55 model_ = model;
56 model_->Print();
57 }
58
GetModel()59 shared_ptr<GenericTriggerModel> TriggerModelData::GetModel()
60 {
61 return model_;
62 }
63
SameModel(std::shared_ptr<GenericTriggerModel> model)64 bool TriggerModelData::SameModel(std::shared_ptr<GenericTriggerModel> model)
65 {
66 if (model == nullptr || model_ == nullptr) {
67 return false;
68 }
69 return model_->GetData() == model->GetData();
70 }
71
SetState(ModelState state)72 void TriggerModelData::SetState(ModelState state)
73 {
74 state_ = state;
75 }
76
GetState() const77 ModelState TriggerModelData::GetState() const
78 {
79 return state_;
80 }
81
SetModelHandle(int32_t handle)82 void TriggerModelData::SetModelHandle(int32_t handle)
83 {
84 modelHandle_ = handle;
85 }
86
GetModelHandle() const87 int32_t TriggerModelData::GetModelHandle() const
88 {
89 return modelHandle_;
90 }
91
Clear()92 void TriggerModelData::Clear()
93 {
94 callback_ = nullptr;
95 }
96
TriggerHelper()97 TriggerHelper::TriggerHelper()
98 {
99 const auto &connectMgr = TriggerConnectorMgr::GetInstance();
100 if (connectMgr != nullptr) {
101 moduleDesc_ = connectMgr->ListConnectorModuleDescriptors();
102 }
103 }
104
~TriggerHelper()105 TriggerHelper::~TriggerHelper()
106 {
107 modelDataMap_.clear();
108 }
109
Create()110 std::shared_ptr<TriggerHelper> TriggerHelper::Create()
111 {
112 return std::shared_ptr<TriggerHelper>(new (std::nothrow) TriggerHelper());
113 }
114
StartGenericRecognition(int32_t uuid,std::shared_ptr<GenericTriggerModel> model,shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)115 int32_t TriggerHelper::StartGenericRecognition(int32_t uuid, std::shared_ptr<GenericTriggerModel> model,
116 shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
117 {
118 INTELL_VOICE_LOG_INFO("enter");
119 lock_guard<std::mutex> lock(mutex_);
120
121 auto modelData = GetTriggerModelData(uuid);
122 if (modelData == nullptr) {
123 INTELL_VOICE_LOG_ERROR("failed to get trigger model data");
124 return -1;
125 }
126
127 GetModule();
128
129 bool unload = !modelData->SameModel(model);
130 int32_t ret = InitRecognition(modelData, unload);
131 if (ret != 0) {
132 INTELL_VOICE_LOG_ERROR("failed to initialize recognition");
133 return -1;
134 }
135
136 modelData->SetModel(model);
137 modelData->SetCallback(callback);
138
139 LoadModel(modelData);
140 return StartRecognition(modelData);
141 }
142
StopGenericRecognition(int32_t uuid,shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)143 int32_t TriggerHelper::StopGenericRecognition(
144 int32_t uuid, shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback)
145 {
146 INTELL_VOICE_LOG_INFO("enter");
147 lock_guard<std::mutex> lock(mutex_);
148 auto modelData = GetTriggerModelData(uuid);
149 if (modelData == nullptr) {
150 INTELL_VOICE_LOG_ERROR("failed to get trigger model data");
151 return -1;
152 }
153 modelData->SetCallback(callback);
154 return StopRecognition(modelData);
155 }
156
UnloadGenericTriggerModel(int32_t uuid)157 void TriggerHelper::UnloadGenericTriggerModel(int32_t uuid)
158 {
159 INTELL_VOICE_LOG_INFO("enter");
160 lock_guard<std::mutex> lock(mutex_);
161 auto modelData = GetTriggerModelData(uuid);
162 if (modelData == nullptr) {
163 INTELL_VOICE_LOG_WARN("no trigger model data");
164 return;
165 }
166
167 if (modelData->GetState() == MODEL_NOTLOADED) {
168 INTELL_VOICE_LOG_INFO("model is not loaded");
169 return;
170 }
171 StopRecognition(modelData);
172 UnloadModel(modelData);
173 modelDataMap_.erase(uuid);
174 }
175
GetModule()176 void TriggerHelper::GetModule()
177 {
178 if (module_ != nullptr) {
179 return;
180 }
181 if (moduleDesc_.size() == 0) {
182 INTELL_VOICE_LOG_INFO("moduleDesc_ is empty");
183 return;
184 }
185 module_ =
186 TriggerConnectorMgr::GetInstance()->GetConnectorModule(moduleDesc_[0].adapterName, shared_from_this());
187 if (module_ == nullptr) {
188 INTELL_VOICE_LOG_ERROR("failed to get connector module");
189 }
190 }
191
InitRecognition(std::shared_ptr<TriggerModelData> modelData,bool unload)192 int32_t TriggerHelper::InitRecognition(std::shared_ptr<TriggerModelData> modelData, bool unload)
193 {
194 INTELL_VOICE_LOG_INFO("enter");
195 if (modelData->GetState() == MODEL_NOTLOADED) {
196 return 0;
197 }
198 int32_t ret = StopRecognition(modelData);
199 if (unload) {
200 ret = UnloadModel(modelData);
201 }
202 modelData->Clear();
203 return ret;
204 }
205
StartRecognition(shared_ptr<TriggerModelData> modelData)206 int32_t TriggerHelper::StartRecognition(shared_ptr<TriggerModelData> modelData)
207 {
208 if (modelData == nullptr) {
209 INTELL_VOICE_LOG_ERROR("modelData is nullptr");
210 return -1;
211 }
212 if (modelData->GetState() != MODEL_LOADED) {
213 return 0;
214 }
215 INTELL_VOICE_LOG_INFO("enter");
216 if (module_ == nullptr) {
217 INTELL_VOICE_LOG_ERROR("module_ is nullptr");
218 return -1;
219 }
220 auto ret = module_->Start(modelData->GetModelHandle());
221 modelData->SetState(MODEL_STARTED);
222 return ret;
223 }
224
StopRecognition(shared_ptr<TriggerModelData> modelData)225 int32_t TriggerHelper::StopRecognition(shared_ptr<TriggerModelData> modelData)
226 {
227 if (modelData == nullptr) {
228 INTELL_VOICE_LOG_ERROR("modelData is nullptr");
229 return -1;
230 }
231 if (modelData->GetState() != MODEL_STARTED) {
232 return 0;
233 }
234 INTELL_VOICE_LOG_INFO("enter");
235 if (module_ == nullptr) {
236 INTELL_VOICE_LOG_ERROR("module_ is nullptr");
237 return -1;
238 }
239 auto ret = module_->Stop(modelData->GetModelHandle());
240 modelData->SetState(MODEL_LOADED);
241 return ret;
242 }
243
LoadModel(shared_ptr<TriggerModelData> modelData)244 int32_t TriggerHelper::LoadModel(shared_ptr<TriggerModelData> modelData)
245 {
246 INTELL_VOICE_LOG_INFO("enter");
247 if (modelData == nullptr) {
248 INTELL_VOICE_LOG_ERROR("modelData is nullptr");
249 return -1;
250 }
251 if (modelData->GetState() != MODEL_NOTLOADED) {
252 INTELL_VOICE_LOG_WARN("model is already loaded");
253 return 0;
254 }
255
256 if (module_ == nullptr) {
257 INTELL_VOICE_LOG_ERROR("module_ is nullptr");
258 return -1;
259 }
260
261 int32_t handle;
262 auto ret = module_->LoadModel(modelData->GetModel(), handle);
263 modelData->SetModelHandle(handle);
264 modelData->SetState(MODEL_LOADED);
265 INTELL_VOICE_LOG_INFO("exit, handle: %{public}d", handle);
266 return ret;
267 }
268
UnloadModel(shared_ptr<TriggerModelData> modelData)269 int32_t TriggerHelper::UnloadModel(shared_ptr<TriggerModelData> modelData)
270 {
271 if (modelData == nullptr) {
272 INTELL_VOICE_LOG_ERROR("modelData is nullptr");
273 return -1;
274 }
275 if (modelData->GetState() != MODEL_LOADED) {
276 return 0;
277 }
278 INTELL_VOICE_LOG_INFO("enter");
279 if (module_ == nullptr) {
280 INTELL_VOICE_LOG_ERROR("module_ is nullptr");
281 return -1;
282 }
283 auto ret = module_->UnloadModel(modelData->GetModelHandle());
284 modelData->SetState(MODEL_NOTLOADED);
285 return ret;
286 }
287
GetTriggerModelData(int32_t uuid)288 shared_ptr<TriggerModelData> TriggerHelper::GetTriggerModelData(int32_t uuid)
289 {
290 INTELL_VOICE_LOG_INFO("enter, uuid is :%{public}d", uuid);
291 auto it = modelDataMap_.find(uuid);
292 if (it != modelDataMap_.end() && it->second != nullptr) {
293 return it->second;
294 }
295
296 auto modelData = std::make_shared<TriggerModelData>(uuid);
297 if (modelData == nullptr) {
298 INTELL_VOICE_LOG_INFO("modelData is nullptr");
299 return nullptr;
300 }
301 modelDataMap_.insert(std::make_pair(uuid, modelData));
302 return modelData;
303 }
304
OnRecognition(int32_t modelHandle,const IntellVoiceRecognitionEvent & event)305 void TriggerHelper::OnRecognition(int32_t modelHandle, const IntellVoiceRecognitionEvent &event)
306 {
307 INTELL_VOICE_LOG_INFO("enter, modelHandle:%{public}d", modelHandle);
308 lock_guard<std::mutex> lock(mutex_);
309 std::shared_ptr<IIntellVoiceTriggerRecognitionCallback> callback = nullptr;
310 for (auto iter : modelDataMap_) {
311 if (iter.second == nullptr) {
312 INTELL_VOICE_LOG_ERROR("uuid: %{public}d, model data is nullptr", iter.first);
313 continue;
314 }
315
316 if (iter.second->GetModelHandle() == modelHandle) {
317 iter.second->SetState(MODEL_LOADED);
318 callback = iter.second->GetCallback();
319 break;
320 }
321 }
322
323 if (callback == nullptr) {
324 INTELL_VOICE_LOG_ERROR("trigger recognition callback is nullptr, modelHandle: %{public}d", modelHandle);
325 return;
326 }
327
328 auto genericEvent = std::make_shared<GenericTriggerEvent>();
329 if (genericEvent == nullptr) {
330 INTELL_VOICE_LOG_ERROR("genericEvent is nullptr");
331 return;
332 }
333 genericEvent->modelHandle_ = modelHandle;
334 callback->OnGenericTriggerDetected(genericEvent);
335 }
336 } // namespace IntellVoiceTrigger
337 } // namespace OHOS