xref: /aosp_15_r20/hardware/interfaces/soundtrigger/2.3/default/SoundTriggerHw.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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), &paramRange);
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