blob: 1d37a8ef4422de74f7400135cbf6cc2fe4c56aeb [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);
171 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
172 if (!soundtrigger_2_1) {
173 ISoundTriggerHw::PhraseSoundModel halSoundModel;
174 convertPhraseSoundModelToHal(&halSoundModel, sound_model);
175 AutoMutex lock(mHalLock);
Eric Laurent7a544b42016-08-05 19:01:13 -0700176 hidlReturn = soundtrigger->loadPhraseSoundModel(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800177 halSoundModel,
Eric Laurent7a544b42016-08-05 19:01:13 -0700178 this, modelId, [&](int32_t retval, auto res) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800179 ret = retval;
180 halHandle = res;
181 });
Eric Laurent7a544b42016-08-05 19:01:13 -0700182 } else {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800183 V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
184 auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
185 if (result.first) {
186 AutoMutex lock(mHalLock);
187 hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
188 halSoundModel,
189 this, modelId, [&](int32_t retval, auto res) {
190 ret = retval;
191 halHandle = res;
192 });
193 } else {
194 return NO_MEMORY;
195 }
196 }
197 } else {
198 if (!soundtrigger_2_1) {
199 ISoundTriggerHw::SoundModel halSoundModel;
200 convertSoundModelToHal(&halSoundModel, sound_model);
201 AutoMutex lock(mHalLock);
202 hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
Eric Laurent7a544b42016-08-05 19:01:13 -0700203 this, modelId, [&](int32_t retval, auto res) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800204 ret = retval;
205 halHandle = res;
206 });
207 } else {
208 V2_1_ISoundTriggerHw::SoundModel halSoundModel;
209 auto result = convertSoundModelToHal(&halSoundModel, sound_model);
210 if (result.first) {
211 AutoMutex lock(mHalLock);
212 hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
213 this, modelId, [&](int32_t retval, auto res) {
214 ret = retval;
215 halHandle = res;
216 });
217 } else {
218 return NO_MEMORY;
219 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700220 }
221 }
222
Steven Morelande83be8a2017-01-06 11:06:33 -0800223 if (hidlReturn.isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800224 if (ret == 0) {
225 AutoMutex lock(mLock);
226 *handle = (sound_model_handle_t)modelId;
227 sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
228 mSoundModels.add(*handle, model);
229 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700230 } else {
Steven Morelande83be8a2017-01-06 11:06:33 -0800231 ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800232 return FAILED_TRANSACTION;
Eric Laurent7a544b42016-08-05 19:01:13 -0700233 }
234
Eric Laurent7a544b42016-08-05 19:01:13 -0700235 return ret;
236}
237
238int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
239{
240 sp<ISoundTriggerHw> soundtrigger = getService();
241 if (soundtrigger == 0) {
242 return -ENODEV;
243 }
244
245 sp<SoundModel> model = removeModel(handle);
246 if (model == 0) {
247 ALOGE("unloadSoundModel model not found for handle %u", handle);
248 return -EINVAL;
249 }
250
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800251 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700252 {
253 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800254 hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700255 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800256
257 if (!hidlReturn.isOk()) {
258 ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800259 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800260 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800261
262 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700263}
264
265int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
266 const struct sound_trigger_recognition_config *config,
267 recognition_callback_t callback,
268 void *cookie)
269{
270 sp<ISoundTriggerHw> soundtrigger = getService();
271 if (soundtrigger == 0) {
272 return -ENODEV;
273 }
274
275 sp<SoundModel> model = getModel(handle);
276 if (model == 0) {
277 ALOGE("startRecognition model not found for handle %u", handle);
278 return -EINVAL;
279 }
280
281 model->mRecognitionCallback = callback;
282 model->mRecognitionCookie = cookie;
283
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800284 sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800285 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700286
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800287 if (!soundtrigger_2_1) {
288 ISoundTriggerHw::RecognitionConfig halConfig;
289 convertRecognitionConfigToHal(&halConfig, config);
290 {
291 AutoMutex lock(mHalLock);
292 hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
293 }
294 } else {
295 V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
296 auto result = convertRecognitionConfigToHal(&halConfig, config);
297 if (result.first) {
298 AutoMutex lock(mHalLock);
299 hidlReturn = soundtrigger_2_1->startRecognition_2_1(
300 model->mHalHandle, halConfig, this, handle);
301 } else {
302 return NO_MEMORY;
303 }
304 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700305
Steven Morelande83be8a2017-01-06 11:06:33 -0800306 if (!hidlReturn.isOk()) {
307 ALOGE("startRecognition error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800308 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800309 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800310 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700311}
312
313int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
314{
315 sp<ISoundTriggerHw> soundtrigger = getService();
316 if (soundtrigger == 0) {
317 return -ENODEV;
318 }
319
320 sp<SoundModel> model = getModel(handle);
321 if (model == 0) {
322 ALOGE("stopRecognition model not found for handle %u", handle);
323 return -EINVAL;
324 }
325
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800326 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700327 {
328 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800329 hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700330 }
331
Steven Morelande83be8a2017-01-06 11:06:33 -0800332 if (!hidlReturn.isOk()) {
333 ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800334 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800335 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800336 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700337}
338
339int SoundTriggerHalHidl::stopAllRecognitions()
340{
341 sp<ISoundTriggerHw> soundtrigger = getService();
342 if (soundtrigger == 0) {
343 return -ENODEV;
344 }
345
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800346 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700347 {
348 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800349 hidlReturn = soundtrigger->stopAllRecognitions();
Eric Laurent7a544b42016-08-05 19:01:13 -0700350 }
351
Steven Morelande83be8a2017-01-06 11:06:33 -0800352 if (!hidlReturn.isOk()) {
353 ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800354 return FAILED_TRANSACTION;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800355 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800356 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700357}
358
mike dooley6e189b12018-11-07 15:44:37 +0100359int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000360{
361 sp<ISoundTriggerHw> soundtrigger = getService();
362 if (soundtrigger == 0) {
363 return -ENODEV;
364 }
365
366 sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
367 if (soundtrigger_2_2 == 0) {
368 ALOGE("getModelState not supported");
369 return -ENODEV;
370 }
371
372 sp<SoundModel> model = getModel(handle);
373 if (model == 0) {
374 ALOGE("getModelState model not found for handle %u", handle);
375 return -EINVAL;
376 }
377
378 int ret = NO_ERROR;
mike dooley6e189b12018-11-07 15:44:37 +0100379 Return<int32_t> hidlReturn(0);
Michael Dooley67e3d412018-10-16 19:51:16 +0000380 {
381 AutoMutex lock(mHalLock);
mike dooley6e189b12018-11-07 15:44:37 +0100382 hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000383 }
384 if (!hidlReturn.isOk()) {
385 ALOGE("getModelState error %s", hidlReturn.description().c_str());
Michael Dooley67e3d412018-10-16 19:51:16 +0000386 ret = FAILED_TRANSACTION;
387 }
388 return ret;
389}
390
Eric Laurent7a544b42016-08-05 19:01:13 -0700391SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
392 : mModuleName(moduleName), mNextUniqueId(1)
393{
Mikhail Naganov49ad5522017-04-13 11:00:06 -0700394 LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
395 "Treble soundtrigger only supports primary module");
Eric Laurent7a544b42016-08-05 19:01:13 -0700396}
397
Eric Laurent7a544b42016-08-05 19:01:13 -0700398SoundTriggerHalHidl::~SoundTriggerHalHidl()
399{
400}
401
402sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
403{
404 AutoMutex lock(mLock);
405 if (mISoundTrigger == 0) {
406 if (mModuleName == NULL) {
407 mModuleName = "primary";
408 }
Mikhail Naganov49ad5522017-04-13 11:00:06 -0700409 mISoundTrigger = ISoundTriggerHw::getService();
Mikhail Naganovd621ac82017-01-12 17:17:45 -0800410 if (mISoundTrigger != 0) {
411 mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
412 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700413 }
414 return mISoundTrigger;
415}
416
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800417sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
418{
419 auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
420 return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
421}
422
Michael Dooley67e3d412018-10-16 19:51:16 +0000423sp<V2_2_ISoundTriggerHw> SoundTriggerHalHidl::toService2_2(const sp<ISoundTriggerHw>& s)
424{
425 auto castResult_2_2 = V2_2_ISoundTriggerHw::castFrom(s);
426 return castResult_2_2.isOk() ? static_cast<sp<V2_2_ISoundTriggerHw>>(castResult_2_2) : nullptr;
427}
428
Eric Laurent7a544b42016-08-05 19:01:13 -0700429sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
430{
431 AutoMutex lock(mLock);
432 return mSoundModels.valueFor(handle);
433}
434
435sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
436{
437 AutoMutex lock(mLock);
438 sp<SoundModel> model = mSoundModels.valueFor(handle);
439 mSoundModels.removeItem(handle);
440 return model;
441}
442
443uint32_t SoundTriggerHalHidl::nextUniqueId()
444{
445 return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
446 (uint_fast32_t) 1, memory_order_acq_rel);
447}
448
449void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
Eric Laurentf7854d42016-10-14 15:57:18 -0700450 const sound_trigger_uuid_t *uuid)
Eric Laurent7a544b42016-08-05 19:01:13 -0700451{
452 halUuid->timeLow = uuid->timeLow;
453 halUuid->timeMid = uuid->timeMid;
454 halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
455 halUuid->variantAndClockSeqHigh = uuid->clockSeq;
456 memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
457}
458
Eric Laurentf7854d42016-10-14 15:57:18 -0700459void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
Eric Laurent7a544b42016-08-05 19:01:13 -0700460 const Uuid *halUuid)
461{
462 uuid->timeLow = halUuid->timeLow;
463 uuid->timeMid = halUuid->timeMid;
464 uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
465 uuid->clockSeq = halUuid->variantAndClockSeqHigh;
466 memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
467}
468
469void SoundTriggerHalHidl::convertPropertiesFromHal(
470 struct sound_trigger_properties *properties,
471 const ISoundTriggerHw::Properties *halProperties)
472{
473 strlcpy(properties->implementor,
474 halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
475 strlcpy(properties->description,
476 halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
477 properties->version = halProperties->version;
478 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
479 properties->max_sound_models = halProperties->maxSoundModels;
480 properties->max_key_phrases = halProperties->maxKeyPhrases;
481 properties->max_users = halProperties->maxUsers;
482 properties->recognition_modes = halProperties->recognitionModes;
483 properties->capture_transition = (bool)halProperties->captureTransition;
484 properties->max_buffer_ms = halProperties->maxBufferMs;
485 properties->concurrent_capture = (bool)halProperties->concurrentCapture;
486 properties->trigger_in_event = (bool)halProperties->triggerInEvent;
487 properties->power_consumption_mw = halProperties->powerConsumptionMw;
488}
489
490void SoundTriggerHalHidl::convertTriggerPhraseToHal(
491 ISoundTriggerHw::Phrase *halTriggerPhrase,
492 const struct sound_trigger_phrase *triggerPhrase)
493{
494 halTriggerPhrase->id = triggerPhrase->id;
495 halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
496 halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
497 halTriggerPhrase->locale = triggerPhrase->locale;
498 halTriggerPhrase->text = triggerPhrase->text;
499}
500
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800501
502void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
503 hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
504 struct sound_trigger_phrase_sound_model *keyPhraseModel)
505{
506 halTriggerPhrases->resize(keyPhraseModel->num_phrases);
507 for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
508 convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
509 }
510}
511
512void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
Eric Laurent7a544b42016-08-05 19:01:13 -0700513 const struct sound_trigger_sound_model *soundModel)
514{
Eric Laurent7a544b42016-08-05 19:01:13 -0700515 halModel->type = (SoundModelType)soundModel->type;
516 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
517 convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
518 halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800519}
Eric Laurent7a544b42016-08-05 19:01:13 -0700520
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800521std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
522 V2_1_ISoundTriggerHw::SoundModel *halModel,
523 const struct sound_trigger_sound_model *soundModel)
524{
525 convertSoundModelToHal(&halModel->header, soundModel);
526 return moveVectorToMemory(&halModel->header.data, &halModel->data);
527}
528
529void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
530 ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
531 const struct sound_trigger_sound_model *soundModel)
532{
533 struct sound_trigger_phrase_sound_model *keyPhraseModel =
534 (struct sound_trigger_phrase_sound_model *)soundModel;
535 convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
536 convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
537}
538
539std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
540 V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
541 const struct sound_trigger_sound_model *soundModel)
542{
543 struct sound_trigger_phrase_sound_model *keyPhraseModel =
544 (struct sound_trigger_phrase_sound_model *)soundModel;
545 convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
546 return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
Eric Laurent7a544b42016-08-05 19:01:13 -0700547}
548
549void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
550 PhraseRecognitionExtra *halExtra,
551 const struct sound_trigger_phrase_recognition_extra *extra)
552{
553 halExtra->id = extra->id;
554 halExtra->recognitionModes = extra->recognition_modes;
555 halExtra->confidenceLevel = extra->confidence_level;
Eric Laurent7a544b42016-08-05 19:01:13 -0700556 halExtra->levels.resize(extra->num_levels);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800557 for (unsigned int i = 0; i < extra->num_levels; i++) {
558 halExtra->levels[i].userId = extra->levels[i].user_id;
559 halExtra->levels[i].levelPercent = extra->levels[i].level;
560 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700561}
562
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800563void SoundTriggerHalHidl::convertRecognitionConfigToHal(
564 ISoundTriggerHw::RecognitionConfig *halConfig,
Eric Laurent7a544b42016-08-05 19:01:13 -0700565 const struct sound_trigger_recognition_config *config)
566{
Eric Laurent7a544b42016-08-05 19:01:13 -0700567 halConfig->captureHandle = config->capture_handle;
568 halConfig->captureDevice = (AudioDevice)config->capture_device;
569 halConfig->captureRequested = (uint32_t)config->capture_requested;
570
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800571 halConfig->phrases.resize(config->num_phrases);
Eric Laurent7a544b42016-08-05 19:01:13 -0700572 for (unsigned int i = 0; i < config->num_phrases; i++) {
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800573 convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
Eric Laurent7a544b42016-08-05 19:01:13 -0700574 &config->phrases[i]);
575 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700576
577 halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800578}
Eric Laurent7a544b42016-08-05 19:01:13 -0700579
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800580std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
581 V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
582 const struct sound_trigger_recognition_config *config)
583{
584 convertRecognitionConfigToHal(&halConfig->header, config);
585 return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
Eric Laurent7a544b42016-08-05 19:01:13 -0700586}
587
588
589// ISoundTriggerHwCallback
590::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800591 const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700592 CallbackCookie cookie)
593{
594 sp<SoundModel> model;
595 {
596 AutoMutex lock(mLock);
597 model = mSoundModels.valueFor((SoundModelHandle)cookie);
598 if (model == 0) {
599 return Return<void>();
600 }
601 }
602 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
603 if (event == NULL) {
604 return Return<void>();
605 }
606 event->model = model->mHandle;
607 model->mRecognitionCallback(event, model->mRecognitionCookie);
608
609 free(event);
610
611 return Return<void>();
612}
613
614::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800615 const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700616 CallbackCookie cookie)
617{
618 sp<SoundModel> model;
619 {
620 AutoMutex lock(mLock);
621 model = mSoundModels.valueFor((SoundModelHandle)cookie);
622 if (model == 0) {
623 return Return<void>();
624 }
625 }
626
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800627 struct sound_trigger_phrase_recognition_event *event =
628 convertPhraseRecognitionEventFromHal(&halEvent);
Eric Laurent7a544b42016-08-05 19:01:13 -0700629 if (event == NULL) {
630 return Return<void>();
631 }
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800632 event->common.model = model->mHandle;
633 model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
Eric Laurent7a544b42016-08-05 19:01:13 -0700634
635 free(event);
636
637 return Return<void>();
638}
639
640::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800641 const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
Eric Laurent7a544b42016-08-05 19:01:13 -0700642 CallbackCookie cookie)
643{
644 sp<SoundModel> model;
645 {
646 AutoMutex lock(mLock);
647 model = mSoundModels.valueFor((SoundModelHandle)cookie);
648 if (model == 0) {
649 return Return<void>();
650 }
651 }
652
653 struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
654 if (event == NULL) {
655 return Return<void>();
656 }
657
658 event->model = model->mHandle;
659 model->mSoundModelCallback(event, model->mSoundModelCookie);
660
661 free(event);
662
663 return Return<void>();
664}
665
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800666::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
667 const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
668 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
669 V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
670 auto result = memoryAsVector(event.data, &event_2_0.data);
671 return result.first ? recognitionCallback(event_2_0, cookie) : Void();
672}
673
674::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
675 const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
676 V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
677 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
678 event_2_0.common = event.common.header;
679 event_2_0.phraseExtras.setToExternal(
680 const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
681 event.phraseExtras.size());
682 auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
683 return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
684}
685
686::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
687 const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
688 // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
689 V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
690 auto result = memoryAsVector(event.data, &event_2_0.data);
691 return result.first ? soundModelCallback(event_2_0, cookie) : Void();
692}
693
Eric Laurent7a544b42016-08-05 19:01:13 -0700694
695struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800696 const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
Eric Laurent7a544b42016-08-05 19:01:13 -0700697{
698 struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
699 sizeof(struct sound_trigger_model_event) +
700 halEvent->data.size());
701 if (event == NULL) {
702 return NULL;
703 }
704
705 event->status = (int)halEvent->status;
706 // event->model to be set by caller
707 event->data_offset = sizeof(struct sound_trigger_model_event);
708 event->data_size = halEvent->data.size();
709 uint8_t *dst = (uint8_t *)event + event->data_offset;
710 uint8_t *src = (uint8_t *)&halEvent->data[0];
711 memcpy(dst, src, halEvent->data.size());
712
713 return event;
714}
715
716void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
717 struct sound_trigger_phrase_recognition_extra *extra,
718 const PhraseRecognitionExtra *halExtra)
719{
720 extra->id = halExtra->id;
721 extra->recognition_modes = halExtra->recognitionModes;
722 extra->confidence_level = halExtra->confidenceLevel;
723
724 size_t i;
725 for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
726 extra->levels[i].user_id = halExtra->levels[i].userId;
727 extra->levels[i].level = halExtra->levels[i].levelPercent;
728 }
729 extra->num_levels = (unsigned int)i;
730}
731
732
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800733struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
734 const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
Eric Laurent7a544b42016-08-05 19:01:13 -0700735{
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800736 if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {
737 ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
738 return NULL;
Eric Laurent7a544b42016-08-05 19:01:13 -0700739 }
Mikhail Naganov6f9f1e22018-01-05 14:09:32 -0800740 struct sound_trigger_phrase_recognition_event *phraseEvent =
741 (struct sound_trigger_phrase_recognition_event *)malloc(
742 sizeof(struct sound_trigger_phrase_recognition_event) +
743 halPhraseEvent->common.data.size());
744 if (phraseEvent == NULL) {
745 return NULL;
746 }
747 phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
748
749 for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
750 convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
751 &halPhraseEvent->phraseExtras[i]);
752 }
753 phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
754
755 fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
756 return phraseEvent;
757}
758
759struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
760 const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
761{
762 if (halEvent->type == SoundModelType::KEYPHRASE) {
763 ALOGE("Received keyphrase event type as RecognitionEvent");
764 return NULL;
765 }
766 struct sound_trigger_recognition_event *event;
767 event = (struct sound_trigger_recognition_event *)malloc(
768 sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
769 if (event == NULL) {
770 return NULL;
771 }
772 event->data_offset = sizeof(sound_trigger_recognition_event);
773
774 fillRecognitionEventFromHal(event, halEvent);
775 return event;
776}
777
778void SoundTriggerHalHidl::fillRecognitionEventFromHal(
779 struct sound_trigger_recognition_event *event,
780 const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
781{
Eric Laurent7a544b42016-08-05 19:01:13 -0700782 event->status = (int)halEvent->status;
783 event->type = (sound_trigger_sound_model_type_t)halEvent->type;
784 // event->model to be set by caller
785 event->capture_available = (bool)halEvent->captureAvailable;
786 event->capture_session = halEvent->captureSession;
787 event->capture_delay_ms = halEvent->captureDelayMs;
788 event->capture_preamble_ms = halEvent->capturePreambleMs;
789 event->trigger_in_data = (bool)halEvent->triggerInData;
790 event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
791 event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
792 event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
793
794 event->data_size = halEvent->data.size();
795 uint8_t *dst = (uint8_t *)event + event->data_offset;
796 uint8_t *src = (uint8_t *)&halEvent->data[0];
797 memcpy(dst, src, halEvent->data.size());
Eric Laurent7a544b42016-08-05 19:01:13 -0700798}
799
800} // namespace android