blob: b1d34dfad9ea3256673763ac5be2daa79050a40d [file] [log] [blame]
Eric Laurent7a544b42016-08-05 19:01:13 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SoundTriggerHalHidl"
18//#define LOG_NDEBUG 0
19
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -080020#include <android/hidl/allocator/1.0/IAllocator.h>
Mikhail Naganovd621ac82017-01-12 17:17:45 -080021#include <media/audiohal/hidl/HalDeathHandler.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070022#include <utils/Log.h>
23#include "SoundTriggerHalHidl.h"
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -080024#include <hidlmemory/mapping.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070025#include <hwbinder/IPCThreadState.h>
26#include <hwbinder/ProcessState.h>
27
28namespace android {
29
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -080030using ::android::hardware::ProcessState;
31using ::android::hardware::Return;
32using ::android::hardware::Status;
33using ::android::hardware::Void;
34using ::android::hardware::audio::common::V2_0::AudioDevice;
35using ::android::hardware::hidl_memory;
36using ::android::hidl::allocator::V1_0::IAllocator;
37using ::android::hidl::memory::V1_0::IMemory;
38
39namespace {
40
41// Backs up by the vector with the contents of shared memory.
42// It is assumed that the passed hidl_vector is empty, so it's
43// not cleared if the memory is a null object.
44// The caller needs to keep the returned sp<IMemory> as long as
45// the data is needed.
46std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
47 sp<IMemory> memory;
48 if (m.size() == 0) {
49 return std::make_pair(true, memory);
50 }
51 memory = mapMemory(m);
52 if (memory != nullptr) {
53 memory->read();
54 vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
55 memory->getSize());
56 return std::make_pair(true, memory);
57 }
58 ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
59 return std::make_pair(false, memory);
60}
61
62// Moves the data from the vector into allocated shared memory,
63// emptying the vector.
64// It is assumed that the passed hidl_memory is a null object, so it's
65// not reset if the vector is empty.
66// The caller needs to keep the returned sp<IMemory> as long as
67// the data is needed.
68std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
69 sp<IMemory> memory;
70 if (v->size() == 0) {
71 return std::make_pair(true, memory);
72 }
73 sp<IAllocator> ashmem = IAllocator::getService("ashmem");
74 if (ashmem == 0) {
75 ALOGE("Failed to retrieve ashmem allocator service");
76 return std::make_pair(false, memory);
77 }
78 bool success = false;
79 Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
80 success = s;
81 if (success) *mem = m;
82 });
83 if (r.isOk() && success) {
84 memory = hardware::mapMemory(*mem);
85 if (memory != 0) {
86 memory->update();
87 memcpy(memory->getPointer(), v->data(), v->size());
88 memory->commit();
89 v->resize(0);
90 return std::make_pair(true, memory);
91 } else {
92 ALOGE("Failed to map allocated ashmem");
93 }
94 } else {
95 ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
96 }
97 return std::make_pair(false, memory);
98}
99
100} // namespace
Eric Laurent7a544b42016-08-05 19:01:13 -0700101
Eric Laurent7a544b42016-08-05 19:01:13 -0700102/* static */
103sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
104{
105 return new SoundTriggerHalHidl(moduleName);
106}
107
108int SoundTriggerHalHidl::getProperties(struct sound_trigger_properties *properties)
109{
110 sp<ISoundTriggerHw> soundtrigger = getService();
111 if (soundtrigger == 0) {
112 return -ENODEV;
113 }
114
115 ISoundTriggerHw::Properties halProperties;
116 Return<void> hidlReturn;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800117 int ret;
Eric Laurent7a544b42016-08-05 19:01:13 -0700118 {
119 AutoMutex lock(mHalLock);
120 hidlReturn = soundtrigger->getProperties([&](int rc, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800121 ret = rc;
Eric Laurent7a544b42016-08-05 19:01:13 -0700122 halProperties = res;
123 ALOGI("getProperties res implementor %s", res.implementor.c_str());
124 });
125 }
126
Steven Morelande83be8a2017-01-06 11:06:33 -0800127 if (hidlReturn.isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800128 if (ret == 0) {
129 convertPropertiesFromHal(properties, &halProperties);
130 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700131 } else {
Steven Morelande83be8a2017-01-06 11:06:33 -0800132 ALOGE("getProperties error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800133 return FAILED_TRANSACTION;
Eric Laurent7a544b42016-08-05 19:01:13 -0700134 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800135 ALOGI("getProperties ret %d", ret);
Eric Laurent7a544b42016-08-05 19:01:13 -0700136 return ret;
137}
138
139int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_model,
140 sound_model_callback_t callback,
141 void *cookie,
142 sound_model_handle_t *handle)
143{
144 if (handle == NULL) {
145 return -EINVAL;
146 }
147
148 sp<ISoundTriggerHw> soundtrigger = getService();
149 if (soundtrigger == 0) {
150 return -ENODEV;
151 }
152
153 uint32_t modelId;
154 {
155 AutoMutex lock(mLock);
156 do {
157 modelId = nextUniqueId();
158 ALOGI("loadSoundModel modelId %u", modelId);
159 sp<SoundModel> model = mSoundModels.valueFor(modelId);
160 ALOGI("loadSoundModel model %p", model.get());
161 } while (mSoundModels.valueFor(modelId) != 0 && modelId != 0);
162 }
163 LOG_ALWAYS_FATAL_IF(modelId == 0,
164 "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
165 mSoundModels.size());
166
Eric Laurent7a544b42016-08-05 19:01:13 -0700167 Return<void> hidlReturn;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800168 int ret;
Eric Laurent7a544b42016-08-05 19:01:13 -0700169 SoundModelHandle halHandle;
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800170 sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
mike dooley0415a842018-12-18 19:46:56 +0100171 sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800172 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
mike dooley0415a842018-12-18 19:46:56 +0100173 if (soundtrigger_2_2) {
174 V2_2_ISoundTriggerHw::PhraseSoundModel halSoundModel;
175 auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
176 if (result.first) {
177 AutoMutex lock(mHalLock);
178 hidlReturn = soundtrigger_2_2->loadPhraseSoundModel_2_1(
179 halSoundModel,
180 this, modelId, [&](int32_t retval, auto res) {
181 ret = retval;
182 halHandle = res;
183 });
184 } else {
185 return NO_MEMORY;
186 }
187 } else if (soundtrigger_2_1) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800188 V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
189 auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
190 if (result.first) {
191 AutoMutex lock(mHalLock);
192 hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
193 halSoundModel,
194 this, modelId, [&](int32_t retval, auto res) {
195 ret = retval;
196 halHandle = res;
197 });
198 } else {
199 return NO_MEMORY;
200 }
mike dooley0415a842018-12-18 19:46:56 +0100201 } else {
202 ISoundTriggerHw::PhraseSoundModel halSoundModel;
203 convertPhraseSoundModelToHal(&halSoundModel, sound_model);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800204 AutoMutex lock(mHalLock);
mike dooley0415a842018-12-18 19:46:56 +0100205 hidlReturn = soundtrigger->loadPhraseSoundModel(
206 halSoundModel,
Eric Laurent7a544b42016-08-05 19:01:13 -0700207 this, modelId, [&](int32_t retval, auto res) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800208 ret = retval;
209 halHandle = res;
210 });
mike dooley0415a842018-12-18 19:46:56 +0100211 }
212 } else {
213 if (soundtrigger_2_2) {
214 V2_2_ISoundTriggerHw::SoundModel halSoundModel;
215 auto result = convertSoundModelToHal(&halSoundModel, sound_model);
216 if (result.first) {
217 AutoMutex lock(mHalLock);
218 hidlReturn = soundtrigger_2_2->loadSoundModel_2_1(halSoundModel,
219 this, modelId, [&](int32_t retval, auto res) {
220 ret = retval;
221 halHandle = res;
222 });
223 } else {
224 return NO_MEMORY;
225 }
226 } else if (soundtrigger_2_1) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800227 V2_1_ISoundTriggerHw::SoundModel halSoundModel;
228 auto result = convertSoundModelToHal(&halSoundModel, sound_model);
229 if (result.first) {
230 AutoMutex lock(mHalLock);
231 hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
232 this, modelId, [&](int32_t retval, auto res) {
233 ret = retval;
234 halHandle = res;
235 });
236 } else {
237 return NO_MEMORY;
238 }
mike dooley0415a842018-12-18 19:46:56 +0100239 } else {
240 ISoundTriggerHw::SoundModel halSoundModel;
241 convertSoundModelToHal(&halSoundModel, sound_model);
242 AutoMutex lock(mHalLock);
243 hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
244 this, modelId, [&](int32_t retval, auto res) {
245 ret = retval;
246 halHandle = res;
247 });
Eric Laurent7a544b42016-08-05 19:01:13 -0700248 }
249 }
250
Steven Morelande83be8a2017-01-06 11:06:33 -0800251 if (hidlReturn.isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800252 if (ret == 0) {
253 AutoMutex lock(mLock);
254 *handle = (sound_model_handle_t)modelId;
255 sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
256 mSoundModels.add(*handle, model);
257 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700258 } else {
Steven Morelande83be8a2017-01-06 11:06:33 -0800259 ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800260 return FAILED_TRANSACTION;
Eric Laurent7a544b42016-08-05 19:01:13 -0700261 }
262
Eric Laurent7a544b42016-08-05 19:01:13 -0700263 return ret;
264}
265
266int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
267{
268 sp<ISoundTriggerHw> soundtrigger = getService();
269 if (soundtrigger == 0) {
270 return -ENODEV;
271 }
272
273 sp<SoundModel> model = removeModel(handle);
274 if (model == 0) {
275 ALOGE("unloadSoundModel model not found for handle %u", handle);
276 return -EINVAL;
277 }
278
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800279 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700280 {
281 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800282 hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700283 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800284
285 if (!hidlReturn.isOk()) {
286 ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800287 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800288 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800289
290 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700291}
292
293int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
294 const struct sound_trigger_recognition_config *config,
295 recognition_callback_t callback,
296 void *cookie)
297{
298 sp<ISoundTriggerHw> soundtrigger = getService();
299 if (soundtrigger == 0) {
300 return -ENODEV;
301 }
302
303 sp<SoundModel> model = getModel(handle);
304 if (model == 0) {
305 ALOGE("startRecognition model not found for handle %u", handle);
306 return -EINVAL;
307 }
308
309 model->mRecognitionCallback = callback;
310 model->mRecognitionCookie = cookie;
311
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800312 sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
mike dooley0415a842018-12-18 19:46:56 +0100313 sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800314 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700315
mike dooley0415a842018-12-18 19:46:56 +0100316 if (soundtrigger_2_2) {
317 V2_2_ISoundTriggerHw::RecognitionConfig halConfig;
318 auto result = convertRecognitionConfigToHal(&halConfig, config);
319 if (result.first) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800320 AutoMutex lock(mHalLock);
mike dooley0415a842018-12-18 19:46:56 +0100321 hidlReturn = soundtrigger_2_2->startRecognition_2_1(
322 model->mHalHandle, halConfig, this, handle);
323 } else {
324 return NO_MEMORY;
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800325 }
mike dooley0415a842018-12-18 19:46:56 +0100326 } else if (soundtrigger_2_1) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800327 V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
328 auto result = convertRecognitionConfigToHal(&halConfig, config);
329 if (result.first) {
330 AutoMutex lock(mHalLock);
331 hidlReturn = soundtrigger_2_1->startRecognition_2_1(
332 model->mHalHandle, halConfig, this, handle);
333 } else {
334 return NO_MEMORY;
335 }
mike dooley0415a842018-12-18 19:46:56 +0100336 } else {
337 ISoundTriggerHw::RecognitionConfig halConfig;
338 convertRecognitionConfigToHal(&halConfig, config);
339 {
340 AutoMutex lock(mHalLock);
341 hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
342 }
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800343 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700344
Steven Morelande83be8a2017-01-06 11:06:33 -0800345 if (!hidlReturn.isOk()) {
346 ALOGE("startRecognition error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800347 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800348 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800349 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700350}
351
352int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
353{
354 sp<ISoundTriggerHw> soundtrigger = getService();
355 if (soundtrigger == 0) {
356 return -ENODEV;
357 }
358
359 sp<SoundModel> model = getModel(handle);
360 if (model == 0) {
361 ALOGE("stopRecognition model not found for handle %u", handle);
362 return -EINVAL;
363 }
364
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800365 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700366 {
367 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800368 hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700369 }
370
Steven Morelande83be8a2017-01-06 11:06:33 -0800371 if (!hidlReturn.isOk()) {
372 ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800373 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800374 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800375 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700376}
377
378int SoundTriggerHalHidl::stopAllRecognitions()
379{
380 sp<ISoundTriggerHw> soundtrigger = getService();
381 if (soundtrigger == 0) {
382 return -ENODEV;
383 }
384
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800385 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700386 {
387 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800388 hidlReturn = soundtrigger->stopAllRecognitions();
Eric Laurent7a544b42016-08-05 19:01:13 -0700389 }
390
Steven Morelande83be8a2017-01-06 11:06:33 -0800391 if (!hidlReturn.isOk()) {
392 ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800393 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800394 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800395 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700396}
397
mike dooley6e189b12018-11-07 15:44:37 +0100398int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000399{
400 sp<ISoundTriggerHw> soundtrigger = getService();
401 if (soundtrigger == 0) {
402 return -ENODEV;
403 }
404
405 sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
406 if (soundtrigger_2_2 == 0) {
407 ALOGE("getModelState not supported");
408 return -ENODEV;
409 }
410
411 sp<SoundModel> model = getModel(handle);
412 if (model == 0) {
413 ALOGE("getModelState model not found for handle %u", handle);
414 return -EINVAL;
415 }
416
417 int ret = NO_ERROR;
mike dooley6e189b12018-11-07 15:44:37 +0100418 Return<int32_t> hidlReturn(0);
Michael Dooley67e3d412018-10-16 19:51:16 +0000419 {
420 AutoMutex lock(mHalLock);
mike dooley6e189b12018-11-07 15:44:37 +0100421 hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000422 }
423 if (!hidlReturn.isOk()) {
424 ALOGE("getModelState error %s", hidlReturn.description().c_str());
Michael Dooley67e3d412018-10-16 19:51:16 +0000425 ret = FAILED_TRANSACTION;
426 }
427 return ret;
428}
429
Nicholas Ambur41947e22019-10-01 11:53:40 -0700430int SoundTriggerHalHidl::setParameter(sound_model_handle_t handle,
431 sound_trigger_model_parameter_t model_param, int32_t value)
432{
433 sp<ISoundTriggerHw> soundtrigger = getService();
434 if (!soundtrigger) {
435 return -ENODEV;
436 }
437
438 sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
439 if (!soundtrigger_2_3) {
440 ALOGE("setParameter not supported");
441 return -ENOSYS;
442 }
443
444 sp<SoundModel> model = getModel(handle);
445 if (!model) {
446 ALOGE("setParameter model not found for handle %u", handle);
447 return -EINVAL;
448 }
449
450 V2_3_ModelParameter halParam;
451 convertModelParameterToHal(&halParam, model_param);
452
453 Return<int32_t> hidlReturn(0);
454 {
455 AutoMutex lock(mHalLock);
456 hidlReturn = soundtrigger_2_3->setParameter(model->mHalHandle, halParam, value);
457 }
458 if (!hidlReturn.isOk()) {
459 ALOGE("getModelState error %s", hidlReturn.description().c_str());
460 return FAILED_TRANSACTION;
461 }
462
463 return hidlReturn;
464}
465
466int SoundTriggerHalHidl::getParameter(sound_model_handle_t handle,
467 sound_trigger_model_parameter_t model_param, int32_t* value)
468{
469 sp<ISoundTriggerHw> soundtrigger = getService();
470 if (!soundtrigger) {
471 return -ENODEV;
472 }
473
474 sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
475 if (!soundtrigger_2_3) {
476 ALOGE("getParameter not supported");
477 return -ENOSYS;
478 }
479
480 if (value == NULL) {
481 ALOGE("getParameter invalid value pointer");
482 return -EINVAL;
483 }
484
485 sp<SoundModel> model = getModel(handle);
486 if (!model) {
487 ALOGE("getParameter model not found for handle %u", handle);
488 return -EINVAL;
489 }
490
491 V2_3_ModelParameter halParam;
492 convertModelParameterToHal(&halParam, model_param);
493
494 Return<void> hidlReturn;
495 int32_t hidlStatus;
496 int32_t hidlValue;
497 {
498 AutoMutex lock(mHalLock);
499 hidlReturn = soundtrigger_2_3->getParameter(model->mHalHandle, halParam,
500 [&](int32_t retStatus, int32_t retValue) {
501 hidlStatus = retStatus;
502 hidlValue = retValue;
503 });
504 }
505 if (!hidlReturn.isOk()) {
506 ALOGE("getModelState error %s", hidlReturn.description().c_str());
507 return FAILED_TRANSACTION;
508 }
509
510 *value = hidlValue;
511 return hidlStatus;
512}
513
514int SoundTriggerHalHidl::queryParameter(sound_model_handle_t handle,
515 sound_trigger_model_parameter_t model_param,
516 sound_trigger_model_parameter_range_t* param_range)
517{
518 sp<ISoundTriggerHw> soundtrigger = getService();
519 if (!soundtrigger) {
520 return -ENODEV;
521 }
522
523 sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
524 if (!soundtrigger_2_3) {
525 ALOGE("queryParameter not supported");
526 return -ENOSYS;
527 }
528
529 sp<SoundModel> model = getModel(handle);
530 if (!model) {
531 ALOGE("queryParameter model not found for handle %u", handle);
532 return -EINVAL;
533 }
534
535 V2_3_ModelParameter halParam;
536 convertModelParameterToHal(&halParam, model_param);
537
538 Return<void> hidlReturn;
539 int32_t hidlStatus;
540 V2_3_OptionalModelParameterRange hidlValue;
541 {
542 AutoMutex lock(mHalLock);
543 hidlReturn = soundtrigger_2_3->queryParameter(model->mHalHandle, halParam,
544 [&](int32_t retStatus, V2_3_OptionalModelParameterRange retValue) {
545 hidlStatus = retStatus;
546 hidlValue = retValue;
547 });
548 }
549 if (!hidlReturn.isOk()) {
550 ALOGE("queryParameter error %s", hidlReturn.description().c_str());
551 return FAILED_TRANSACTION;
552 }
553
554 if (hidlStatus != 0) {
555 ALOGE("queryParameter error code: %d", hidlStatus);
556 return hidlStatus;
557 }
558
559 if (hidlValue.getDiscriminator() ==
560 V2_3_OptionalModelParameterRange::hidl_discriminator::noinit) {
561 return -1;
562 }
563
564 param_range->start = hidlValue.range().start;
565 param_range->end = hidlValue.range().end;
566
567 return 0;
568}
569
Eric Laurent7a544b42016-08-05 19:01:13 -0700570SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
571 : mModuleName(moduleName), mNextUniqueId(1)
572{
Mikhail Naganov49ad5522017-04-13 11:00:06 -0700573 LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
574 "Treble soundtrigger only supports primary module");
Eric Laurent7a544b42016-08-05 19:01:13 -0700575}
576
Eric Laurent7a544b42016-08-05 19:01:13 -0700577SoundTriggerHalHidl::~SoundTriggerHalHidl()
578{
579}
580
581sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
582{
583 AutoMutex lock(mLock);
584 if (mISoundTrigger == 0) {
585 if (mModuleName == NULL) {
586 mModuleName = "primary";
587 }
Mikhail Naganov49ad5522017-04-13 11:00:06 -0700588 mISoundTrigger = ISoundTriggerHw::getService();
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800589 if (mISoundTrigger != 0) {
590 mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
591 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700592 }
593 return mISoundTrigger;
594}
595
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800596sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
597{
598 auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
599 return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
600}
601
Michael Dooley67e3d412018-10-16 19:51:16 +0000602sp<V2_2_ISoundTriggerHw> SoundTriggerHalHidl::toService2_2(const sp<ISoundTriggerHw>& s)
603{
604 auto castResult_2_2 = V2_2_ISoundTriggerHw::castFrom(s);
605 return castResult_2_2.isOk() ? static_cast<sp<V2_2_ISoundTriggerHw>>(castResult_2_2) : nullptr;
606}
607
Nicholas Ambur41947e22019-10-01 11:53:40 -0700608sp<V2_3_ISoundTriggerHw> SoundTriggerHalHidl::toService2_3(const sp<ISoundTriggerHw>& s)
609{
610 auto castResult_3_0 = V2_3_ISoundTriggerHw::castFrom(s);
611 return castResult_3_0.isOk() ? static_cast<sp<V2_3_ISoundTriggerHw>>(castResult_3_0) : nullptr;
612}
613
Eric Laurent7a544b42016-08-05 19:01:13 -0700614sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
615{
616 AutoMutex lock(mLock);
617 return mSoundModels.valueFor(handle);
618}
619
620sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
621{
622 AutoMutex lock(mLock);
623 sp<SoundModel> model = mSoundModels.valueFor(handle);
624 mSoundModels.removeItem(handle);
625 return model;
626}
627
628uint32_t SoundTriggerHalHidl::nextUniqueId()
629{
630 return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
631 (uint_fast32_t) 1, memory_order_acq_rel);
632}
633
634void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
Eric Laurentf7854d42016-10-14 15:57:18 -0700635 const sound_trigger_uuid_t *uuid)
Eric Laurent7a544b42016-08-05 19:01:13 -0700636{
637 halUuid->timeLow = uuid->timeLow;
638 halUuid->timeMid = uuid->timeMid;
639 halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
640 halUuid->variantAndClockSeqHigh = uuid->clockSeq;
641 memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
642}
643
Eric Laurentf7854d42016-10-14 15:57:18 -0700644void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
Eric Laurent7a544b42016-08-05 19:01:13 -0700645 const Uuid *halUuid)
646{
647 uuid->timeLow = halUuid->timeLow;
648 uuid->timeMid = halUuid->timeMid;
649 uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
650 uuid->clockSeq = halUuid->variantAndClockSeqHigh;
651 memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
652}
653
654void SoundTriggerHalHidl::convertPropertiesFromHal(
655 struct sound_trigger_properties *properties,
656 const ISoundTriggerHw::Properties *halProperties)
657{
658 strlcpy(properties->implementor,
659 halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
660 strlcpy(properties->description,
661 halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
662 properties->version = halProperties->version;
663 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
664 properties->max_sound_models = halProperties->maxSoundModels;
665 properties->max_key_phrases = halProperties->maxKeyPhrases;
666 properties->max_users = halProperties->maxUsers;
667 properties->recognition_modes = halProperties->recognitionModes;
668 properties->capture_transition = (bool)halProperties->captureTransition;
669 properties->max_buffer_ms = halProperties->maxBufferMs;
670 properties->concurrent_capture = (bool)halProperties->concurrentCapture;
671 properties->trigger_in_event = (bool)halProperties->triggerInEvent;
672 properties->power_consumption_mw = halProperties->powerConsumptionMw;
673}
674
Nicholas Ambur41947e22019-10-01 11:53:40 -0700675// static
676void SoundTriggerHalHidl::convertModelParameterToHal(V2_3_ModelParameter* halParam,
677 sound_trigger_model_parameter_t param)
678{
679 switch (param) {
680 case MODEL_PARAMETER_THRESHOLD_FACTOR:
681 *halParam = V2_3_ModelParameter::THRESHOLD_FACTOR;
682 return;
683 case MODEL_PARAMETER_INVALID:
684 default:
685 *halParam = V2_3_ModelParameter::INVALID;
686 }
687}
688
Eric Laurent7a544b42016-08-05 19:01:13 -0700689void SoundTriggerHalHidl::convertTriggerPhraseToHal(
690 ISoundTriggerHw::Phrase *halTriggerPhrase,
691 const struct sound_trigger_phrase *triggerPhrase)
692{
693 halTriggerPhrase->id = triggerPhrase->id;
694 halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
695 halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
696 halTriggerPhrase->locale = triggerPhrase->locale;
697 halTriggerPhrase->text = triggerPhrase->text;
698}
699
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800700
701void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
702 hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
703 struct sound_trigger_phrase_sound_model *keyPhraseModel)
704{
705 halTriggerPhrases->resize(keyPhraseModel->num_phrases);
706 for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
707 convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
708 }
709}
710
711void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
Eric Laurent7a544b42016-08-05 19:01:13 -0700712 const struct sound_trigger_sound_model *soundModel)
713{
Eric Laurent7a544b42016-08-05 19:01:13 -0700714 halModel->type = (SoundModelType)soundModel->type;
715 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
716 convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
717 halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800718}
Eric Laurent7a544b42016-08-05 19:01:13 -0700719
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800720std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
721 V2_1_ISoundTriggerHw::SoundModel *halModel,
722 const struct sound_trigger_sound_model *soundModel)
723{
724 convertSoundModelToHal(&halModel->header, soundModel);
725 return moveVectorToMemory(&halModel->header.data, &halModel->data);
726}
727
728void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
729 ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
730 const struct sound_trigger_sound_model *soundModel)
731{
732 struct sound_trigger_phrase_sound_model *keyPhraseModel =
733 (struct sound_trigger_phrase_sound_model *)soundModel;
734 convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
735 convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
736}
737
738std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
739 V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
740 const struct sound_trigger_sound_model *soundModel)
741{
742 struct sound_trigger_phrase_sound_model *keyPhraseModel =
743 (struct sound_trigger_phrase_sound_model *)soundModel;
744 convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
745 return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
Eric Laurent7a544b42016-08-05 19:01:13 -0700746}
747
748void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
749 PhraseRecognitionExtra *halExtra,
750 const struct sound_trigger_phrase_recognition_extra *extra)
751{
752 halExtra->id = extra->id;
753 halExtra->recognitionModes = extra->recognition_modes;
754 halExtra->confidenceLevel = extra->confidence_level;
Eric Laurent7a544b42016-08-05 19:01:13 -0700755 halExtra->levels.resize(extra->num_levels);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800756 for (unsigned int i = 0; i < extra->num_levels; i++) {
757 halExtra->levels[i].userId = extra->levels[i].user_id;
758 halExtra->levels[i].levelPercent = extra->levels[i].level;
759 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700760}
761
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800762void SoundTriggerHalHidl::convertRecognitionConfigToHal(
763 ISoundTriggerHw::RecognitionConfig *halConfig,
Eric Laurent7a544b42016-08-05 19:01:13 -0700764 const struct sound_trigger_recognition_config *config)
765{
Eric Laurent7a544b42016-08-05 19:01:13 -0700766 halConfig->captureHandle = config->capture_handle;
767 halConfig->captureDevice = (AudioDevice)config->capture_device;
768 halConfig->captureRequested = (uint32_t)config->capture_requested;
769
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800770 halConfig->phrases.resize(config->num_phrases);
Eric Laurent7a544b42016-08-05 19:01:13 -0700771 for (unsigned int i = 0; i < config->num_phrases; i++) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800772 convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
Eric Laurent7a544b42016-08-05 19:01:13 -0700773 &config->phrases[i]);
774 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700775
776 halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800777}
Eric Laurent7a544b42016-08-05 19:01:13 -0700778
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800779std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
780 V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
781 const struct sound_trigger_recognition_config *config)
782{
783 convertRecognitionConfigToHal(&halConfig->header, config);
784 return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
Eric Laurent7a544b42016-08-05 19:01:13 -0700785}
786
787
788// ISoundTriggerHwCallback
789::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800790 const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700791 CallbackCookie cookie)
792{
793 sp<SoundModel> model;
794 {
795 AutoMutex lock(mLock);
796 model = mSoundModels.valueFor((SoundModelHandle)cookie);
797 if (model == 0) {
798 return Return<void>();
799 }
800 }
801 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
802 if (event == NULL) {
803 return Return<void>();
804 }
805 event->model = model->mHandle;
806 model->mRecognitionCallback(event, model->mRecognitionCookie);
807
808 free(event);
809
810 return Return<void>();
811}
812
813::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800814 const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700815 CallbackCookie cookie)
816{
817 sp<SoundModel> model;
818 {
819 AutoMutex lock(mLock);
820 model = mSoundModels.valueFor((SoundModelHandle)cookie);
821 if (model == 0) {
822 return Return<void>();
823 }
824 }
825
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800826 struct sound_trigger_phrase_recognition_event *event =
827 convertPhraseRecognitionEventFromHal(&halEvent);
Eric Laurent7a544b42016-08-05 19:01:13 -0700828 if (event == NULL) {
829 return Return<void>();
830 }
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800831 event->common.model = model->mHandle;
832 model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
Eric Laurent7a544b42016-08-05 19:01:13 -0700833
834 free(event);
835
836 return Return<void>();
837}
838
839::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800840 const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700841 CallbackCookie cookie)
842{
843 sp<SoundModel> model;
844 {
845 AutoMutex lock(mLock);
846 model = mSoundModels.valueFor((SoundModelHandle)cookie);
847 if (model == 0) {
848 return Return<void>();
849 }
850 }
851
852 struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
853 if (event == NULL) {
854 return Return<void>();
855 }
856
857 event->model = model->mHandle;
858 model->mSoundModelCallback(event, model->mSoundModelCookie);
859
860 free(event);
861
862 return Return<void>();
863}
864
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800865::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
866 const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
867 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
868 V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
869 auto result = memoryAsVector(event.data, &event_2_0.data);
870 return result.first ? recognitionCallback(event_2_0, cookie) : Void();
871}
872
873::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
874 const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
875 V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
876 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
877 event_2_0.common = event.common.header;
878 event_2_0.phraseExtras.setToExternal(
879 const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
880 event.phraseExtras.size());
881 auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
882 return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
883}
884
885::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
886 const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
887 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
888 V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
889 auto result = memoryAsVector(event.data, &event_2_0.data);
890 return result.first ? soundModelCallback(event_2_0, cookie) : Void();
891}
892
Eric Laurent7a544b42016-08-05 19:01:13 -0700893
894struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800895 const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
Eric Laurent7a544b42016-08-05 19:01:13 -0700896{
897 struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
898 sizeof(struct sound_trigger_model_event) +
899 halEvent->data.size());
900 if (event == NULL) {
901 return NULL;
902 }
903
904 event->status = (int)halEvent->status;
905 // event->model to be set by caller
906 event->data_offset = sizeof(struct sound_trigger_model_event);
907 event->data_size = halEvent->data.size();
908 uint8_t *dst = (uint8_t *)event + event->data_offset;
909 uint8_t *src = (uint8_t *)&halEvent->data[0];
910 memcpy(dst, src, halEvent->data.size());
911
912 return event;
913}
914
915void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
916 struct sound_trigger_phrase_recognition_extra *extra,
917 const PhraseRecognitionExtra *halExtra)
918{
919 extra->id = halExtra->id;
920 extra->recognition_modes = halExtra->recognitionModes;
921 extra->confidence_level = halExtra->confidenceLevel;
922
923 size_t i;
924 for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
925 extra->levels[i].user_id = halExtra->levels[i].userId;
926 extra->levels[i].level = halExtra->levels[i].levelPercent;
927 }
928 extra->num_levels = (unsigned int)i;
929}
930
931
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800932struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
933 const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
Eric Laurent7a544b42016-08-05 19:01:13 -0700934{
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800935 if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {
936 ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
937 return NULL;
Eric Laurent7a544b42016-08-05 19:01:13 -0700938 }
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800939 struct sound_trigger_phrase_recognition_event *phraseEvent =
940 (struct sound_trigger_phrase_recognition_event *)malloc(
941 sizeof(struct sound_trigger_phrase_recognition_event) +
942 halPhraseEvent->common.data.size());
943 if (phraseEvent == NULL) {
944 return NULL;
945 }
946 phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
947
948 for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
949 convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
950 &halPhraseEvent->phraseExtras[i]);
951 }
952 phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
953
954 fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
955 return phraseEvent;
956}
957
958struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
959 const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
960{
961 if (halEvent->type == SoundModelType::KEYPHRASE) {
962 ALOGE("Received keyphrase event type as RecognitionEvent");
963 return NULL;
964 }
965 struct sound_trigger_recognition_event *event;
966 event = (struct sound_trigger_recognition_event *)malloc(
967 sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
968 if (event == NULL) {
969 return NULL;
970 }
971 event->data_offset = sizeof(sound_trigger_recognition_event);
972
973 fillRecognitionEventFromHal(event, halEvent);
974 return event;
975}
976
977void SoundTriggerHalHidl::fillRecognitionEventFromHal(
978 struct sound_trigger_recognition_event *event,
979 const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
980{
Eric Laurent7a544b42016-08-05 19:01:13 -0700981 event->status = (int)halEvent->status;
982 event->type = (sound_trigger_sound_model_type_t)halEvent->type;
983 // event->model to be set by caller
984 event->capture_available = (bool)halEvent->captureAvailable;
985 event->capture_session = halEvent->captureSession;
986 event->capture_delay_ms = halEvent->captureDelayMs;
987 event->capture_preamble_ms = halEvent->capturePreambleMs;
988 event->trigger_in_data = (bool)halEvent->triggerInData;
989 event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
990 event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
991 event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
992
993 event->data_size = halEvent->data.size();
994 uint8_t *dst = (uint8_t *)event + event->data_offset;
995 uint8_t *src = (uint8_t *)&halEvent->data[0];
996 memcpy(dst, src, halEvent->data.size());
Eric Laurent7a544b42016-08-05 19:01:13 -0700997}
998
999} // namespace android