1 /*
2 * Copyright (c) 2024 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 "engine_util.h"
16 #include <ashmem.h>
17 #include "intell_voice_log.h"
18 #include "string_util.h"
19 #include "scope_guard.h"
20 #include "engine_host_manager.h"
21 #include "engine_callback_message.h"
22 #include "intell_voice_engine_manager.h"
23 #include "history_info_mgr.h"
24 #include "intell_voice_definitions.h"
25
26 #define LOG_TAG "EngineUtils"
27
28 using namespace OHOS::IntellVoiceUtils;
29 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
30 using namespace OHOS::AudioStandard;
31
32 namespace OHOS {
33 namespace IntellVoiceEngine {
34 static const std::string LANGUAGE_TEXT = "language=";
35 static const std::string AREA_TEXT = "area=";
36 static const int32_t INTELL_VOICE_SERVICE_UID = 1042;
37
EngineUtil()38 EngineUtil::EngineUtil()
39 {
40 desc_.adapterType = ADAPTER_TYPE_BUT;
41 }
42
SetParameter(const std::string & keyValueList)43 int32_t EngineUtil::SetParameter(const std::string &keyValueList)
44 {
45 if (adapter_ == nullptr) {
46 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
47 return -1;
48 }
49 return adapter_->SetParameter(keyValueList);
50 }
51
GetParameter(const std::string & key)52 std::string EngineUtil::GetParameter(const std::string &key)
53 {
54 if (adapter_ == nullptr) {
55 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
56 return "";
57 }
58
59 std::string value;
60 adapter_->GetParameter(key, value);
61 return value;
62 }
63
WriteAudio(const uint8_t * buffer,uint32_t size)64 int32_t EngineUtil::WriteAudio(const uint8_t *buffer, uint32_t size)
65 {
66 if (adapter_ == nullptr) {
67 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
68 return -1;
69 }
70
71 if (buffer == nullptr || size == 0) {
72 INTELL_VOICE_LOG_ERROR("buffer is invalid, size:%{public}u", size);
73 return -1;
74 }
75
76 std::vector<uint8_t> audioBuff(&buffer[0], &buffer[size]);
77 return adapter_->WriteAudio(audioBuff);
78 }
79
Stop()80 int32_t EngineUtil::Stop()
81 {
82 if (adapter_ == nullptr) {
83 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
84 return -1;
85 }
86 return adapter_->Stop();
87 }
88
GetWakeupPcm(std::vector<uint8_t> & data)89 int32_t EngineUtil::GetWakeupPcm(std::vector<uint8_t> &data)
90 {
91 if (adapter_ == nullptr) {
92 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
93 return -1;
94 }
95 return adapter_->GetWakeupPcm(data);
96 }
97
Evaluate(const std::string & word,EvaluationResultInfo & info)98 int32_t EngineUtil::Evaluate(const std::string &word, EvaluationResultInfo &info)
99 {
100 if (adapter_ == nullptr) {
101 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
102 return -1;
103 }
104
105 return adapter_->Evaluate(word, info);
106 }
107
SetDspFeatures()108 bool EngineUtil::SetDspFeatures()
109 {
110 if (adapter_ == nullptr) {
111 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
112 return false;
113 }
114
115 auto ret = EngineCallbackMessage::CallFunc(TRIGGERMGR_GET_PARAMETER, KEY_GET_WAKEUP_FEATURE);
116 std::string features = "";
117 if (ret.has_value()) {
118 try {
119 features = std::any_cast<std::string>(*ret);
120 } catch (const std::bad_any_cast&) {
121 INTELL_VOICE_LOG_ERROR("msg bus bad any cast");
122 return false;
123 }
124 } else {
125 INTELL_VOICE_LOG_ERROR("msg bus return no value");
126 return false;
127 }
128
129 if (features == "") {
130 INTELL_VOICE_LOG_WARN("failed to get wakeup dsp feature");
131 features = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WAKEUP_DSP_FEATURE);
132 if (features == "") {
133 INTELL_VOICE_LOG_WARN("no historical wakeup dsp feature");
134 return false;
135 }
136 } else {
137 HistoryInfoMgr::GetInstance().SetStringKVPair(KEY_WAKEUP_DSP_FEATURE, features);
138 }
139
140 std::string kvPair = KEY_GET_WAKEUP_FEATURE + "=" + features;
141 adapter_->SetParameter(kvPair);
142 return true;
143 }
144
WriteBufferFromAshmem(uint8_t * & buffer,uint32_t size,sptr<OHOS::Ashmem> ashmem)145 void EngineUtil::WriteBufferFromAshmem(uint8_t *&buffer, uint32_t size, sptr<OHOS::Ashmem> ashmem)
146 {
147 if (!ashmem->MapReadOnlyAshmem()) {
148 INTELL_VOICE_LOG_ERROR("map ashmem failed");
149 return;
150 }
151
152 const uint8_t *tmpBuffer = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
153 if (tmpBuffer == nullptr) {
154 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
155 return;
156 }
157
158 buffer = new (std::nothrow) uint8_t[size];
159 if (buffer == nullptr) {
160 INTELL_VOICE_LOG_ERROR("allocate buffer failed");
161 return;
162 }
163
164 if (memcpy_s(buffer, size, tmpBuffer, size) != 0) {
165 INTELL_VOICE_LOG_ERROR("memcpy_s failed");
166 return;
167 }
168 }
169
ReadDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)170 std::vector<uint8_t> EngineUtil::ReadDspModel(
171 OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)
172 {
173 INTELL_VOICE_LOG_INFO("enter");
174 uint8_t *buffer = nullptr;
175 uint32_t size = 0;
176 sptr<Ashmem> ashmem = nullptr;
177 std::vector<uint8_t> ret;
178
179 if (adapter_ == nullptr) {
180 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
181 return ret;
182 }
183 adapter_->Read(type, ashmem);
184 if (ashmem == nullptr) {
185 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
186 return ret;
187 }
188
189 ON_SCOPE_EXIT_WITH_NAME(ashmemExit)
190 {
191 INTELL_VOICE_LOG_DEBUG("close ashmem");
192 ashmem->UnmapAshmem();
193 ashmem->CloseAshmem();
194 };
195
196 size = static_cast<uint32_t>(ashmem->GetAshmemSize());
197 if (size == 0) {
198 INTELL_VOICE_LOG_ERROR("size is zero");
199 return ret;
200 }
201
202 WriteBufferFromAshmem(buffer, size, ashmem);
203 if (buffer == nullptr) {
204 INTELL_VOICE_LOG_ERROR("buffer is nullptr");
205 return ret;
206 }
207
208 ON_SCOPE_EXIT_WITH_NAME(bufferExit)
209 {
210 INTELL_VOICE_LOG_DEBUG("now delete buffer");
211 delete[] buffer;
212 buffer = nullptr;
213 };
214 ret.insert(ret.end(), buffer, buffer + size);
215 return ret;
216 }
217
ProcDspModel(const std::vector<uint8_t> & buffer)218 void EngineUtil::ProcDspModel(const std::vector<uint8_t> &buffer)
219 {
220 if (buffer.empty()) {
221 INTELL_VOICE_LOG_ERROR("vector is empty");
222 return;
223 }
224 EngineCallbackMessage::CallFunc(TRIGGERMGR_UPDATE_MODEL, buffer, VOICE_WAKEUP_MODEL_UUID,
225 IntellVoiceTrigger::TriggerModelType::VOICE_WAKEUP_TYPE);
226 }
227
SetLanguage()228 void EngineUtil::SetLanguage()
229 {
230 if (adapter_ == nullptr) {
231 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
232 return;
233 }
234
235 std::string language = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_LANGUAGE);
236 if (language.empty()) {
237 INTELL_VOICE_LOG_WARN("language is empty");
238 return;
239 }
240 adapter_->SetParameter(LANGUAGE_TEXT + language);
241 }
242
SetArea()243 void EngineUtil::SetArea()
244 {
245 if (adapter_ == nullptr) {
246 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
247 return;
248 }
249
250 std::string area = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_AREA);
251 if (area.empty()) {
252 INTELL_VOICE_LOG_WARN("area is empty");
253 return;
254 }
255
256 adapter_->SetParameter(AREA_TEXT + area);
257 }
258
SetSensibility()259 void EngineUtil::SetSensibility()
260 {
261 if (adapter_ == nullptr) {
262 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
263 return;
264 }
265
266 std::string sensibility = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_SENSIBILITY);
267 if (sensibility.empty()) {
268 INTELL_VOICE_LOG_WARN("sensibility is empty");
269 return;
270 }
271
272 auto engineMgr = IntellVoiceEngineManager::GetInstance();
273 if (engineMgr != nullptr) {
274 engineMgr->SetDspSensibility(sensibility);
275 }
276 adapter_->SetParameter(SENSIBILITY_TEXT + sensibility);
277 }
278
SelectInputDevice(DeviceType type)279 void EngineUtil::SelectInputDevice(DeviceType type)
280 {
281 INTELL_VOICE_LOG_INFO("enter");
282 sptr<AudioCapturerFilter> audioCapturerFilter = new (std::nothrow) AudioCapturerFilter();
283 if (audioCapturerFilter == nullptr) {
284 INTELL_VOICE_LOG_ERROR("audioCapturerFilter is nullptr");
285 return;
286 }
287 audioCapturerFilter->uid = INTELL_VOICE_SERVICE_UID;
288 audioCapturerFilter->capturerInfo.sourceType = SourceType::SOURCE_TYPE_VOICE_RECOGNITION;
289 std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceDescriptorVector;
290 auto audioSystemManager = AudioSystemManager::GetInstance();
291 if (audioSystemManager == nullptr) {
292 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
293 return;
294 }
295 auto audioDeviceDescriptors = audioSystemManager->GetDevices(DeviceFlag::INPUT_DEVICES_FLAG);
296 for (int i = 0; i < audioDeviceDescriptors.size(); i++) {
297 if (audioDeviceDescriptors[i]->deviceType_ == type) {
298 deviceDescriptorVector.push_back(audioDeviceDescriptors[i]);
299 }
300 }
301 audioSystemManager->SelectInputDevice(audioCapturerFilter, deviceDescriptorVector);
302 }
303
SetScreenStatus()304 void EngineUtil::SetScreenStatus()
305 {
306 if (IntellVoiceEngineManager::GetScreenOff()) {
307 SetParameter("screenoff=true");
308 } else {
309 SetParameter("screenoff=false");
310 }
311 }
312 }
313 }
314