1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "SoundTriggerHw"
17*4d7e907cSAndroid Build Coastguard Worker
18*4d7e907cSAndroid Build Coastguard Worker #include "SoundTriggerHw.h"
19*4d7e907cSAndroid Build Coastguard Worker
20*4d7e907cSAndroid Build Coastguard Worker #include <android/hidl/allocator/1.0/IAllocator.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <android/log.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <hidlmemory/mapping.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <utility>
24*4d7e907cSAndroid Build Coastguard Worker
25*4d7e907cSAndroid Build Coastguard Worker using android::hardware::hidl_memory;
26*4d7e907cSAndroid Build Coastguard Worker using android::hidl::allocator::V1_0::IAllocator;
27*4d7e907cSAndroid Build Coastguard Worker using android::hidl::memory::V1_0::IMemory;
28*4d7e907cSAndroid Build Coastguard Worker
29*4d7e907cSAndroid Build Coastguard Worker namespace android {
30*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
31*4d7e907cSAndroid Build Coastguard Worker namespace soundtrigger {
32*4d7e907cSAndroid Build Coastguard Worker namespace V2_3 {
33*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
34*4d7e907cSAndroid Build Coastguard Worker
35*4d7e907cSAndroid Build Coastguard Worker /**
36*4d7e907cSAndroid Build Coastguard Worker * According to the HIDL C++ Users Guide: client and server implementations
37*4d7e907cSAndroid Build Coastguard Worker * should never directly refer to anything other than the interface header
38*4d7e907cSAndroid Build Coastguard Worker * generated from the HIDL definition file (ie. ISoundTriggerHw.hal), so
39*4d7e907cSAndroid Build Coastguard Worker * this V2_3 implementation copies the previous implementations and
40*4d7e907cSAndroid Build Coastguard Worker * then adds the new implementation.
41*4d7e907cSAndroid Build Coastguard Worker */
42*4d7e907cSAndroid Build Coastguard Worker
43*4d7e907cSAndroid Build Coastguard Worker // Begin V2_0 implementation, copied from
44*4d7e907cSAndroid Build Coastguard Worker // hardware/interfaces/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
45*4d7e907cSAndroid Build Coastguard Worker
46*4d7e907cSAndroid Build Coastguard Worker // static
soundModelCallback_(struct sound_trigger_model_event * halEvent,void * cookie)47*4d7e907cSAndroid Build Coastguard Worker void soundModelCallback_(struct sound_trigger_model_event* halEvent, void* cookie) {
48*4d7e907cSAndroid Build Coastguard Worker if (halEvent == NULL) {
49*4d7e907cSAndroid Build Coastguard Worker ALOGW("soundModelCallback called with NULL event");
50*4d7e907cSAndroid Build Coastguard Worker return;
51*4d7e907cSAndroid Build Coastguard Worker }
52*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client =
53*4d7e907cSAndroid Build Coastguard Worker wp<SoundTriggerHw::SoundModelClient>(
54*4d7e907cSAndroid Build Coastguard Worker static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
55*4d7e907cSAndroid Build Coastguard Worker .promote();
56*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
57*4d7e907cSAndroid Build Coastguard Worker ALOGW("soundModelCallback called on stale client");
58*4d7e907cSAndroid Build Coastguard Worker return;
59*4d7e907cSAndroid Build Coastguard Worker }
60*4d7e907cSAndroid Build Coastguard Worker if (halEvent->model != client->getHalHandle()) {
61*4d7e907cSAndroid Build Coastguard Worker ALOGW("soundModelCallback call with wrong handle %d on client with handle %d",
62*4d7e907cSAndroid Build Coastguard Worker (int)halEvent->model, (int)client->getHalHandle());
63*4d7e907cSAndroid Build Coastguard Worker return;
64*4d7e907cSAndroid Build Coastguard Worker }
65*4d7e907cSAndroid Build Coastguard Worker
66*4d7e907cSAndroid Build Coastguard Worker client->soundModelCallback(halEvent);
67*4d7e907cSAndroid Build Coastguard Worker }
68*4d7e907cSAndroid Build Coastguard Worker
69*4d7e907cSAndroid Build Coastguard Worker // static
recognitionCallback_(struct sound_trigger_recognition_event * halEvent,void * cookie)70*4d7e907cSAndroid Build Coastguard Worker void recognitionCallback_(struct sound_trigger_recognition_event* halEvent, void* cookie) {
71*4d7e907cSAndroid Build Coastguard Worker if (halEvent == NULL) {
72*4d7e907cSAndroid Build Coastguard Worker ALOGW("recognitionCallback call NULL event");
73*4d7e907cSAndroid Build Coastguard Worker return;
74*4d7e907cSAndroid Build Coastguard Worker }
75*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client =
76*4d7e907cSAndroid Build Coastguard Worker wp<SoundTriggerHw::SoundModelClient>(
77*4d7e907cSAndroid Build Coastguard Worker static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
78*4d7e907cSAndroid Build Coastguard Worker .promote();
79*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
80*4d7e907cSAndroid Build Coastguard Worker ALOGW("recognitionCallback called on stale client");
81*4d7e907cSAndroid Build Coastguard Worker return;
82*4d7e907cSAndroid Build Coastguard Worker }
83*4d7e907cSAndroid Build Coastguard Worker
84*4d7e907cSAndroid Build Coastguard Worker client->recognitionCallback(halEvent);
85*4d7e907cSAndroid Build Coastguard Worker }
86*4d7e907cSAndroid Build Coastguard Worker
getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb)87*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb) {
88*4d7e907cSAndroid Build Coastguard Worker ALOGV("getProperties() mHwDevice %p", mHwDevice);
89*4d7e907cSAndroid Build Coastguard Worker int ret;
90*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_properties halProperties;
91*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHw::Properties properties;
92*4d7e907cSAndroid Build Coastguard Worker
93*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
94*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
95*4d7e907cSAndroid Build Coastguard Worker goto exit;
96*4d7e907cSAndroid Build Coastguard Worker }
97*4d7e907cSAndroid Build Coastguard Worker
98*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->get_properties(mHwDevice, &halProperties);
99*4d7e907cSAndroid Build Coastguard Worker
100*4d7e907cSAndroid Build Coastguard Worker convertPropertiesFromHal(&properties, &halProperties);
101*4d7e907cSAndroid Build Coastguard Worker
102*4d7e907cSAndroid Build Coastguard Worker ALOGV("getProperties implementor %s recognitionModes %08x", properties.implementor.c_str(),
103*4d7e907cSAndroid Build Coastguard Worker properties.recognitionModes);
104*4d7e907cSAndroid Build Coastguard Worker
105*4d7e907cSAndroid Build Coastguard Worker exit:
106*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(ret, properties);
107*4d7e907cSAndroid Build Coastguard Worker return Void();
108*4d7e907cSAndroid Build Coastguard Worker }
109*4d7e907cSAndroid Build Coastguard Worker
doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel & soundModel,sp<SoundTriggerHw::SoundModelClient> client)110*4d7e907cSAndroid Build Coastguard Worker int SoundTriggerHw::doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
111*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client) {
112*4d7e907cSAndroid Build Coastguard Worker int32_t ret = 0;
113*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_sound_model* halSoundModel;
114*4d7e907cSAndroid Build Coastguard Worker
115*4d7e907cSAndroid Build Coastguard Worker ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size());
116*4d7e907cSAndroid Build Coastguard Worker
117*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
118*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
119*4d7e907cSAndroid Build Coastguard Worker goto exit;
120*4d7e907cSAndroid Build Coastguard Worker }
121*4d7e907cSAndroid Build Coastguard Worker
122*4d7e907cSAndroid Build Coastguard Worker halSoundModel = convertSoundModelToHal(&soundModel);
123*4d7e907cSAndroid Build Coastguard Worker if (halSoundModel == NULL) {
124*4d7e907cSAndroid Build Coastguard Worker ret = -EINVAL;
125*4d7e907cSAndroid Build Coastguard Worker goto exit;
126*4d7e907cSAndroid Build Coastguard Worker }
127*4d7e907cSAndroid Build Coastguard Worker
128*4d7e907cSAndroid Build Coastguard Worker sound_model_handle_t halHandle;
129*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback_, client.get(),
130*4d7e907cSAndroid Build Coastguard Worker &halHandle);
131*4d7e907cSAndroid Build Coastguard Worker
132*4d7e907cSAndroid Build Coastguard Worker free(halSoundModel);
133*4d7e907cSAndroid Build Coastguard Worker
134*4d7e907cSAndroid Build Coastguard Worker if (ret != 0) {
135*4d7e907cSAndroid Build Coastguard Worker goto exit;
136*4d7e907cSAndroid Build Coastguard Worker }
137*4d7e907cSAndroid Build Coastguard Worker
138*4d7e907cSAndroid Build Coastguard Worker client->setHalHandle(halHandle);
139*4d7e907cSAndroid Build Coastguard Worker {
140*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
141*4d7e907cSAndroid Build Coastguard Worker mClients.add(client->getId(), client);
142*4d7e907cSAndroid Build Coastguard Worker }
143*4d7e907cSAndroid Build Coastguard Worker
144*4d7e907cSAndroid Build Coastguard Worker exit:
145*4d7e907cSAndroid Build Coastguard Worker return ret;
146*4d7e907cSAndroid Build Coastguard Worker }
147*4d7e907cSAndroid Build Coastguard Worker
loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel & soundModel,const sp<V2_0::ISoundTriggerHwCallback> & callback,V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,ISoundTriggerHw::loadSoundModel_cb _hidl_cb)148*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
149*4d7e907cSAndroid Build Coastguard Worker const sp<V2_0::ISoundTriggerHwCallback>& callback,
150*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
151*4d7e907cSAndroid Build Coastguard Worker ISoundTriggerHw::loadSoundModel_cb _hidl_cb) {
152*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client =
153*4d7e907cSAndroid Build Coastguard Worker new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
154*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(doLoadSoundModel(soundModel, client), client->getId());
155*4d7e907cSAndroid Build Coastguard Worker return Void();
156*4d7e907cSAndroid Build Coastguard Worker }
157*4d7e907cSAndroid Build Coastguard Worker
loadPhraseSoundModel(const V2_0::ISoundTriggerHw::PhraseSoundModel & soundModel,const sp<V2_0::ISoundTriggerHwCallback> & callback,V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb)158*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::loadPhraseSoundModel(
159*4d7e907cSAndroid Build Coastguard Worker const V2_0::ISoundTriggerHw::PhraseSoundModel& soundModel,
160*4d7e907cSAndroid Build Coastguard Worker const sp<V2_0::ISoundTriggerHwCallback>& callback,
161*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
162*4d7e907cSAndroid Build Coastguard Worker ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb) {
163*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client =
164*4d7e907cSAndroid Build Coastguard Worker new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
165*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel, client),
166*4d7e907cSAndroid Build Coastguard Worker client->getId());
167*4d7e907cSAndroid Build Coastguard Worker return Void();
168*4d7e907cSAndroid Build Coastguard Worker }
169*4d7e907cSAndroid Build Coastguard Worker
unloadSoundModel(int32_t modelHandle)170*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::unloadSoundModel(int32_t modelHandle) {
171*4d7e907cSAndroid Build Coastguard Worker int32_t ret;
172*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client;
173*4d7e907cSAndroid Build Coastguard Worker
174*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
175*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
176*4d7e907cSAndroid Build Coastguard Worker goto exit;
177*4d7e907cSAndroid Build Coastguard Worker }
178*4d7e907cSAndroid Build Coastguard Worker
179*4d7e907cSAndroid Build Coastguard Worker {
180*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
181*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
182*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
183*4d7e907cSAndroid Build Coastguard Worker ret = -ENOSYS;
184*4d7e907cSAndroid Build Coastguard Worker goto exit;
185*4d7e907cSAndroid Build Coastguard Worker }
186*4d7e907cSAndroid Build Coastguard Worker }
187*4d7e907cSAndroid Build Coastguard Worker
188*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->unload_sound_model(mHwDevice, client->getHalHandle());
189*4d7e907cSAndroid Build Coastguard Worker
190*4d7e907cSAndroid Build Coastguard Worker mClients.removeItem(modelHandle);
191*4d7e907cSAndroid Build Coastguard Worker
192*4d7e907cSAndroid Build Coastguard Worker exit:
193*4d7e907cSAndroid Build Coastguard Worker return ret;
194*4d7e907cSAndroid Build Coastguard Worker }
195*4d7e907cSAndroid Build Coastguard Worker
startRecognition(int32_t modelHandle,const V2_0::ISoundTriggerHw::RecognitionConfig & config,const sp<V2_0::ISoundTriggerHwCallback> &,int32_t)196*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::startRecognition(
197*4d7e907cSAndroid Build Coastguard Worker int32_t modelHandle, const V2_0::ISoundTriggerHw::RecognitionConfig& config,
198*4d7e907cSAndroid Build Coastguard Worker const sp<V2_0::ISoundTriggerHwCallback>& /* callback */, int32_t /* cookie */) {
199*4d7e907cSAndroid Build Coastguard Worker int32_t ret;
200*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client;
201*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config* halConfig;
202*4d7e907cSAndroid Build Coastguard Worker
203*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
204*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
205*4d7e907cSAndroid Build Coastguard Worker goto exit;
206*4d7e907cSAndroid Build Coastguard Worker }
207*4d7e907cSAndroid Build Coastguard Worker
208*4d7e907cSAndroid Build Coastguard Worker {
209*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
210*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
211*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
212*4d7e907cSAndroid Build Coastguard Worker ret = -ENOSYS;
213*4d7e907cSAndroid Build Coastguard Worker goto exit;
214*4d7e907cSAndroid Build Coastguard Worker }
215*4d7e907cSAndroid Build Coastguard Worker }
216*4d7e907cSAndroid Build Coastguard Worker
217*4d7e907cSAndroid Build Coastguard Worker halConfig =
218*4d7e907cSAndroid Build Coastguard Worker convertRecognitionConfigToHal((const V2_0::ISoundTriggerHw::RecognitionConfig*)&config);
219*4d7e907cSAndroid Build Coastguard Worker
220*4d7e907cSAndroid Build Coastguard Worker if (halConfig == NULL) {
221*4d7e907cSAndroid Build Coastguard Worker ret = -EINVAL;
222*4d7e907cSAndroid Build Coastguard Worker goto exit;
223*4d7e907cSAndroid Build Coastguard Worker }
224*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig,
225*4d7e907cSAndroid Build Coastguard Worker recognitionCallback_, client.get());
226*4d7e907cSAndroid Build Coastguard Worker
227*4d7e907cSAndroid Build Coastguard Worker free(halConfig);
228*4d7e907cSAndroid Build Coastguard Worker
229*4d7e907cSAndroid Build Coastguard Worker exit:
230*4d7e907cSAndroid Build Coastguard Worker return ret;
231*4d7e907cSAndroid Build Coastguard Worker }
232*4d7e907cSAndroid Build Coastguard Worker
stopRecognition(int32_t modelHandle)233*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::stopRecognition(int32_t modelHandle) {
234*4d7e907cSAndroid Build Coastguard Worker int32_t ret;
235*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client;
236*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
237*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
238*4d7e907cSAndroid Build Coastguard Worker goto exit;
239*4d7e907cSAndroid Build Coastguard Worker }
240*4d7e907cSAndroid Build Coastguard Worker
241*4d7e907cSAndroid Build Coastguard Worker {
242*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
243*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
244*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
245*4d7e907cSAndroid Build Coastguard Worker ret = -ENOSYS;
246*4d7e907cSAndroid Build Coastguard Worker goto exit;
247*4d7e907cSAndroid Build Coastguard Worker }
248*4d7e907cSAndroid Build Coastguard Worker }
249*4d7e907cSAndroid Build Coastguard Worker
250*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->stop_recognition(mHwDevice, client->getHalHandle());
251*4d7e907cSAndroid Build Coastguard Worker
252*4d7e907cSAndroid Build Coastguard Worker exit:
253*4d7e907cSAndroid Build Coastguard Worker return ret;
254*4d7e907cSAndroid Build Coastguard Worker }
255*4d7e907cSAndroid Build Coastguard Worker
stopAllRecognitions()256*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::stopAllRecognitions() {
257*4d7e907cSAndroid Build Coastguard Worker int32_t ret;
258*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
259*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
260*4d7e907cSAndroid Build Coastguard Worker goto exit;
261*4d7e907cSAndroid Build Coastguard Worker }
262*4d7e907cSAndroid Build Coastguard Worker
263*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->stop_all_recognitions(mHwDevice);
264*4d7e907cSAndroid Build Coastguard Worker
265*4d7e907cSAndroid Build Coastguard Worker exit:
266*4d7e907cSAndroid Build Coastguard Worker return ret;
267*4d7e907cSAndroid Build Coastguard Worker }
268*4d7e907cSAndroid Build Coastguard Worker
SoundTriggerHw()269*4d7e907cSAndroid Build Coastguard Worker SoundTriggerHw::SoundTriggerHw() : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1) {}
270*4d7e907cSAndroid Build Coastguard Worker
onFirstRef()271*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::onFirstRef() {
272*4d7e907cSAndroid Build Coastguard Worker const hw_module_t* mod;
273*4d7e907cSAndroid Build Coastguard Worker int rc;
274*4d7e907cSAndroid Build Coastguard Worker
275*4d7e907cSAndroid Build Coastguard Worker rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
276*4d7e907cSAndroid Build Coastguard Worker if (rc != 0) {
277*4d7e907cSAndroid Build Coastguard Worker ALOGE("couldn't load sound trigger module %s.%s (%s)", SOUND_TRIGGER_HARDWARE_MODULE_ID,
278*4d7e907cSAndroid Build Coastguard Worker mModuleName, strerror(-rc));
279*4d7e907cSAndroid Build Coastguard Worker return;
280*4d7e907cSAndroid Build Coastguard Worker }
281*4d7e907cSAndroid Build Coastguard Worker rc = sound_trigger_hw_device_open(mod, &mHwDevice);
282*4d7e907cSAndroid Build Coastguard Worker if (rc != 0) {
283*4d7e907cSAndroid Build Coastguard Worker ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
284*4d7e907cSAndroid Build Coastguard Worker SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
285*4d7e907cSAndroid Build Coastguard Worker mHwDevice = NULL;
286*4d7e907cSAndroid Build Coastguard Worker return;
287*4d7e907cSAndroid Build Coastguard Worker }
288*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
289*4d7e907cSAndroid Build Coastguard Worker ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
290*4d7e907cSAndroid Build Coastguard Worker sound_trigger_hw_device_close(mHwDevice);
291*4d7e907cSAndroid Build Coastguard Worker mHwDevice = NULL;
292*4d7e907cSAndroid Build Coastguard Worker return;
293*4d7e907cSAndroid Build Coastguard Worker }
294*4d7e907cSAndroid Build Coastguard Worker
295*4d7e907cSAndroid Build Coastguard Worker ALOGI("onFirstRef() mModuleName %s mHwDevice %p", mModuleName, mHwDevice);
296*4d7e907cSAndroid Build Coastguard Worker }
297*4d7e907cSAndroid Build Coastguard Worker
~SoundTriggerHw()298*4d7e907cSAndroid Build Coastguard Worker SoundTriggerHw::~SoundTriggerHw() {
299*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice != NULL) {
300*4d7e907cSAndroid Build Coastguard Worker sound_trigger_hw_device_close(mHwDevice);
301*4d7e907cSAndroid Build Coastguard Worker }
302*4d7e907cSAndroid Build Coastguard Worker }
303*4d7e907cSAndroid Build Coastguard Worker
nextUniqueModelId()304*4d7e907cSAndroid Build Coastguard Worker uint32_t SoundTriggerHw::nextUniqueModelId() {
305*4d7e907cSAndroid Build Coastguard Worker uint32_t modelId = 0;
306*4d7e907cSAndroid Build Coastguard Worker {
307*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
308*4d7e907cSAndroid Build Coastguard Worker do {
309*4d7e907cSAndroid Build Coastguard Worker modelId = atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1,
310*4d7e907cSAndroid Build Coastguard Worker memory_order_acq_rel);
311*4d7e907cSAndroid Build Coastguard Worker } while (mClients.valueFor(modelId) != 0 && modelId != 0);
312*4d7e907cSAndroid Build Coastguard Worker }
313*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(modelId == 0, "wrap around in sound model IDs, num loaded models %zu",
314*4d7e907cSAndroid Build Coastguard Worker mClients.size());
315*4d7e907cSAndroid Build Coastguard Worker return modelId;
316*4d7e907cSAndroid Build Coastguard Worker }
317*4d7e907cSAndroid Build Coastguard Worker
convertUuidFromHal(Uuid * uuid,const sound_trigger_uuid_t * halUuid)318*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid) {
319*4d7e907cSAndroid Build Coastguard Worker uuid->timeLow = halUuid->timeLow;
320*4d7e907cSAndroid Build Coastguard Worker uuid->timeMid = halUuid->timeMid;
321*4d7e907cSAndroid Build Coastguard Worker uuid->versionAndTimeHigh = halUuid->timeHiAndVersion;
322*4d7e907cSAndroid Build Coastguard Worker uuid->variantAndClockSeqHigh = halUuid->clockSeq;
323*4d7e907cSAndroid Build Coastguard Worker memcpy(&uuid->node[0], &halUuid->node[0], 6);
324*4d7e907cSAndroid Build Coastguard Worker }
325*4d7e907cSAndroid Build Coastguard Worker
convertUuidToHal(sound_trigger_uuid_t * halUuid,const Uuid * uuid)326*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid) {
327*4d7e907cSAndroid Build Coastguard Worker halUuid->timeLow = uuid->timeLow;
328*4d7e907cSAndroid Build Coastguard Worker halUuid->timeMid = uuid->timeMid;
329*4d7e907cSAndroid Build Coastguard Worker halUuid->timeHiAndVersion = uuid->versionAndTimeHigh;
330*4d7e907cSAndroid Build Coastguard Worker halUuid->clockSeq = uuid->variantAndClockSeqHigh;
331*4d7e907cSAndroid Build Coastguard Worker memcpy(&halUuid->node[0], &uuid->node[0], 6);
332*4d7e907cSAndroid Build Coastguard Worker }
333*4d7e907cSAndroid Build Coastguard Worker
convertPropertiesFromHal(V2_0::ISoundTriggerHw::Properties * properties,const struct sound_trigger_properties * halProperties)334*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertPropertiesFromHal(
335*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHw::Properties* properties,
336*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_properties* halProperties) {
337*4d7e907cSAndroid Build Coastguard Worker properties->implementor = halProperties->implementor;
338*4d7e907cSAndroid Build Coastguard Worker properties->description = halProperties->description;
339*4d7e907cSAndroid Build Coastguard Worker properties->version = halProperties->version;
340*4d7e907cSAndroid Build Coastguard Worker convertUuidFromHal(&properties->uuid, &halProperties->uuid);
341*4d7e907cSAndroid Build Coastguard Worker properties->maxSoundModels = halProperties->max_sound_models;
342*4d7e907cSAndroid Build Coastguard Worker properties->maxKeyPhrases = halProperties->max_key_phrases;
343*4d7e907cSAndroid Build Coastguard Worker properties->maxUsers = halProperties->max_users;
344*4d7e907cSAndroid Build Coastguard Worker properties->recognitionModes = halProperties->recognition_modes;
345*4d7e907cSAndroid Build Coastguard Worker properties->captureTransition = halProperties->capture_transition;
346*4d7e907cSAndroid Build Coastguard Worker properties->maxBufferMs = halProperties->max_buffer_ms;
347*4d7e907cSAndroid Build Coastguard Worker properties->concurrentCapture = halProperties->concurrent_capture;
348*4d7e907cSAndroid Build Coastguard Worker properties->triggerInEvent = halProperties->trigger_in_event;
349*4d7e907cSAndroid Build Coastguard Worker properties->powerConsumptionMw = halProperties->power_consumption_mw;
350*4d7e907cSAndroid Build Coastguard Worker }
351*4d7e907cSAndroid Build Coastguard Worker
convertPropertiesFromHal(V2_3::Properties * properties,const struct sound_trigger_properties_header * header)352*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertPropertiesFromHal(
353*4d7e907cSAndroid Build Coastguard Worker V2_3::Properties* properties, const struct sound_trigger_properties_header* header) {
354*4d7e907cSAndroid Build Coastguard Worker if (header->version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
355*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_properties_extended_1_3* halProperties =
356*4d7e907cSAndroid Build Coastguard Worker (const struct sound_trigger_properties_extended_1_3*)header;
357*4d7e907cSAndroid Build Coastguard Worker convertPropertiesFromHal(&properties->base, &halProperties->base);
358*4d7e907cSAndroid Build Coastguard Worker properties->supportedModelArch = halProperties->supported_model_arch;
359*4d7e907cSAndroid Build Coastguard Worker properties->audioCapabilities = halProperties->audio_capabilities;
360*4d7e907cSAndroid Build Coastguard Worker }
361*4d7e907cSAndroid Build Coastguard Worker }
362*4d7e907cSAndroid Build Coastguard Worker
convertTriggerPhraseToHal(struct sound_trigger_phrase * halTriggerPhrase,const ISoundTriggerHw::Phrase * triggerPhrase)363*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
364*4d7e907cSAndroid Build Coastguard Worker const ISoundTriggerHw::Phrase* triggerPhrase) {
365*4d7e907cSAndroid Build Coastguard Worker halTriggerPhrase->id = triggerPhrase->id;
366*4d7e907cSAndroid Build Coastguard Worker halTriggerPhrase->recognition_mode = triggerPhrase->recognitionModes;
367*4d7e907cSAndroid Build Coastguard Worker unsigned int i;
368*4d7e907cSAndroid Build Coastguard Worker
369*4d7e907cSAndroid Build Coastguard Worker halTriggerPhrase->num_users =
370*4d7e907cSAndroid Build Coastguard Worker std::min((int)triggerPhrase->users.size(), SOUND_TRIGGER_MAX_USERS);
371*4d7e907cSAndroid Build Coastguard Worker for (i = 0; i < halTriggerPhrase->num_users; i++) {
372*4d7e907cSAndroid Build Coastguard Worker halTriggerPhrase->users[i] = triggerPhrase->users[i];
373*4d7e907cSAndroid Build Coastguard Worker }
374*4d7e907cSAndroid Build Coastguard Worker
375*4d7e907cSAndroid Build Coastguard Worker strlcpy(halTriggerPhrase->locale, triggerPhrase->locale.c_str(), SOUND_TRIGGER_MAX_LOCALE_LEN);
376*4d7e907cSAndroid Build Coastguard Worker strlcpy(halTriggerPhrase->text, triggerPhrase->text.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
377*4d7e907cSAndroid Build Coastguard Worker }
378*4d7e907cSAndroid Build Coastguard Worker
convertSoundModelToHal(const V2_0::ISoundTriggerHw::SoundModel * soundModel)379*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_sound_model* SoundTriggerHw::convertSoundModelToHal(
380*4d7e907cSAndroid Build Coastguard Worker const V2_0::ISoundTriggerHw::SoundModel* soundModel) {
381*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_sound_model* halModel = NULL;
382*4d7e907cSAndroid Build Coastguard Worker if (soundModel->type == V2_0::SoundModelType::KEYPHRASE) {
383*4d7e907cSAndroid Build Coastguard Worker size_t allocSize =
384*4d7e907cSAndroid Build Coastguard Worker sizeof(struct sound_trigger_phrase_sound_model) + soundModel->data.size();
385*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_phrase_sound_model* halKeyPhraseModel =
386*4d7e907cSAndroid Build Coastguard Worker static_cast<struct sound_trigger_phrase_sound_model*>(malloc(allocSize));
387*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(halKeyPhraseModel == NULL,
388*4d7e907cSAndroid Build Coastguard Worker "malloc failed for size %zu in convertSoundModelToHal PHRASE",
389*4d7e907cSAndroid Build Coastguard Worker allocSize);
390*4d7e907cSAndroid Build Coastguard Worker
391*4d7e907cSAndroid Build Coastguard Worker const V2_0::ISoundTriggerHw::PhraseSoundModel* keyPhraseModel =
392*4d7e907cSAndroid Build Coastguard Worker reinterpret_cast<const V2_0::ISoundTriggerHw::PhraseSoundModel*>(soundModel);
393*4d7e907cSAndroid Build Coastguard Worker
394*4d7e907cSAndroid Build Coastguard Worker size_t i;
395*4d7e907cSAndroid Build Coastguard Worker for (i = 0; i < keyPhraseModel->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
396*4d7e907cSAndroid Build Coastguard Worker convertTriggerPhraseToHal(&halKeyPhraseModel->phrases[i], &keyPhraseModel->phrases[i]);
397*4d7e907cSAndroid Build Coastguard Worker }
398*4d7e907cSAndroid Build Coastguard Worker halKeyPhraseModel->num_phrases = (unsigned int)i;
399*4d7e907cSAndroid Build Coastguard Worker halModel = reinterpret_cast<struct sound_trigger_sound_model*>(halKeyPhraseModel);
400*4d7e907cSAndroid Build Coastguard Worker halModel->data_offset = sizeof(struct sound_trigger_phrase_sound_model);
401*4d7e907cSAndroid Build Coastguard Worker } else {
402*4d7e907cSAndroid Build Coastguard Worker size_t allocSize = sizeof(struct sound_trigger_sound_model) + soundModel->data.size();
403*4d7e907cSAndroid Build Coastguard Worker halModel = static_cast<struct sound_trigger_sound_model*>(malloc(allocSize));
404*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(halModel == NULL,
405*4d7e907cSAndroid Build Coastguard Worker "malloc failed for size %zu in convertSoundModelToHal GENERIC",
406*4d7e907cSAndroid Build Coastguard Worker allocSize);
407*4d7e907cSAndroid Build Coastguard Worker
408*4d7e907cSAndroid Build Coastguard Worker halModel->data_offset = sizeof(struct sound_trigger_sound_model);
409*4d7e907cSAndroid Build Coastguard Worker }
410*4d7e907cSAndroid Build Coastguard Worker halModel->type = (sound_trigger_sound_model_type_t)soundModel->type;
411*4d7e907cSAndroid Build Coastguard Worker convertUuidToHal(&halModel->uuid, &soundModel->uuid);
412*4d7e907cSAndroid Build Coastguard Worker convertUuidToHal(&halModel->vendor_uuid, &soundModel->vendorUuid);
413*4d7e907cSAndroid Build Coastguard Worker halModel->data_size = soundModel->data.size();
414*4d7e907cSAndroid Build Coastguard Worker uint8_t* dst = reinterpret_cast<uint8_t*>(halModel) + halModel->data_offset;
415*4d7e907cSAndroid Build Coastguard Worker const uint8_t* src = reinterpret_cast<const uint8_t*>(&soundModel->data[0]);
416*4d7e907cSAndroid Build Coastguard Worker memcpy(dst, src, soundModel->data.size());
417*4d7e907cSAndroid Build Coastguard Worker
418*4d7e907cSAndroid Build Coastguard Worker return halModel;
419*4d7e907cSAndroid Build Coastguard Worker }
420*4d7e907cSAndroid Build Coastguard Worker
convertPhraseRecognitionExtraToHal(struct sound_trigger_phrase_recognition_extra * halExtra,const V2_0::PhraseRecognitionExtra * extra)421*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertPhraseRecognitionExtraToHal(
422*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_phrase_recognition_extra* halExtra,
423*4d7e907cSAndroid Build Coastguard Worker const V2_0::PhraseRecognitionExtra* extra) {
424*4d7e907cSAndroid Build Coastguard Worker halExtra->id = extra->id;
425*4d7e907cSAndroid Build Coastguard Worker halExtra->recognition_modes = extra->recognitionModes;
426*4d7e907cSAndroid Build Coastguard Worker halExtra->confidence_level = extra->confidenceLevel;
427*4d7e907cSAndroid Build Coastguard Worker
428*4d7e907cSAndroid Build Coastguard Worker unsigned int i;
429*4d7e907cSAndroid Build Coastguard Worker for (i = 0; i < extra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
430*4d7e907cSAndroid Build Coastguard Worker halExtra->levels[i].user_id = extra->levels[i].userId;
431*4d7e907cSAndroid Build Coastguard Worker halExtra->levels[i].level = extra->levels[i].levelPercent;
432*4d7e907cSAndroid Build Coastguard Worker }
433*4d7e907cSAndroid Build Coastguard Worker halExtra->num_levels = i;
434*4d7e907cSAndroid Build Coastguard Worker }
435*4d7e907cSAndroid Build Coastguard Worker
convertRecognitionConfigToHal(const V2_0::ISoundTriggerHw::RecognitionConfig * config)436*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config* SoundTriggerHw::convertRecognitionConfigToHal(
437*4d7e907cSAndroid Build Coastguard Worker const V2_0::ISoundTriggerHw::RecognitionConfig* config) {
438*4d7e907cSAndroid Build Coastguard Worker size_t allocSize = sizeof(struct sound_trigger_recognition_config) + config->data.size();
439*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config* halConfig =
440*4d7e907cSAndroid Build Coastguard Worker static_cast<struct sound_trigger_recognition_config*>(malloc(allocSize));
441*4d7e907cSAndroid Build Coastguard Worker
442*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(halConfig == NULL,
443*4d7e907cSAndroid Build Coastguard Worker "malloc failed for size %zu in convertRecognitionConfigToHal", allocSize);
444*4d7e907cSAndroid Build Coastguard Worker
445*4d7e907cSAndroid Build Coastguard Worker halConfig->capture_handle = (audio_io_handle_t)config->captureHandle;
446*4d7e907cSAndroid Build Coastguard Worker halConfig->capture_device = (audio_devices_t)config->captureDevice;
447*4d7e907cSAndroid Build Coastguard Worker halConfig->capture_requested = config->captureRequested;
448*4d7e907cSAndroid Build Coastguard Worker
449*4d7e907cSAndroid Build Coastguard Worker unsigned int i;
450*4d7e907cSAndroid Build Coastguard Worker for (i = 0; i < config->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
451*4d7e907cSAndroid Build Coastguard Worker convertPhraseRecognitionExtraToHal(&halConfig->phrases[i], &config->phrases[i]);
452*4d7e907cSAndroid Build Coastguard Worker }
453*4d7e907cSAndroid Build Coastguard Worker halConfig->num_phrases = i;
454*4d7e907cSAndroid Build Coastguard Worker
455*4d7e907cSAndroid Build Coastguard Worker halConfig->data_offset = sizeof(struct sound_trigger_recognition_config);
456*4d7e907cSAndroid Build Coastguard Worker halConfig->data_size = config->data.size();
457*4d7e907cSAndroid Build Coastguard Worker uint8_t* dst = reinterpret_cast<uint8_t*>(halConfig) + halConfig->data_offset;
458*4d7e907cSAndroid Build Coastguard Worker const uint8_t* src = reinterpret_cast<const uint8_t*>(&config->data[0]);
459*4d7e907cSAndroid Build Coastguard Worker memcpy(dst, src, config->data.size());
460*4d7e907cSAndroid Build Coastguard Worker return halConfig;
461*4d7e907cSAndroid Build Coastguard Worker }
462*4d7e907cSAndroid Build Coastguard Worker
convertRecognitionConfigToHalHeader(const V2_3::RecognitionConfig * config)463*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config_header* SoundTriggerHw::convertRecognitionConfigToHalHeader(
464*4d7e907cSAndroid Build Coastguard Worker const V2_3::RecognitionConfig* config) {
465*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> memory;
466*4d7e907cSAndroid Build Coastguard Worker const V2_1::ISoundTriggerHw::RecognitionConfig* config_2_1 = &config->base;
467*4d7e907cSAndroid Build Coastguard Worker const V2_0::ISoundTriggerHw::RecognitionConfig* config_2_0 = &config_2_1->header;
468*4d7e907cSAndroid Build Coastguard Worker
469*4d7e907cSAndroid Build Coastguard Worker size_t allocSize =
470*4d7e907cSAndroid Build Coastguard Worker sizeof(struct sound_trigger_recognition_config_extended_1_3) + config_2_1->data.size();
471*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config_extended_1_3* halConfigExtended =
472*4d7e907cSAndroid Build Coastguard Worker static_cast<struct sound_trigger_recognition_config_extended_1_3*>(malloc(allocSize));
473*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(halConfigExtended == nullptr,
474*4d7e907cSAndroid Build Coastguard Worker "malloc failed for size %zu in convertRecognitionConfigToHalHeader",
475*4d7e907cSAndroid Build Coastguard Worker allocSize);
476*4d7e907cSAndroid Build Coastguard Worker halConfigExtended->header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
477*4d7e907cSAndroid Build Coastguard Worker halConfigExtended->header.size = allocSize;
478*4d7e907cSAndroid Build Coastguard Worker
479*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config* halConfigBase = &halConfigExtended->base;
480*4d7e907cSAndroid Build Coastguard Worker
481*4d7e907cSAndroid Build Coastguard Worker halConfigBase->capture_handle = (audio_io_handle_t)config_2_0->captureHandle;
482*4d7e907cSAndroid Build Coastguard Worker halConfigBase->capture_device = (audio_devices_t)config_2_0->captureDevice;
483*4d7e907cSAndroid Build Coastguard Worker halConfigBase->capture_requested = config_2_0->captureRequested;
484*4d7e907cSAndroid Build Coastguard Worker
485*4d7e907cSAndroid Build Coastguard Worker unsigned int i;
486*4d7e907cSAndroid Build Coastguard Worker for (i = 0; i < config_2_0->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
487*4d7e907cSAndroid Build Coastguard Worker convertPhraseRecognitionExtraToHal(&halConfigBase->phrases[i], &config_2_0->phrases[i]);
488*4d7e907cSAndroid Build Coastguard Worker }
489*4d7e907cSAndroid Build Coastguard Worker halConfigBase->num_phrases = i;
490*4d7e907cSAndroid Build Coastguard Worker
491*4d7e907cSAndroid Build Coastguard Worker halConfigBase->data_offset = sizeof(struct sound_trigger_recognition_config_extended_1_3);
492*4d7e907cSAndroid Build Coastguard Worker halConfigBase->data_size = config_2_1->data.size();
493*4d7e907cSAndroid Build Coastguard Worker if (config_2_1->data.size() != 0) {
494*4d7e907cSAndroid Build Coastguard Worker memory = mapMemory(config_2_1->data);
495*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(memory == nullptr,
496*4d7e907cSAndroid Build Coastguard Worker "failed to map config memory in convertRecognitionConfigToHalHeader");
497*4d7e907cSAndroid Build Coastguard Worker memory->read();
498*4d7e907cSAndroid Build Coastguard Worker
499*4d7e907cSAndroid Build Coastguard Worker uint8_t* dst = reinterpret_cast<uint8_t*>(halConfigExtended) + halConfigBase->data_offset;
500*4d7e907cSAndroid Build Coastguard Worker const uint8_t* src = static_cast<const uint8_t*>(static_cast<void*>(memory->getPointer()));
501*4d7e907cSAndroid Build Coastguard Worker memcpy(dst, src, config_2_1->data.size());
502*4d7e907cSAndroid Build Coastguard Worker
503*4d7e907cSAndroid Build Coastguard Worker memory->commit();
504*4d7e907cSAndroid Build Coastguard Worker }
505*4d7e907cSAndroid Build Coastguard Worker
506*4d7e907cSAndroid Build Coastguard Worker halConfigExtended->audio_capabilities = config->audioCapabilities;
507*4d7e907cSAndroid Build Coastguard Worker
508*4d7e907cSAndroid Build Coastguard Worker return &halConfigExtended->header;
509*4d7e907cSAndroid Build Coastguard Worker }
510*4d7e907cSAndroid Build Coastguard Worker
511*4d7e907cSAndroid Build Coastguard Worker // static
convertSoundModelEventFromHal(V2_0::ISoundTriggerHwCallback::ModelEvent * event,const struct sound_trigger_model_event * halEvent)512*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertSoundModelEventFromHal(
513*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::ModelEvent* event,
514*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_model_event* halEvent) {
515*4d7e907cSAndroid Build Coastguard Worker event->status = (V2_0::ISoundTriggerHwCallback::SoundModelStatus)halEvent->status;
516*4d7e907cSAndroid Build Coastguard Worker // event->model to be remapped by called
517*4d7e907cSAndroid Build Coastguard Worker event->data.setToExternal(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) +
518*4d7e907cSAndroid Build Coastguard Worker halEvent->data_offset,
519*4d7e907cSAndroid Build Coastguard Worker halEvent->data_size);
520*4d7e907cSAndroid Build Coastguard Worker }
521*4d7e907cSAndroid Build Coastguard Worker
522*4d7e907cSAndroid Build Coastguard Worker // static
convertPhaseRecognitionEventFromHal(V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent * event,const struct sound_trigger_phrase_recognition_event * halEvent)523*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertPhaseRecognitionEventFromHal(
524*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
525*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_phrase_recognition_event* halEvent) {
526*4d7e907cSAndroid Build Coastguard Worker event->phraseExtras.resize(halEvent->num_phrases);
527*4d7e907cSAndroid Build Coastguard Worker for (unsigned int i = 0; i < halEvent->num_phrases; i++) {
528*4d7e907cSAndroid Build Coastguard Worker convertPhraseRecognitionExtraFromHal(&event->phraseExtras[i], &halEvent->phrase_extras[i]);
529*4d7e907cSAndroid Build Coastguard Worker }
530*4d7e907cSAndroid Build Coastguard Worker convertRecognitionEventFromHal(&event->common, &halEvent->common);
531*4d7e907cSAndroid Build Coastguard Worker }
532*4d7e907cSAndroid Build Coastguard Worker
533*4d7e907cSAndroid Build Coastguard Worker // static
convertRecognitionEventFromHal(V2_0::ISoundTriggerHwCallback::RecognitionEvent * event,const struct sound_trigger_recognition_event * halEvent)534*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertRecognitionEventFromHal(
535*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::RecognitionEvent* event,
536*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_recognition_event* halEvent) {
537*4d7e907cSAndroid Build Coastguard Worker event->status = static_cast<V2_0::ISoundTriggerHwCallback::RecognitionStatus>(halEvent->status);
538*4d7e907cSAndroid Build Coastguard Worker event->type = static_cast<V2_0::SoundModelType>(halEvent->type);
539*4d7e907cSAndroid Build Coastguard Worker // event->model to be remapped by called
540*4d7e907cSAndroid Build Coastguard Worker event->captureAvailable = halEvent->capture_available;
541*4d7e907cSAndroid Build Coastguard Worker event->captureSession = halEvent->capture_session;
542*4d7e907cSAndroid Build Coastguard Worker event->captureDelayMs = halEvent->capture_delay_ms;
543*4d7e907cSAndroid Build Coastguard Worker event->capturePreambleMs = halEvent->capture_preamble_ms;
544*4d7e907cSAndroid Build Coastguard Worker event->triggerInData = halEvent->trigger_in_data;
545*4d7e907cSAndroid Build Coastguard Worker event->audioConfig.sampleRateHz = halEvent->audio_config.sample_rate;
546*4d7e907cSAndroid Build Coastguard Worker event->audioConfig.channelMask =
547*4d7e907cSAndroid Build Coastguard Worker (audio::common::V2_0::AudioChannelMask)halEvent->audio_config.channel_mask;
548*4d7e907cSAndroid Build Coastguard Worker event->audioConfig.format = (audio::common::V2_0::AudioFormat)halEvent->audio_config.format;
549*4d7e907cSAndroid Build Coastguard Worker event->data.setToExternal(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) +
550*4d7e907cSAndroid Build Coastguard Worker halEvent->data_offset,
551*4d7e907cSAndroid Build Coastguard Worker halEvent->data_size);
552*4d7e907cSAndroid Build Coastguard Worker }
553*4d7e907cSAndroid Build Coastguard Worker
554*4d7e907cSAndroid Build Coastguard Worker // static
convertPhraseRecognitionExtraFromHal(V2_0::PhraseRecognitionExtra * extra,const struct sound_trigger_phrase_recognition_extra * halExtra)555*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::convertPhraseRecognitionExtraFromHal(
556*4d7e907cSAndroid Build Coastguard Worker V2_0::PhraseRecognitionExtra* extra,
557*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_phrase_recognition_extra* halExtra) {
558*4d7e907cSAndroid Build Coastguard Worker extra->id = halExtra->id;
559*4d7e907cSAndroid Build Coastguard Worker extra->recognitionModes = halExtra->recognition_modes;
560*4d7e907cSAndroid Build Coastguard Worker extra->confidenceLevel = halExtra->confidence_level;
561*4d7e907cSAndroid Build Coastguard Worker
562*4d7e907cSAndroid Build Coastguard Worker extra->levels.resize(halExtra->num_levels);
563*4d7e907cSAndroid Build Coastguard Worker for (unsigned int i = 0; i < halExtra->num_levels; i++) {
564*4d7e907cSAndroid Build Coastguard Worker extra->levels[i].userId = halExtra->levels[i].user_id;
565*4d7e907cSAndroid Build Coastguard Worker extra->levels[i].levelPercent = halExtra->levels[i].level;
566*4d7e907cSAndroid Build Coastguard Worker }
567*4d7e907cSAndroid Build Coastguard Worker }
568*4d7e907cSAndroid Build Coastguard Worker
recognitionCallback(struct sound_trigger_recognition_event * halEvent)569*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::SoundModelClient_2_0::recognitionCallback(
570*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_event* halEvent) {
571*4d7e907cSAndroid Build Coastguard Worker if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
572*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
573*4d7e907cSAndroid Build Coastguard Worker convertPhaseRecognitionEventFromHal(
574*4d7e907cSAndroid Build Coastguard Worker &event, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
575*4d7e907cSAndroid Build Coastguard Worker event.common.model = mId;
576*4d7e907cSAndroid Build Coastguard Worker mCallback->phraseRecognitionCallback(event, mCookie);
577*4d7e907cSAndroid Build Coastguard Worker } else {
578*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::RecognitionEvent event;
579*4d7e907cSAndroid Build Coastguard Worker convertRecognitionEventFromHal(&event, halEvent);
580*4d7e907cSAndroid Build Coastguard Worker event.model = mId;
581*4d7e907cSAndroid Build Coastguard Worker mCallback->recognitionCallback(event, mCookie);
582*4d7e907cSAndroid Build Coastguard Worker }
583*4d7e907cSAndroid Build Coastguard Worker }
584*4d7e907cSAndroid Build Coastguard Worker
soundModelCallback(struct sound_trigger_model_event * halEvent)585*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::SoundModelClient_2_0::soundModelCallback(
586*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_model_event* halEvent) {
587*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::ModelEvent event;
588*4d7e907cSAndroid Build Coastguard Worker convertSoundModelEventFromHal(&event, halEvent);
589*4d7e907cSAndroid Build Coastguard Worker event.model = mId;
590*4d7e907cSAndroid Build Coastguard Worker mCallback->soundModelCallback(event, mCookie);
591*4d7e907cSAndroid Build Coastguard Worker }
592*4d7e907cSAndroid Build Coastguard Worker
593*4d7e907cSAndroid Build Coastguard Worker // Begin V2_1 implementation, copied from
594*4d7e907cSAndroid Build Coastguard Worker // hardware/interfaces/soundtrigger/2.1/default/SoundTriggerHw.cpp
595*4d7e907cSAndroid Build Coastguard Worker
596*4d7e907cSAndroid Build Coastguard Worker namespace {
597*4d7e907cSAndroid Build Coastguard Worker
598*4d7e907cSAndroid Build Coastguard Worker // Backs up by the vector with the contents of shared memory.
599*4d7e907cSAndroid Build Coastguard Worker // It is assumed that the passed hidl_vector is empty, so it's
600*4d7e907cSAndroid Build Coastguard Worker // not cleared if the memory is a null object.
601*4d7e907cSAndroid Build Coastguard Worker // The caller needs to keep the returned sp<IMemory> as long as
602*4d7e907cSAndroid Build Coastguard Worker // the data is needed.
memoryAsVector(const hidl_memory & m,hidl_vec<uint8_t> * vec)603*4d7e907cSAndroid Build Coastguard Worker std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
604*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> memory;
605*4d7e907cSAndroid Build Coastguard Worker if (m.size() == 0) {
606*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(true, memory);
607*4d7e907cSAndroid Build Coastguard Worker }
608*4d7e907cSAndroid Build Coastguard Worker memory = mapMemory(m);
609*4d7e907cSAndroid Build Coastguard Worker if (memory != nullptr) {
610*4d7e907cSAndroid Build Coastguard Worker memory->read();
611*4d7e907cSAndroid Build Coastguard Worker vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
612*4d7e907cSAndroid Build Coastguard Worker memory->getSize());
613*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(true, memory);
614*4d7e907cSAndroid Build Coastguard Worker }
615*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
616*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(false, memory);
617*4d7e907cSAndroid Build Coastguard Worker }
618*4d7e907cSAndroid Build Coastguard Worker
619*4d7e907cSAndroid Build Coastguard Worker // Moves the data from the vector into allocated shared memory,
620*4d7e907cSAndroid Build Coastguard Worker // emptying the vector.
621*4d7e907cSAndroid Build Coastguard Worker // It is assumed that the passed hidl_memory is a null object, so it's
622*4d7e907cSAndroid Build Coastguard Worker // not reset if the vector is empty.
623*4d7e907cSAndroid Build Coastguard Worker // The caller needs to keep the returned sp<IMemory> as long as
624*4d7e907cSAndroid Build Coastguard Worker // the data is needed.
moveVectorToMemory(hidl_vec<uint8_t> * v,hidl_memory * mem)625*4d7e907cSAndroid Build Coastguard Worker std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
626*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> memory;
627*4d7e907cSAndroid Build Coastguard Worker if (v->size() == 0) {
628*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(true, memory);
629*4d7e907cSAndroid Build Coastguard Worker }
630*4d7e907cSAndroid Build Coastguard Worker sp<IAllocator> ashmem = IAllocator::getService("ashmem");
631*4d7e907cSAndroid Build Coastguard Worker if (ashmem == 0) {
632*4d7e907cSAndroid Build Coastguard Worker ALOGE("Failed to retrieve ashmem allocator service");
633*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(false, memory);
634*4d7e907cSAndroid Build Coastguard Worker }
635*4d7e907cSAndroid Build Coastguard Worker bool success = false;
636*4d7e907cSAndroid Build Coastguard Worker Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
637*4d7e907cSAndroid Build Coastguard Worker success = s;
638*4d7e907cSAndroid Build Coastguard Worker if (success) *mem = m;
639*4d7e907cSAndroid Build Coastguard Worker });
640*4d7e907cSAndroid Build Coastguard Worker if (r.isOk() && success) {
641*4d7e907cSAndroid Build Coastguard Worker memory = hardware::mapMemory(*mem);
642*4d7e907cSAndroid Build Coastguard Worker if (memory != 0) {
643*4d7e907cSAndroid Build Coastguard Worker memory->update();
644*4d7e907cSAndroid Build Coastguard Worker memcpy(memory->getPointer(), v->data(), v->size());
645*4d7e907cSAndroid Build Coastguard Worker memory->commit();
646*4d7e907cSAndroid Build Coastguard Worker v->resize(0);
647*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(true, memory);
648*4d7e907cSAndroid Build Coastguard Worker } else {
649*4d7e907cSAndroid Build Coastguard Worker ALOGE("Failed to map allocated ashmem");
650*4d7e907cSAndroid Build Coastguard Worker }
651*4d7e907cSAndroid Build Coastguard Worker } else {
652*4d7e907cSAndroid Build Coastguard Worker ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
653*4d7e907cSAndroid Build Coastguard Worker }
654*4d7e907cSAndroid Build Coastguard Worker return std::make_pair(false, memory);
655*4d7e907cSAndroid Build Coastguard Worker }
656*4d7e907cSAndroid Build Coastguard Worker
657*4d7e907cSAndroid Build Coastguard Worker } // namespace
658*4d7e907cSAndroid Build Coastguard Worker
loadSoundModel_2_1(const V2_1::ISoundTriggerHw::SoundModel & soundModel,const sp<V2_1::ISoundTriggerHwCallback> & callback,int32_t cookie,V2_1::ISoundTriggerHw::loadSoundModel_2_1_cb _hidl_cb)659*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::loadSoundModel_2_1(
660*4d7e907cSAndroid Build Coastguard Worker const V2_1::ISoundTriggerHw::SoundModel& soundModel,
661*4d7e907cSAndroid Build Coastguard Worker const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
662*4d7e907cSAndroid Build Coastguard Worker V2_1::ISoundTriggerHw::loadSoundModel_2_1_cb _hidl_cb) {
663*4d7e907cSAndroid Build Coastguard Worker // It is assumed that legacy data vector is empty, thus making copy is cheap.
664*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHw::SoundModel soundModel_2_0(soundModel.header);
665*4d7e907cSAndroid Build Coastguard Worker auto result = memoryAsVector(soundModel.data, &soundModel_2_0.data);
666*4d7e907cSAndroid Build Coastguard Worker if (result.first) {
667*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client =
668*4d7e907cSAndroid Build Coastguard Worker new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
669*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(doLoadSoundModel(soundModel_2_0, client), client->getId());
670*4d7e907cSAndroid Build Coastguard Worker return Void();
671*4d7e907cSAndroid Build Coastguard Worker }
672*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-ENOMEM, 0);
673*4d7e907cSAndroid Build Coastguard Worker return Void();
674*4d7e907cSAndroid Build Coastguard Worker }
675*4d7e907cSAndroid Build Coastguard Worker
loadPhraseSoundModel_2_1(const V2_1::ISoundTriggerHw::PhraseSoundModel & soundModel,const sp<V2_1::ISoundTriggerHwCallback> & callback,int32_t cookie,V2_1::ISoundTriggerHw::loadPhraseSoundModel_2_1_cb _hidl_cb)676*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::loadPhraseSoundModel_2_1(
677*4d7e907cSAndroid Build Coastguard Worker const V2_1::ISoundTriggerHw::PhraseSoundModel& soundModel,
678*4d7e907cSAndroid Build Coastguard Worker const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
679*4d7e907cSAndroid Build Coastguard Worker V2_1::ISoundTriggerHw::loadPhraseSoundModel_2_1_cb _hidl_cb) {
680*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHw::PhraseSoundModel soundModel_2_0;
681*4d7e907cSAndroid Build Coastguard Worker // It is assumed that legacy data vector is empty, thus making copy is cheap.
682*4d7e907cSAndroid Build Coastguard Worker soundModel_2_0.common = soundModel.common.header;
683*4d7e907cSAndroid Build Coastguard Worker // Avoid copying phrases data.
684*4d7e907cSAndroid Build Coastguard Worker soundModel_2_0.phrases.setToExternal(
685*4d7e907cSAndroid Build Coastguard Worker const_cast<V2_0::ISoundTriggerHw::Phrase*>(soundModel.phrases.data()),
686*4d7e907cSAndroid Build Coastguard Worker soundModel.phrases.size());
687*4d7e907cSAndroid Build Coastguard Worker auto result = memoryAsVector(soundModel.common.data, &soundModel_2_0.common.data);
688*4d7e907cSAndroid Build Coastguard Worker if (result.first) {
689*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client =
690*4d7e907cSAndroid Build Coastguard Worker new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
691*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel_2_0, client),
692*4d7e907cSAndroid Build Coastguard Worker client->getId());
693*4d7e907cSAndroid Build Coastguard Worker return Void();
694*4d7e907cSAndroid Build Coastguard Worker }
695*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-ENOMEM, 0);
696*4d7e907cSAndroid Build Coastguard Worker return Void();
697*4d7e907cSAndroid Build Coastguard Worker }
698*4d7e907cSAndroid Build Coastguard Worker
startRecognition_2_1(int32_t modelHandle,const V2_1::ISoundTriggerHw::RecognitionConfig & config,const sp<V2_1::ISoundTriggerHwCallback> & callback,int32_t cookie)699*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::startRecognition_2_1(
700*4d7e907cSAndroid Build Coastguard Worker int32_t modelHandle, const V2_1::ISoundTriggerHw::RecognitionConfig& config,
701*4d7e907cSAndroid Build Coastguard Worker const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie) {
702*4d7e907cSAndroid Build Coastguard Worker // It is assumed that legacy data vector is empty, thus making copy is cheap.
703*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHw::RecognitionConfig config_2_0(config.header);
704*4d7e907cSAndroid Build Coastguard Worker auto result = memoryAsVector(config.data, &config_2_0.data);
705*4d7e907cSAndroid Build Coastguard Worker return result.first ? startRecognition(modelHandle, config_2_0, callback, cookie)
706*4d7e907cSAndroid Build Coastguard Worker : Return<int32_t>(-ENOMEM);
707*4d7e907cSAndroid Build Coastguard Worker }
708*4d7e907cSAndroid Build Coastguard Worker
recognitionCallback(struct sound_trigger_recognition_event * halEvent)709*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::SoundModelClient_2_1::recognitionCallback(
710*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_event* halEvent) {
711*4d7e907cSAndroid Build Coastguard Worker if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
712*4d7e907cSAndroid Build Coastguard Worker V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
713*4d7e907cSAndroid Build Coastguard Worker convertPhaseRecognitionEventFromHal(
714*4d7e907cSAndroid Build Coastguard Worker &event_2_0, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
715*4d7e907cSAndroid Build Coastguard Worker event_2_0.common.model = mId;
716*4d7e907cSAndroid Build Coastguard Worker V2_1::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
717*4d7e907cSAndroid Build Coastguard Worker event.phraseExtras.setToExternal(event_2_0.phraseExtras.data(),
718*4d7e907cSAndroid Build Coastguard Worker event_2_0.phraseExtras.size());
719*4d7e907cSAndroid Build Coastguard Worker auto result = moveVectorToMemory(&event_2_0.common.data, &event.common.data);
720*4d7e907cSAndroid Build Coastguard Worker if (result.first) {
721*4d7e907cSAndroid Build Coastguard Worker // The data vector is now empty, thus copying is cheap.
722*4d7e907cSAndroid Build Coastguard Worker event.common.header = event_2_0.common;
723*4d7e907cSAndroid Build Coastguard Worker mCallback->phraseRecognitionCallback_2_1(event, mCookie);
724*4d7e907cSAndroid Build Coastguard Worker }
725*4d7e907cSAndroid Build Coastguard Worker } else {
726*4d7e907cSAndroid Build Coastguard Worker V2_1::ISoundTriggerHwCallback::RecognitionEvent event;
727*4d7e907cSAndroid Build Coastguard Worker convertRecognitionEventFromHal(&event.header, halEvent);
728*4d7e907cSAndroid Build Coastguard Worker event.header.model = mId;
729*4d7e907cSAndroid Build Coastguard Worker auto result = moveVectorToMemory(&event.header.data, &event.data);
730*4d7e907cSAndroid Build Coastguard Worker if (result.first) {
731*4d7e907cSAndroid Build Coastguard Worker mCallback->recognitionCallback_2_1(event, mCookie);
732*4d7e907cSAndroid Build Coastguard Worker }
733*4d7e907cSAndroid Build Coastguard Worker }
734*4d7e907cSAndroid Build Coastguard Worker }
735*4d7e907cSAndroid Build Coastguard Worker
soundModelCallback(struct sound_trigger_model_event * halEvent)736*4d7e907cSAndroid Build Coastguard Worker void SoundTriggerHw::SoundModelClient_2_1::soundModelCallback(
737*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_model_event* halEvent) {
738*4d7e907cSAndroid Build Coastguard Worker V2_1::ISoundTriggerHwCallback::ModelEvent event;
739*4d7e907cSAndroid Build Coastguard Worker convertSoundModelEventFromHal(&event.header, halEvent);
740*4d7e907cSAndroid Build Coastguard Worker event.header.model = mId;
741*4d7e907cSAndroid Build Coastguard Worker auto result = moveVectorToMemory(&event.header.data, &event.data);
742*4d7e907cSAndroid Build Coastguard Worker if (result.first) {
743*4d7e907cSAndroid Build Coastguard Worker mCallback->soundModelCallback_2_1(event, mCookie);
744*4d7e907cSAndroid Build Coastguard Worker }
745*4d7e907cSAndroid Build Coastguard Worker }
746*4d7e907cSAndroid Build Coastguard Worker
747*4d7e907cSAndroid Build Coastguard Worker // Begin V2_2 implementation, copied from
748*4d7e907cSAndroid Build Coastguard Worker // hardware/interfaces/soundtrigger/2.2/default/SoundTriggerHw.cpp
749*4d7e907cSAndroid Build Coastguard Worker
getModelState(int32_t modelHandle)750*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::getModelState(int32_t modelHandle) {
751*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client;
752*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
753*4d7e907cSAndroid Build Coastguard Worker return -ENODEV;
754*4d7e907cSAndroid Build Coastguard Worker }
755*4d7e907cSAndroid Build Coastguard Worker
756*4d7e907cSAndroid Build Coastguard Worker {
757*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
758*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
759*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
760*4d7e907cSAndroid Build Coastguard Worker return -ENOSYS;
761*4d7e907cSAndroid Build Coastguard Worker }
762*4d7e907cSAndroid Build Coastguard Worker }
763*4d7e907cSAndroid Build Coastguard Worker
764*4d7e907cSAndroid Build Coastguard Worker return mHwDevice->get_model_state(mHwDevice, client->getHalHandle());
765*4d7e907cSAndroid Build Coastguard Worker }
766*4d7e907cSAndroid Build Coastguard Worker
767*4d7e907cSAndroid Build Coastguard Worker // Begin V2_3 implementation
768*4d7e907cSAndroid Build Coastguard Worker
getProperties_2_3(ISoundTriggerHw::getProperties_2_3_cb _hidl_cb)769*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::getProperties_2_3(ISoundTriggerHw::getProperties_2_3_cb _hidl_cb) {
770*4d7e907cSAndroid Build Coastguard Worker ALOGV("getProperties_2_3() mHwDevice %p", mHwDevice);
771*4d7e907cSAndroid Build Coastguard Worker int ret = 0;
772*4d7e907cSAndroid Build Coastguard Worker V2_3::Properties properties;
773*4d7e907cSAndroid Build Coastguard Worker const struct sound_trigger_properties_header* header;
774*4d7e907cSAndroid Build Coastguard Worker
775*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
776*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
777*4d7e907cSAndroid Build Coastguard Worker goto exit;
778*4d7e907cSAndroid Build Coastguard Worker }
779*4d7e907cSAndroid Build Coastguard Worker
780*4d7e907cSAndroid Build Coastguard Worker header = mHwDevice->get_properties_extended(mHwDevice);
781*4d7e907cSAndroid Build Coastguard Worker
782*4d7e907cSAndroid Build Coastguard Worker convertPropertiesFromHal(&properties, header);
783*4d7e907cSAndroid Build Coastguard Worker
784*4d7e907cSAndroid Build Coastguard Worker ALOGV("getProperties_2_3 implementor %s supportedModelArch %s",
785*4d7e907cSAndroid Build Coastguard Worker properties.base.implementor.c_str(), properties.supportedModelArch.c_str());
786*4d7e907cSAndroid Build Coastguard Worker
787*4d7e907cSAndroid Build Coastguard Worker exit:
788*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(ret, properties);
789*4d7e907cSAndroid Build Coastguard Worker return Void();
790*4d7e907cSAndroid Build Coastguard Worker }
791*4d7e907cSAndroid Build Coastguard Worker
startRecognition_2_3(int32_t modelHandle,const V2_3::RecognitionConfig & config)792*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::startRecognition_2_3(int32_t modelHandle,
793*4d7e907cSAndroid Build Coastguard Worker const V2_3::RecognitionConfig& config) {
794*4d7e907cSAndroid Build Coastguard Worker int32_t ret;
795*4d7e907cSAndroid Build Coastguard Worker sp<SoundTriggerHw::SoundModelClient> client;
796*4d7e907cSAndroid Build Coastguard Worker struct sound_trigger_recognition_config_header* header;
797*4d7e907cSAndroid Build Coastguard Worker
798*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
799*4d7e907cSAndroid Build Coastguard Worker ret = -ENODEV;
800*4d7e907cSAndroid Build Coastguard Worker goto exit;
801*4d7e907cSAndroid Build Coastguard Worker }
802*4d7e907cSAndroid Build Coastguard Worker
803*4d7e907cSAndroid Build Coastguard Worker {
804*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
805*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
806*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
807*4d7e907cSAndroid Build Coastguard Worker ret = -ENOSYS;
808*4d7e907cSAndroid Build Coastguard Worker goto exit;
809*4d7e907cSAndroid Build Coastguard Worker }
810*4d7e907cSAndroid Build Coastguard Worker }
811*4d7e907cSAndroid Build Coastguard Worker
812*4d7e907cSAndroid Build Coastguard Worker header = convertRecognitionConfigToHalHeader(&config);
813*4d7e907cSAndroid Build Coastguard Worker
814*4d7e907cSAndroid Build Coastguard Worker if (header == nullptr) {
815*4d7e907cSAndroid Build Coastguard Worker ret = -EINVAL;
816*4d7e907cSAndroid Build Coastguard Worker goto exit;
817*4d7e907cSAndroid Build Coastguard Worker }
818*4d7e907cSAndroid Build Coastguard Worker ret = mHwDevice->start_recognition_extended(mHwDevice, client->getHalHandle(), header,
819*4d7e907cSAndroid Build Coastguard Worker recognitionCallback_, client.get());
820*4d7e907cSAndroid Build Coastguard Worker
821*4d7e907cSAndroid Build Coastguard Worker free(header);
822*4d7e907cSAndroid Build Coastguard Worker
823*4d7e907cSAndroid Build Coastguard Worker exit:
824*4d7e907cSAndroid Build Coastguard Worker return ret;
825*4d7e907cSAndroid Build Coastguard Worker }
826*4d7e907cSAndroid Build Coastguard Worker
setParameter(V2_0::SoundModelHandle modelHandle,ModelParameter modelParam,int32_t value)827*4d7e907cSAndroid Build Coastguard Worker Return<int32_t> SoundTriggerHw::setParameter(V2_0::SoundModelHandle modelHandle,
828*4d7e907cSAndroid Build Coastguard Worker ModelParameter modelParam, int32_t value) {
829*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client;
830*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
831*4d7e907cSAndroid Build Coastguard Worker return -ENODEV;
832*4d7e907cSAndroid Build Coastguard Worker }
833*4d7e907cSAndroid Build Coastguard Worker
834*4d7e907cSAndroid Build Coastguard Worker {
835*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
836*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
837*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
838*4d7e907cSAndroid Build Coastguard Worker return -EINVAL;
839*4d7e907cSAndroid Build Coastguard Worker }
840*4d7e907cSAndroid Build Coastguard Worker }
841*4d7e907cSAndroid Build Coastguard Worker
842*4d7e907cSAndroid Build Coastguard Worker return mHwDevice->set_parameter(mHwDevice, client->getHalHandle(),
843*4d7e907cSAndroid Build Coastguard Worker convertModelParameterToHal(modelParam), value);
844*4d7e907cSAndroid Build Coastguard Worker }
845*4d7e907cSAndroid Build Coastguard Worker
getParameter(V2_0::SoundModelHandle modelHandle,ModelParameter modelParam,getParameter_cb _hidl_cb)846*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::getParameter(V2_0::SoundModelHandle modelHandle,
847*4d7e907cSAndroid Build Coastguard Worker ModelParameter modelParam, getParameter_cb _hidl_cb) {
848*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client;
849*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
850*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-ENODEV, 0);
851*4d7e907cSAndroid Build Coastguard Worker return Void();
852*4d7e907cSAndroid Build Coastguard Worker }
853*4d7e907cSAndroid Build Coastguard Worker
854*4d7e907cSAndroid Build Coastguard Worker {
855*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
856*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
857*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
858*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-EINVAL, 0);
859*4d7e907cSAndroid Build Coastguard Worker return Void();
860*4d7e907cSAndroid Build Coastguard Worker }
861*4d7e907cSAndroid Build Coastguard Worker }
862*4d7e907cSAndroid Build Coastguard Worker
863*4d7e907cSAndroid Build Coastguard Worker int32_t value;
864*4d7e907cSAndroid Build Coastguard Worker int32_t status = mHwDevice->get_parameter(mHwDevice, client->getHalHandle(),
865*4d7e907cSAndroid Build Coastguard Worker convertModelParameterToHal(modelParam), &value);
866*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, value);
867*4d7e907cSAndroid Build Coastguard Worker return Void();
868*4d7e907cSAndroid Build Coastguard Worker }
869*4d7e907cSAndroid Build Coastguard Worker
queryParameter(V2_0::SoundModelHandle modelHandle,ModelParameter modelParam,queryParameter_cb _hidl_cb)870*4d7e907cSAndroid Build Coastguard Worker Return<void> SoundTriggerHw::queryParameter(V2_0::SoundModelHandle modelHandle,
871*4d7e907cSAndroid Build Coastguard Worker ModelParameter modelParam, queryParameter_cb _hidl_cb) {
872*4d7e907cSAndroid Build Coastguard Worker OptionalModelParameterRange optionalParamRange;
873*4d7e907cSAndroid Build Coastguard Worker sp<SoundModelClient> client;
874*4d7e907cSAndroid Build Coastguard Worker if (mHwDevice == NULL) {
875*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-ENODEV, optionalParamRange);
876*4d7e907cSAndroid Build Coastguard Worker return Void();
877*4d7e907cSAndroid Build Coastguard Worker }
878*4d7e907cSAndroid Build Coastguard Worker
879*4d7e907cSAndroid Build Coastguard Worker {
880*4d7e907cSAndroid Build Coastguard Worker AutoMutex lock(mLock);
881*4d7e907cSAndroid Build Coastguard Worker client = mClients.valueFor(modelHandle);
882*4d7e907cSAndroid Build Coastguard Worker if (client == 0) {
883*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(-EINVAL, optionalParamRange);
884*4d7e907cSAndroid Build Coastguard Worker return Void();
885*4d7e907cSAndroid Build Coastguard Worker }
886*4d7e907cSAndroid Build Coastguard Worker }
887*4d7e907cSAndroid Build Coastguard Worker
888*4d7e907cSAndroid Build Coastguard Worker sound_trigger_model_parameter_range_t paramRange;
889*4d7e907cSAndroid Build Coastguard Worker int32_t status = mHwDevice->query_parameter(
890*4d7e907cSAndroid Build Coastguard Worker mHwDevice, client->getHalHandle(), convertModelParameterToHal(modelParam), ¶mRange);
891*4d7e907cSAndroid Build Coastguard Worker
892*4d7e907cSAndroid Build Coastguard Worker if (status == 0 && paramRange.is_supported) {
893*4d7e907cSAndroid Build Coastguard Worker optionalParamRange.range({.start = paramRange.start, .end = paramRange.end});
894*4d7e907cSAndroid Build Coastguard Worker }
895*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, optionalParamRange);
896*4d7e907cSAndroid Build Coastguard Worker return Void();
897*4d7e907cSAndroid Build Coastguard Worker }
898*4d7e907cSAndroid Build Coastguard Worker
899*4d7e907cSAndroid Build Coastguard Worker // static
convertModelParameterToHal(ModelParameter param)900*4d7e907cSAndroid Build Coastguard Worker sound_trigger_model_parameter_t SoundTriggerHw::convertModelParameterToHal(ModelParameter param) {
901*4d7e907cSAndroid Build Coastguard Worker switch (param) {
902*4d7e907cSAndroid Build Coastguard Worker case ModelParameter::THRESHOLD_FACTOR:
903*4d7e907cSAndroid Build Coastguard Worker return MODEL_PARAMETER_THRESHOLD_FACTOR;
904*4d7e907cSAndroid Build Coastguard Worker case ModelParameter::INVALID:
905*4d7e907cSAndroid Build Coastguard Worker default:
906*4d7e907cSAndroid Build Coastguard Worker return MODEL_PARAMETER_INVALID;
907*4d7e907cSAndroid Build Coastguard Worker }
908*4d7e907cSAndroid Build Coastguard Worker }
909*4d7e907cSAndroid Build Coastguard Worker
910*4d7e907cSAndroid Build Coastguard Worker // Methods from ::android::hidl::base::V1_0::IBase follow.
911*4d7e907cSAndroid Build Coastguard Worker
HIDL_FETCH_ISoundTriggerHw(const char *)912*4d7e907cSAndroid Build Coastguard Worker ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* /* name */) {
913*4d7e907cSAndroid Build Coastguard Worker return new SoundTriggerHw();
914*4d7e907cSAndroid Build Coastguard Worker }
915*4d7e907cSAndroid Build Coastguard Worker
916*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation
917*4d7e907cSAndroid Build Coastguard Worker } // namespace V2_3
918*4d7e907cSAndroid Build Coastguard Worker } // namespace soundtrigger
919*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware
920*4d7e907cSAndroid Build Coastguard Worker } // namespace android
921