SoundTriggerHwService.cpp revision 7504b9eb4561df88550f874cf0ce95b6f4d09927
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SoundTriggerHwService"
18//#define LOG_NDEBUG 0
19
20#include <stdio.h>
21#include <string.h>
22#include <sys/types.h>
23#include <pthread.h>
24
25#include <system/sound_trigger.h>
26#include <cutils/atomic.h>
27#include <cutils/properties.h>
28#include <hardware/hardware.h>
29#include <media/AudioSystem.h>
30#include <utils/Errors.h>
31#include <utils/Log.h>
32#include <binder/IServiceManager.h>
33#include <binder/MemoryBase.h>
34#include <binder/MemoryHeapBase.h>
35#include <system/sound_trigger.h>
36#include <ServiceUtilities.h>
37#include "SoundTriggerHwService.h"
38
39#ifdef SOUND_TRIGGER_USE_STUB_MODULE
40#define HW_MODULE_PREFIX "stub"
41#else
42#define HW_MODULE_PREFIX "primary"
43#endif
44namespace android {
45
46SoundTriggerHwService::SoundTriggerHwService()
47    : BnSoundTriggerHwService(),
48      mNextUniqueId(1),
49      mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
50      mCaptureState(false)
51{
52}
53
54void SoundTriggerHwService::onFirstRef()
55{
56    int rc;
57
58    sp<SoundTriggerHalInterface> halInterface =
59            SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
60
61    if (halInterface == 0) {
62        ALOGW("could not connect to HAL");
63        return;
64    }
65    sound_trigger_module_descriptor descriptor;
66    rc = halInterface->getProperties(&descriptor.properties);
67    if (rc != 0) {
68        ALOGE("could not read implementation properties");
69        return;
70    }
71    descriptor.handle =
72            (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
73    ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
74                                                 descriptor.handle);
75
76    sp<Module> module = new Module(this, halInterface, descriptor);
77    mModules.add(descriptor.handle, module);
78    mCallbackThread = new CallbackThread(this);
79}
80
81SoundTriggerHwService::~SoundTriggerHwService()
82{
83    if (mCallbackThread != 0) {
84        mCallbackThread->exit();
85    }
86}
87
88status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
89                             uint32_t *numModules)
90{
91    ALOGV("listModules");
92    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
93                               IPCThreadState::self()->getCallingUid())) {
94        return PERMISSION_DENIED;
95    }
96
97    AutoMutex lock(mServiceLock);
98    if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
99        return BAD_VALUE;
100    }
101    size_t maxModules = *numModules;
102    *numModules = mModules.size();
103    for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
104        modules[i] = mModules.valueAt(i)->descriptor();
105    }
106    return NO_ERROR;
107}
108
109status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
110                        const sp<ISoundTriggerClient>& client,
111                        sp<ISoundTrigger>& moduleInterface)
112{
113    ALOGV("attach module %d", handle);
114    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
115                               IPCThreadState::self()->getCallingUid())) {
116        return PERMISSION_DENIED;
117    }
118
119    AutoMutex lock(mServiceLock);
120    moduleInterface.clear();
121    if (client == 0) {
122        return BAD_VALUE;
123    }
124    ssize_t index = mModules.indexOfKey(handle);
125    if (index < 0) {
126        return BAD_VALUE;
127    }
128    sp<Module> module = mModules.valueAt(index);
129
130    sp<ModuleClient> moduleClient = module->addClient(client);
131    if (moduleClient == 0) {
132        return NO_INIT;
133    }
134
135    moduleClient->setCaptureState_l(mCaptureState);
136    moduleInterface = moduleClient;
137
138    return NO_ERROR;
139}
140
141status_t SoundTriggerHwService::setCaptureState(bool active)
142{
143    ALOGV("setCaptureState %d", active);
144    AutoMutex lock(mServiceLock);
145    mCaptureState = active;
146    for (size_t i = 0; i < mModules.size(); i++) {
147        mModules.valueAt(i)->setCaptureState_l(active);
148    }
149    return NO_ERROR;
150}
151
152
153static const int kDumpLockRetries = 50;
154static const int kDumpLockSleep = 60000;
155
156static bool tryLock(Mutex& mutex)
157{
158    bool locked = false;
159    for (int i = 0; i < kDumpLockRetries; ++i) {
160        if (mutex.tryLock() == NO_ERROR) {
161            locked = true;
162            break;
163        }
164        usleep(kDumpLockSleep);
165    }
166    return locked;
167}
168
169status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
170    String8 result;
171    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
172        result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
173        write(fd, result.string(), result.size());
174    } else {
175        bool locked = tryLock(mServiceLock);
176        // failed to lock - SoundTriggerHwService is probably deadlocked
177        if (!locked) {
178            result.append("SoundTriggerHwService may be deadlocked\n");
179            write(fd, result.string(), result.size());
180        }
181
182        if (locked) mServiceLock.unlock();
183    }
184    return NO_ERROR;
185}
186
187status_t SoundTriggerHwService::onTransact(
188    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
189    return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
190}
191
192
193// static
194void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
195                                                void *cookie)
196{
197    Module *module = (Module *)cookie;
198    if (module == NULL) {
199        return;
200    }
201    sp<SoundTriggerHwService> service = module->service().promote();
202    if (service == 0) {
203        return;
204    }
205
206    service->sendRecognitionEvent(event, module);
207}
208
209sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
210                                                    struct sound_trigger_recognition_event *event)
211{
212    sp<IMemory> eventMemory;
213
214    //sanitize event
215    switch (event->type) {
216    case SOUND_MODEL_TYPE_KEYPHRASE:
217        ALOGW_IF(event->data_size != 0 && event->data_offset !=
218                    sizeof(struct sound_trigger_phrase_recognition_event),
219                    "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
220                    event->data_offset);
221        event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
222        break;
223    case SOUND_MODEL_TYPE_GENERIC:
224        ALOGW_IF(event->data_size != 0 && event->data_offset !=
225                    sizeof(struct sound_trigger_generic_recognition_event),
226                    "prepareRecognitionEvent_l(): invalid data offset %u for generic event type",
227                    event->data_offset);
228        event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
229        break;
230    case SOUND_MODEL_TYPE_UNKNOWN:
231        ALOGW_IF(event->data_size != 0 && event->data_offset !=
232                    sizeof(struct sound_trigger_recognition_event),
233                    "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
234                    event->data_offset);
235        event->data_offset = sizeof(struct sound_trigger_recognition_event);
236        break;
237    default:
238        return eventMemory;
239    }
240
241    size_t size = event->data_offset + event->data_size;
242    eventMemory = mMemoryDealer->allocate(size);
243    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
244        eventMemory.clear();
245        return eventMemory;
246    }
247    memcpy(eventMemory->pointer(), event, size);
248
249    return eventMemory;
250}
251
252void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
253                                                 Module *module)
254 {
255     AutoMutex lock(mServiceLock);
256     if (module == NULL) {
257         return;
258     }
259     sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
260     if (eventMemory == 0) {
261         return;
262     }
263     sp<Module> strongModule;
264     for (size_t i = 0; i < mModules.size(); i++) {
265         if (mModules.valueAt(i).get() == module) {
266             strongModule = mModules.valueAt(i);
267             break;
268         }
269     }
270     if (strongModule == 0) {
271         return;
272     }
273
274    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
275                                                        eventMemory);
276    callbackEvent->setModule(strongModule);
277    sendCallbackEvent_l(callbackEvent);
278}
279
280// static
281void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
282                                               void *cookie)
283{
284    Module *module = (Module *)cookie;
285    if (module == NULL) {
286        return;
287    }
288    sp<SoundTriggerHwService> service = module->service().promote();
289    if (service == 0) {
290        return;
291    }
292
293    service->sendSoundModelEvent(event, module);
294}
295
296sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
297{
298    sp<IMemory> eventMemory;
299
300    size_t size = event->data_offset + event->data_size;
301    eventMemory = mMemoryDealer->allocate(size);
302    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
303        eventMemory.clear();
304        return eventMemory;
305    }
306    memcpy(eventMemory->pointer(), event, size);
307
308    return eventMemory;
309}
310
311void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
312                                                Module *module)
313{
314    AutoMutex lock(mServiceLock);
315    sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
316    if (eventMemory == 0) {
317        return;
318    }
319    sp<Module> strongModule;
320    for (size_t i = 0; i < mModules.size(); i++) {
321        if (mModules.valueAt(i).get() == module) {
322            strongModule = mModules.valueAt(i);
323            break;
324        }
325    }
326    if (strongModule == 0) {
327        return;
328    }
329    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
330                                                        eventMemory);
331    callbackEvent->setModule(strongModule);
332    sendCallbackEvent_l(callbackEvent);
333}
334
335
336sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
337{
338    sp<IMemory> eventMemory;
339
340    size_t size = sizeof(sound_trigger_service_state_t);
341    eventMemory = mMemoryDealer->allocate(size);
342    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
343        eventMemory.clear();
344        return eventMemory;
345    }
346    *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
347    return eventMemory;
348}
349
350// call with mServiceLock held
351void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
352                                                  Module *module)
353{
354    sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
355    if (eventMemory == 0) {
356        return;
357    }
358    sp<Module> strongModule;
359    for (size_t i = 0; i < mModules.size(); i++) {
360        if (mModules.valueAt(i).get() == module) {
361            strongModule = mModules.valueAt(i);
362            break;
363        }
364    }
365    if (strongModule == 0) {
366        return;
367    }
368    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
369                                                        eventMemory);
370    callbackEvent->setModule(strongModule);
371    sendCallbackEvent_l(callbackEvent);
372}
373
374void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
375                                                    ModuleClient *moduleClient)
376{
377    sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
378    if (eventMemory == 0) {
379        return;
380    }
381    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
382                                                        eventMemory);
383    callbackEvent->setModuleClient(moduleClient);
384    sendCallbackEvent_l(callbackEvent);
385}
386
387// call with mServiceLock held
388void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
389{
390    mCallbackThread->sendCallbackEvent(event);
391}
392
393void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
394{
395    ALOGV("onCallbackEvent");
396    sp<Module> module;
397    sp<ModuleClient> moduleClient;
398    {
399        AutoMutex lock(mServiceLock);
400        //CallbackEvent is either for Module or ModuleClient
401        module = event->mModule.promote();
402        if (module == 0) {
403            moduleClient = event->mModuleClient.promote();
404            if (moduleClient == 0) {
405                return;
406            }
407        }
408    }
409    if (module != 0) {
410        ALOGV("onCallbackEvent for module");
411        module->onCallbackEvent(event);
412    } else if (moduleClient != 0) {
413        ALOGV("onCallbackEvent for moduleClient");
414        moduleClient->onCallbackEvent(event);
415    }
416    {
417        AutoMutex lock(mServiceLock);
418        // clear now to execute with mServiceLock locked
419        event->mMemory.clear();
420    }
421}
422
423#undef LOG_TAG
424#define LOG_TAG "SoundTriggerHwService::CallbackThread"
425
426SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
427    : mService(service)
428{
429}
430
431SoundTriggerHwService::CallbackThread::~CallbackThread()
432{
433    while (!mEventQueue.isEmpty()) {
434        mEventQueue[0]->mMemory.clear();
435        mEventQueue.removeAt(0);
436    }
437}
438
439void SoundTriggerHwService::CallbackThread::onFirstRef()
440{
441    run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
442}
443
444bool SoundTriggerHwService::CallbackThread::threadLoop()
445{
446    while (!exitPending()) {
447        sp<CallbackEvent> event;
448        sp<SoundTriggerHwService> service;
449        {
450            Mutex::Autolock _l(mCallbackLock);
451            while (mEventQueue.isEmpty() && !exitPending()) {
452                ALOGV("CallbackThread::threadLoop() sleep");
453                mCallbackCond.wait(mCallbackLock);
454                ALOGV("CallbackThread::threadLoop() wake up");
455            }
456            if (exitPending()) {
457                break;
458            }
459            event = mEventQueue[0];
460            mEventQueue.removeAt(0);
461            service = mService.promote();
462        }
463        if (service != 0) {
464            service->onCallbackEvent(event);
465        }
466    }
467    return false;
468}
469
470void SoundTriggerHwService::CallbackThread::exit()
471{
472    Mutex::Autolock _l(mCallbackLock);
473    requestExit();
474    mCallbackCond.broadcast();
475}
476
477void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
478                        const sp<SoundTriggerHwService::CallbackEvent>& event)
479{
480    AutoMutex lock(mCallbackLock);
481    mEventQueue.add(event);
482    mCallbackCond.signal();
483}
484
485SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
486    : mType(type), mMemory(memory)
487{
488}
489
490SoundTriggerHwService::CallbackEvent::~CallbackEvent()
491{
492}
493
494
495#undef LOG_TAG
496#define LOG_TAG "SoundTriggerHwService::Module"
497
498SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
499                                      const sp<SoundTriggerHalInterface>& halInterface,
500                                      sound_trigger_module_descriptor descriptor)
501 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
502   mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
503{
504}
505
506SoundTriggerHwService::Module::~Module() {
507    mModuleClients.clear();
508}
509
510sp<SoundTriggerHwService::ModuleClient>
511SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
512{
513    AutoMutex lock(mLock);
514    sp<ModuleClient> moduleClient;
515
516    for (size_t i = 0; i < mModuleClients.size(); i++) {
517        if (mModuleClients[i]->client() == client) {
518            // Client already present, reuse client
519            return moduleClient;
520        }
521    }
522    moduleClient = new ModuleClient(this, client);
523
524    ALOGV("addClient() client %p", moduleClient.get());
525    mModuleClients.add(moduleClient);
526
527    return moduleClient;
528}
529
530void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
531{
532    ALOGV("Module::detach()");
533    AutoMutex lock(mLock);
534    ssize_t index = -1;
535
536    for (size_t i = 0; i < mModuleClients.size(); i++) {
537        if (mModuleClients[i] == moduleClient) {
538            index = i;
539            break;
540        }
541    }
542    if (index == -1) {
543        return;
544    }
545
546    ALOGV("remove client %p", moduleClient.get());
547    mModuleClients.removeAt(index);
548
549    // Iterate in reverse order as models are removed from list inside the loop.
550    for (size_t i = mModels.size(); i > 0; i--) {
551        sp<Model> model = mModels.valueAt(i - 1);
552        if (moduleClient == model->mModuleClient) {
553            mModels.removeItemsAt(i - 1);
554            ALOGV("detach() unloading model %d", model->mHandle);
555            if (mHalInterface != 0) {
556                if (model->mState == Model::STATE_ACTIVE) {
557                    mHalInterface->stopRecognition(model->mHandle);
558                }
559                mHalInterface->unloadSoundModel(model->mHandle);
560            }
561            AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
562            mHalInterface->unloadSoundModel(model->mHandle);
563        }
564    }
565}
566
567status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
568                                                       sp<ModuleClient> moduleClient,
569                                                       sound_model_handle_t *handle)
570{
571    ALOGV("loadSoundModel() handle");
572    if (mHalInterface == 0) {
573        return NO_INIT;
574    }
575    if (modelMemory == 0 || modelMemory->pointer() == NULL) {
576        ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
577        return BAD_VALUE;
578    }
579    struct sound_trigger_sound_model *sound_model =
580            (struct sound_trigger_sound_model *)modelMemory->pointer();
581
582    size_t structSize;
583    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
584        structSize = sizeof(struct sound_trigger_phrase_sound_model);
585    } else {
586        structSize = sizeof(struct sound_trigger_sound_model);
587    }
588
589    if (sound_model->data_offset < structSize ||
590           sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
591           modelMemory->size() < sound_model->data_offset ||
592           sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
593        android_errorWriteLog(0x534e4554, "30148546");
594        ALOGE("loadSoundModel() data_size is too big");
595        return BAD_VALUE;
596    }
597
598    AutoMutex lock(mLock);
599
600    if (mModels.size() >= mDescriptor.properties.max_sound_models) {
601        ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
602              mDescriptor.properties.max_sound_models);
603        return INVALID_OPERATION;
604    }
605
606    status_t status = mHalInterface->loadSoundModel(sound_model,
607                                                  SoundTriggerHwService::soundModelCallback,
608                                                  this, handle);
609
610    if (status != NO_ERROR) {
611        return status;
612    }
613    audio_session_t session;
614    audio_io_handle_t ioHandle;
615    audio_devices_t device;
616
617    status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
618    if (status != NO_ERROR) {
619        return status;
620    }
621
622    sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
623                                moduleClient);
624    mModels.replaceValueFor(*handle, model);
625
626    return status;
627}
628
629status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
630{
631    ALOGV("unloadSoundModel() model handle %d", handle);
632    AutoMutex lock(mLock);
633    return unloadSoundModel_l(handle);
634}
635
636status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
637{
638    if (mHalInterface == 0) {
639        return NO_INIT;
640    }
641    ssize_t index = mModels.indexOfKey(handle);
642    if (index < 0) {
643        return BAD_VALUE;
644    }
645    sp<Model> model = mModels.valueAt(index);
646    mModels.removeItem(handle);
647    if (model->mState == Model::STATE_ACTIVE) {
648        mHalInterface->stopRecognition(model->mHandle);
649        model->mState = Model::STATE_IDLE;
650    }
651    AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
652    return mHalInterface->unloadSoundModel(handle);
653}
654
655status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
656                                 const sp<IMemory>& dataMemory)
657{
658    ALOGV("startRecognition() model handle %d", handle);
659    if (mHalInterface == 0) {
660        return NO_INIT;
661    }
662    if (dataMemory == 0 || dataMemory->pointer() == NULL) {
663        ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
664        return BAD_VALUE;
665
666    }
667
668    struct sound_trigger_recognition_config *config =
669            (struct sound_trigger_recognition_config *)dataMemory->pointer();
670
671    if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
672            config->data_size > (UINT_MAX - config->data_offset) ||
673            dataMemory->size() < config->data_offset ||
674            config->data_size > (dataMemory->size() - config->data_offset)) {
675        ALOGE("startRecognition() data_size is too big");
676        return BAD_VALUE;
677    }
678
679    AutoMutex lock(mLock);
680    if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
681        return INVALID_OPERATION;
682    }
683    sp<Model> model = getModel(handle);
684    if (model == 0) {
685        return BAD_VALUE;
686    }
687
688    if (model->mState == Model::STATE_ACTIVE) {
689        return INVALID_OPERATION;
690    }
691
692
693    //TODO: get capture handle and device from audio policy service
694    config->capture_handle = model->mCaptureIOHandle;
695    config->capture_device = model->mCaptureDevice;
696    status_t status = mHalInterface->startRecognition(handle, config,
697                                        SoundTriggerHwService::recognitionCallback,
698                                        this);
699
700    if (status == NO_ERROR) {
701        model->mState = Model::STATE_ACTIVE;
702        model->mConfig = *config;
703    }
704
705    return status;
706}
707
708status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
709{
710    ALOGV("stopRecognition() model handle %d", handle);
711    if (mHalInterface == 0) {
712        return NO_INIT;
713    }
714    AutoMutex lock(mLock);
715    sp<Model> model = getModel(handle);
716    if (model == 0) {
717        return BAD_VALUE;
718    }
719
720    if (model->mState != Model::STATE_ACTIVE) {
721        return INVALID_OPERATION;
722    }
723    mHalInterface->stopRecognition(handle);
724    model->mState = Model::STATE_IDLE;
725    return NO_ERROR;
726}
727
728void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
729{
730    ALOGV("onCallbackEvent type %d", event->mType);
731
732    sp<IMemory> eventMemory = event->mMemory;
733
734    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
735        return;
736    }
737    if (mModuleClients.isEmpty()) {
738        ALOGI("%s no clients", __func__);
739        return;
740    }
741
742    switch (event->mType) {
743    case CallbackEvent::TYPE_RECOGNITION: {
744        struct sound_trigger_recognition_event *recognitionEvent =
745                (struct sound_trigger_recognition_event *)eventMemory->pointer();
746        sp<ISoundTriggerClient> client;
747        {
748            AutoMutex lock(mLock);
749            sp<Model> model = getModel(recognitionEvent->model);
750            if (model == 0) {
751                ALOGW("%s model == 0", __func__);
752                return;
753            }
754            if (model->mState != Model::STATE_ACTIVE) {
755                ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
756                return;
757            }
758
759            recognitionEvent->capture_session = model->mCaptureSession;
760            model->mState = Model::STATE_IDLE;
761            client = model->mModuleClient->client();
762        }
763        if (client != 0) {
764            client->onRecognitionEvent(eventMemory);
765        }
766    } break;
767    case CallbackEvent::TYPE_SOUNDMODEL: {
768        struct sound_trigger_model_event *soundmodelEvent =
769                (struct sound_trigger_model_event *)eventMemory->pointer();
770        sp<ISoundTriggerClient> client;
771        {
772            AutoMutex lock(mLock);
773            sp<Model> model = getModel(soundmodelEvent->model);
774            if (model == 0) {
775                ALOGW("%s model == 0", __func__);
776                return;
777            }
778            client = model->mModuleClient->client();
779        }
780        if (client != 0) {
781            client->onSoundModelEvent(eventMemory);
782        }
783    } break;
784    case CallbackEvent::TYPE_SERVICE_STATE: {
785        Vector< sp<ISoundTriggerClient> > clients;
786        {
787            AutoMutex lock(mLock);
788            for (size_t i = 0; i < mModuleClients.size(); i++) {
789                if (mModuleClients[i] != 0) {
790                    clients.add(mModuleClients[i]->client());
791                }
792            }
793        }
794        for (size_t i = 0; i < clients.size(); i++) {
795            clients[i]->onServiceStateChange(eventMemory);
796        }
797    } break;
798    default:
799        LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
800    }
801}
802
803sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
804        sound_model_handle_t handle)
805{
806    sp<Model> model;
807    ssize_t index = mModels.indexOfKey(handle);
808    if (index >= 0) {
809        model = mModels.valueAt(index);
810    }
811    return model;
812}
813
814// Called with mServiceLock held
815void SoundTriggerHwService::Module::setCaptureState_l(bool active)
816{
817    ALOGV("Module::setCaptureState_l %d", active);
818    sp<SoundTriggerHwService> service;
819    sound_trigger_service_state_t state;
820
821    Vector< sp<IMemory> > events;
822    {
823        AutoMutex lock(mLock);
824        state = (active && !mDescriptor.properties.concurrent_capture) ?
825                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
826
827        if (state == mServiceState) {
828            return;
829        }
830
831        mServiceState = state;
832
833        service = mService.promote();
834        if (service == 0) {
835            return;
836        }
837
838        if (state == SOUND_TRIGGER_STATE_ENABLED) {
839            goto exit;
840        }
841
842        const bool supports_stop_all =
843                (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() == ENOSYS);
844
845        for (size_t i = 0; i < mModels.size(); i++) {
846            sp<Model> model = mModels.valueAt(i);
847            if (model->mState == Model::STATE_ACTIVE) {
848                if (mHalInterface != 0 && !supports_stop_all) {
849                    mHalInterface->stopRecognition(model->mHandle);
850                }
851                // keep model in ACTIVE state so that event is processed by onCallbackEvent()
852                if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
853                    struct sound_trigger_phrase_recognition_event event;
854                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
855                    event.num_phrases = model->mConfig.num_phrases;
856                    for (size_t i = 0; i < event.num_phrases; i++) {
857                        event.phrase_extras[i] = model->mConfig.phrases[i];
858                    }
859                    event.common.status = RECOGNITION_STATUS_ABORT;
860                    event.common.type = model->mType;
861                    event.common.model = model->mHandle;
862                    event.common.data_size = 0;
863                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
864                    if (eventMemory != 0) {
865                        events.add(eventMemory);
866                    }
867                } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
868                    struct sound_trigger_generic_recognition_event event;
869                    memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
870                    event.common.status = RECOGNITION_STATUS_ABORT;
871                    event.common.type = model->mType;
872                    event.common.model = model->mHandle;
873                    event.common.data_size = 0;
874                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
875                    if (eventMemory != 0) {
876                        events.add(eventMemory);
877                    }
878                } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
879                    struct sound_trigger_phrase_recognition_event event;
880                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
881                    event.common.status = RECOGNITION_STATUS_ABORT;
882                    event.common.type = model->mType;
883                    event.common.model = model->mHandle;
884                    event.common.data_size = 0;
885                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
886                    if (eventMemory != 0) {
887                        events.add(eventMemory);
888                    }
889                } else {
890                    goto exit;
891                }
892            }
893        }
894    }
895
896    for (size_t i = 0; i < events.size(); i++) {
897        sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
898                                                            events[i]);
899        callbackEvent->setModule(this);
900        service->sendCallbackEvent_l(callbackEvent);
901    }
902
903exit:
904    service->sendServiceStateEvent_l(state, this);
905}
906
907
908SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
909                                    audio_io_handle_t ioHandle, audio_devices_t device,
910                                    sound_trigger_sound_model_type_t type,
911                                    sp<ModuleClient>& moduleClient) :
912    mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
913    mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
914    mModuleClient(moduleClient)
915{
916}
917
918#undef LOG_TAG
919#define LOG_TAG "SoundTriggerHwService::ModuleClient"
920
921SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
922                                                  const sp<ISoundTriggerClient>& client)
923 : mModule(module), mClient(client)
924{
925}
926
927void SoundTriggerHwService::ModuleClient::onFirstRef()
928{
929    sp<IBinder> binder = IInterface::asBinder(mClient);
930    if (binder != 0) {
931        binder->linkToDeath(this);
932    }
933}
934
935SoundTriggerHwService::ModuleClient::~ModuleClient()
936{
937}
938
939status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
940                                                   const Vector<String16>& args __unused) {
941    String8 result;
942    return NO_ERROR;
943}
944
945void SoundTriggerHwService::ModuleClient::detach() {
946    ALOGV("detach()");
947    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
948                               IPCThreadState::self()->getCallingUid())) {
949        return;
950    }
951
952    {
953        AutoMutex lock(mLock);
954        if (mClient != 0) {
955            IInterface::asBinder(mClient)->unlinkToDeath(this);
956            mClient.clear();
957        }
958    }
959
960    sp<Module> module = mModule.promote();
961    if (module == 0) {
962        return;
963    }
964    module->detach(this);
965}
966
967status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
968                                sound_model_handle_t *handle)
969{
970    ALOGV("loadSoundModel() handle");
971    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
972                               IPCThreadState::self()->getCallingUid())) {
973        return PERMISSION_DENIED;
974    }
975
976    sp<Module> module = mModule.promote();
977    if (module == 0) {
978        return NO_INIT;
979    }
980    return module->loadSoundModel(modelMemory, this, handle);
981}
982
983status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
984{
985    ALOGV("unloadSoundModel() model handle %d", handle);
986    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
987                               IPCThreadState::self()->getCallingUid())) {
988        return PERMISSION_DENIED;
989    }
990
991    sp<Module> module = mModule.promote();
992    if (module == 0) {
993        return NO_INIT;
994    }
995    return module->unloadSoundModel(handle);
996}
997
998status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
999                                 const sp<IMemory>& dataMemory)
1000{
1001    ALOGV("startRecognition() model handle %d", handle);
1002    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1003                               IPCThreadState::self()->getCallingUid())) {
1004        return PERMISSION_DENIED;
1005    }
1006
1007    sp<Module> module = mModule.promote();
1008    if (module == 0) {
1009        return NO_INIT;
1010    }
1011    return module->startRecognition(handle, dataMemory);
1012}
1013
1014status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1015{
1016    ALOGV("stopRecognition() model handle %d", handle);
1017    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1018                               IPCThreadState::self()->getCallingUid())) {
1019        return PERMISSION_DENIED;
1020    }
1021
1022    sp<Module> module = mModule.promote();
1023    if (module == 0) {
1024        return NO_INIT;
1025    }
1026    return module->stopRecognition(handle);
1027}
1028
1029void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1030{
1031    ALOGV("ModuleClient::setCaptureState_l %d", active);
1032    sp<SoundTriggerHwService> service;
1033    sound_trigger_service_state_t state;
1034
1035    sp<Module> module = mModule.promote();
1036    if (module == 0) {
1037        return;
1038    }
1039    {
1040        AutoMutex lock(mLock);
1041        state = (active && !module->isConcurrentCaptureAllowed()) ?
1042                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1043
1044        service = module->service().promote();
1045        if (service == 0) {
1046            return;
1047        }
1048    }
1049    service->sendServiceStateEvent_l(state, this);
1050}
1051
1052void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1053{
1054    ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1055
1056    sp<IMemory> eventMemory = event->mMemory;
1057
1058    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1059        return;
1060    }
1061
1062    switch (event->mType) {
1063    case CallbackEvent::TYPE_SERVICE_STATE: {
1064        sp<ISoundTriggerClient> client;
1065        {
1066            AutoMutex lock(mLock);
1067            client = mClient;
1068        }
1069        if (client !=0 ) {
1070            client->onServiceStateChange(eventMemory);
1071        }
1072    } break;
1073    default:
1074        LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1075    }
1076}
1077
1078void SoundTriggerHwService::ModuleClient::binderDied(
1079    const wp<IBinder> &who __unused) {
1080    ALOGW("client binder died for client %p", this);
1081    detach();
1082}
1083
1084}; // namespace android
1085