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(
210                                                    struct sound_trigger_recognition_event *event)
211{
212    AutoMutex lock(mMemoryDealerLock);
213    sp<IMemory> eventMemory;
214
215    //sanitize event
216    switch (event->type) {
217    case SOUND_MODEL_TYPE_KEYPHRASE:
218        ALOGW_IF(event->data_size != 0 && event->data_offset !=
219                    sizeof(struct sound_trigger_phrase_recognition_event),
220                    "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
221                    event->data_offset);
222        event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
223        break;
224    case SOUND_MODEL_TYPE_GENERIC:
225        ALOGW_IF(event->data_size != 0 && event->data_offset !=
226                    sizeof(struct sound_trigger_generic_recognition_event),
227                    "prepareRecognitionEvent(): invalid data offset %u for generic event type",
228                    event->data_offset);
229        event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
230        break;
231    case SOUND_MODEL_TYPE_UNKNOWN:
232        ALOGW_IF(event->data_size != 0 && event->data_offset !=
233                    sizeof(struct sound_trigger_recognition_event),
234                    "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
235                    event->data_offset);
236        event->data_offset = sizeof(struct sound_trigger_recognition_event);
237        break;
238    default:
239        return eventMemory;
240    }
241
242    size_t size = event->data_offset + event->data_size;
243    eventMemory = mMemoryDealer->allocate(size);
244    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
245        eventMemory.clear();
246        return eventMemory;
247    }
248    memcpy(eventMemory->pointer(), event, size);
249
250    return eventMemory;
251}
252
253void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
254                                                 Module *module)
255{
256    if (module == NULL) {
257        return;
258    }
259    sp<IMemory> eventMemory = prepareRecognitionEvent(event);
260    if (eventMemory == 0) {
261        return;
262    }
263
264    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
265                                                        eventMemory);
266    callbackEvent->setModule(module);
267    sendCallbackEvent(callbackEvent);
268}
269
270// static
271void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
272                                               void *cookie)
273{
274    Module *module = (Module *)cookie;
275    if (module == NULL) {
276        return;
277    }
278    sp<SoundTriggerHwService> service = module->service().promote();
279    if (service == 0) {
280        return;
281    }
282
283    service->sendSoundModelEvent(event, module);
284}
285
286sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
287{
288    AutoMutex lock(mMemoryDealerLock);
289    sp<IMemory> eventMemory;
290
291    size_t size = event->data_offset + event->data_size;
292    eventMemory = mMemoryDealer->allocate(size);
293    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
294        eventMemory.clear();
295        return eventMemory;
296    }
297    memcpy(eventMemory->pointer(), event, size);
298
299    return eventMemory;
300}
301
302void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
303                                                Module *module)
304{
305    sp<IMemory> eventMemory = prepareSoundModelEvent(event);
306    if (eventMemory == 0) {
307        return;
308    }
309    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
310                                                        eventMemory);
311    callbackEvent->setModule(module);
312    sendCallbackEvent(callbackEvent);
313}
314
315
316sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
317{
318    AutoMutex lock(mMemoryDealerLock);
319    sp<IMemory> eventMemory;
320
321    size_t size = sizeof(sound_trigger_service_state_t);
322    eventMemory = mMemoryDealer->allocate(size);
323    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
324        eventMemory.clear();
325        return eventMemory;
326    }
327    *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
328    return eventMemory;
329}
330
331void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
332                                                  Module *module)
333{
334    sp<IMemory> eventMemory = prepareServiceStateEvent(state);
335    if (eventMemory == 0) {
336        return;
337    }
338    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
339                                                        eventMemory);
340    callbackEvent->setModule(module);
341    sendCallbackEvent(callbackEvent);
342}
343
344void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
345                                                  ModuleClient *moduleClient)
346{
347    sp<IMemory> eventMemory = prepareServiceStateEvent(state);
348    if (eventMemory == 0) {
349        return;
350    }
351    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
352                                                        eventMemory);
353    callbackEvent->setModuleClient(moduleClient);
354    sendCallbackEvent(callbackEvent);
355}
356
357void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
358{
359    mCallbackThread->sendCallbackEvent(event);
360}
361
362void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
363{
364    ALOGV("onCallbackEvent");
365    sp<Module> module;
366    sp<ModuleClient> moduleClient;
367    {
368        AutoMutex lock(mServiceLock);
369        //CallbackEvent is either for Module or ModuleClient
370        module = event->mModule.promote();
371        if (module == 0) {
372            moduleClient = event->mModuleClient.promote();
373            if (moduleClient == 0) {
374                return;
375            }
376        } else {
377            // Sanity check on this being a Module we know about.
378            bool foundModule = false;
379            for (size_t i = 0; i < mModules.size(); i++) {
380                if (mModules.valueAt(i).get() == module.get()) {
381                    foundModule = true;
382                    break;
383                }
384            }
385            if (!foundModule) {
386                ALOGE("onCallbackEvent for unknown module");
387                return;
388            }
389        }
390    }
391    if (module != 0) {
392        ALOGV("onCallbackEvent for module");
393        module->onCallbackEvent(event);
394    } else if (moduleClient != 0) {
395        ALOGV("onCallbackEvent for moduleClient");
396        moduleClient->onCallbackEvent(event);
397    }
398    {
399        AutoMutex lock(mServiceLock);
400        // clear now to execute with mServiceLock locked
401        event->mMemory.clear();
402    }
403}
404
405#undef LOG_TAG
406#define LOG_TAG "SoundTriggerHwService::CallbackThread"
407
408SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
409    : mService(service)
410{
411}
412
413SoundTriggerHwService::CallbackThread::~CallbackThread()
414{
415    while (!mEventQueue.isEmpty()) {
416        mEventQueue[0]->mMemory.clear();
417        mEventQueue.removeAt(0);
418    }
419}
420
421void SoundTriggerHwService::CallbackThread::onFirstRef()
422{
423    run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
424}
425
426bool SoundTriggerHwService::CallbackThread::threadLoop()
427{
428    while (!exitPending()) {
429        sp<CallbackEvent> event;
430        sp<SoundTriggerHwService> service;
431        {
432            Mutex::Autolock _l(mCallbackLock);
433            while (mEventQueue.isEmpty() && !exitPending()) {
434                ALOGV("CallbackThread::threadLoop() sleep");
435                mCallbackCond.wait(mCallbackLock);
436                ALOGV("CallbackThread::threadLoop() wake up");
437            }
438            if (exitPending()) {
439                break;
440            }
441            event = mEventQueue[0];
442            mEventQueue.removeAt(0);
443            service = mService.promote();
444        }
445        if (service != 0) {
446            service->onCallbackEvent(event);
447        }
448    }
449    return false;
450}
451
452void SoundTriggerHwService::CallbackThread::exit()
453{
454    Mutex::Autolock _l(mCallbackLock);
455    requestExit();
456    mCallbackCond.broadcast();
457}
458
459void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
460                        const sp<SoundTriggerHwService::CallbackEvent>& event)
461{
462    AutoMutex lock(mCallbackLock);
463    mEventQueue.add(event);
464    mCallbackCond.signal();
465}
466
467SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
468    : mType(type), mMemory(memory)
469{
470}
471
472SoundTriggerHwService::CallbackEvent::~CallbackEvent()
473{
474}
475
476
477#undef LOG_TAG
478#define LOG_TAG "SoundTriggerHwService::Module"
479
480SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
481                                      const sp<SoundTriggerHalInterface>& halInterface,
482                                      sound_trigger_module_descriptor descriptor)
483 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
484   mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
485{
486}
487
488SoundTriggerHwService::Module::~Module() {
489    mModuleClients.clear();
490}
491
492sp<SoundTriggerHwService::ModuleClient>
493SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
494{
495    AutoMutex lock(mLock);
496    sp<ModuleClient> moduleClient;
497
498    for (size_t i = 0; i < mModuleClients.size(); i++) {
499        if (mModuleClients[i]->client() == client) {
500            // Client already present, reuse client
501            return moduleClient;
502        }
503    }
504    moduleClient = new ModuleClient(this, client);
505
506    ALOGV("addClient() client %p", moduleClient.get());
507    mModuleClients.add(moduleClient);
508
509    return moduleClient;
510}
511
512void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
513{
514    ALOGV("Module::detach()");
515    Vector<audio_session_t> releasedSessions;
516
517    {
518        AutoMutex lock(mLock);
519        ssize_t index = -1;
520
521        for (size_t i = 0; i < mModuleClients.size(); i++) {
522            if (mModuleClients[i] == moduleClient) {
523                index = i;
524                break;
525            }
526        }
527        if (index == -1) {
528            return;
529        }
530
531        ALOGV("remove client %p", moduleClient.get());
532        mModuleClients.removeAt(index);
533
534        // Iterate in reverse order as models are removed from list inside the loop.
535        for (size_t i = mModels.size(); i > 0; i--) {
536            sp<Model> model = mModels.valueAt(i - 1);
537            if (moduleClient == model->mModuleClient) {
538                mModels.removeItemsAt(i - 1);
539                ALOGV("detach() unloading model %d", model->mHandle);
540                if (mHalInterface != 0) {
541                    if (model->mState == Model::STATE_ACTIVE) {
542                        mHalInterface->stopRecognition(model->mHandle);
543                    }
544                    mHalInterface->unloadSoundModel(model->mHandle);
545                }
546                releasedSessions.add(model->mCaptureSession);
547            }
548        }
549    }
550
551    for (size_t i = 0; i < releasedSessions.size(); i++) {
552        // do not call AudioSystem methods with mLock held
553        AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
554    }
555}
556
557status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
558                                                       sp<ModuleClient> moduleClient,
559                                                       sound_model_handle_t *handle)
560{
561    ALOGV("loadSoundModel() handle");
562    if (mHalInterface == 0) {
563        return NO_INIT;
564    }
565    if (modelMemory == 0 || modelMemory->pointer() == NULL) {
566        ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
567        return BAD_VALUE;
568    }
569    struct sound_trigger_sound_model *sound_model =
570            (struct sound_trigger_sound_model *)modelMemory->pointer();
571
572    size_t structSize;
573    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
574        structSize = sizeof(struct sound_trigger_phrase_sound_model);
575    } else {
576        structSize = sizeof(struct sound_trigger_sound_model);
577    }
578
579    if (sound_model->data_offset < structSize ||
580           sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
581           modelMemory->size() < sound_model->data_offset ||
582           sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
583        android_errorWriteLog(0x534e4554, "30148546");
584        ALOGE("loadSoundModel() data_size is too big");
585        return BAD_VALUE;
586    }
587
588    audio_session_t session;
589    audio_io_handle_t ioHandle;
590    audio_devices_t device;
591    // do not call AudioSystem methods with mLock held
592    status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
593    if (status != NO_ERROR) {
594        return status;
595    }
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            status = INVALID_OPERATION;
604            goto exit;
605        }
606
607        status = mHalInterface->loadSoundModel(sound_model,
608                                                      SoundTriggerHwService::soundModelCallback,
609                                                      this, handle);
610        if (status != NO_ERROR) {
611            goto exit;
612        }
613
614        sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
615                                    moduleClient);
616        mModels.replaceValueFor(*handle, model);
617    }
618exit:
619    if (status != NO_ERROR) {
620        // do not call AudioSystem methods with mLock held
621        AudioSystem::releaseSoundTriggerSession(session);
622    }
623    return status;
624}
625
626status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
627{
628    ALOGV("unloadSoundModel() model handle %d", handle);
629    status_t status;
630    audio_session_t session;
631
632    {
633        AutoMutex lock(mLock);
634        if (mHalInterface == 0) {
635            return NO_INIT;
636        }
637        ssize_t index = mModels.indexOfKey(handle);
638        if (index < 0) {
639            return BAD_VALUE;
640        }
641        sp<Model> model = mModels.valueAt(index);
642        mModels.removeItem(handle);
643        if (model->mState == Model::STATE_ACTIVE) {
644            mHalInterface->stopRecognition(model->mHandle);
645            model->mState = Model::STATE_IDLE;
646        }
647        status = mHalInterface->unloadSoundModel(handle);
648        session = model->mCaptureSession;
649    }
650    // do not call AudioSystem methods with mLock held
651    AudioSystem::releaseSoundTriggerSession(session);
652    return status;
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    Vector< sp<ModuleClient> > clients;
743
744    switch (event->mType) {
745    case CallbackEvent::TYPE_RECOGNITION: {
746        struct sound_trigger_recognition_event *recognitionEvent =
747                (struct sound_trigger_recognition_event *)eventMemory->pointer();
748        {
749            AutoMutex lock(mLock);
750            sp<Model> model = getModel(recognitionEvent->model);
751            if (model == 0) {
752                ALOGW("%s model == 0", __func__);
753                return;
754            }
755            if (model->mState != Model::STATE_ACTIVE) {
756                ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
757                return;
758            }
759
760            recognitionEvent->capture_session = model->mCaptureSession;
761            model->mState = Model::STATE_IDLE;
762            clients.add(model->mModuleClient);
763        }
764    } break;
765    case CallbackEvent::TYPE_SOUNDMODEL: {
766        struct sound_trigger_model_event *soundmodelEvent =
767                (struct sound_trigger_model_event *)eventMemory->pointer();
768        {
769            AutoMutex lock(mLock);
770            sp<Model> model = getModel(soundmodelEvent->model);
771            if (model == 0) {
772                ALOGW("%s model == 0", __func__);
773                return;
774            }
775            clients.add(model->mModuleClient);
776        }
777    } break;
778    case CallbackEvent::TYPE_SERVICE_STATE: {
779        {
780            AutoMutex lock(mLock);
781            for (size_t i = 0; i < mModuleClients.size(); i++) {
782                if (mModuleClients[i] != 0) {
783                    clients.add(mModuleClients[i]);
784                }
785            }
786        }
787    } break;
788    default:
789        LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
790    }
791
792    for (size_t i = 0; i < clients.size(); i++) {
793        clients[i]->onCallbackEvent(event);
794    }
795}
796
797sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
798        sound_model_handle_t handle)
799{
800    sp<Model> model;
801    ssize_t index = mModels.indexOfKey(handle);
802    if (index >= 0) {
803        model = mModels.valueAt(index);
804    }
805    return model;
806}
807
808// Called with mServiceLock held
809void SoundTriggerHwService::Module::setCaptureState_l(bool active)
810{
811    ALOGV("Module::setCaptureState_l %d", active);
812    sp<SoundTriggerHwService> service;
813    sound_trigger_service_state_t state;
814
815    Vector< sp<IMemory> > events;
816    {
817        AutoMutex lock(mLock);
818        state = (active && !mDescriptor.properties.concurrent_capture) ?
819                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
820
821        if (state == mServiceState) {
822            return;
823        }
824
825        mServiceState = state;
826
827        service = mService.promote();
828        if (service == 0) {
829            return;
830        }
831
832        if (state == SOUND_TRIGGER_STATE_ENABLED) {
833            goto exit;
834        }
835
836        const bool supports_stop_all =
837                (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
838
839        for (size_t i = 0; i < mModels.size(); i++) {
840            sp<Model> model = mModels.valueAt(i);
841            if (model->mState == Model::STATE_ACTIVE) {
842                if (mHalInterface != 0 && !supports_stop_all) {
843                    mHalInterface->stopRecognition(model->mHandle);
844                }
845                // keep model in ACTIVE state so that event is processed by onCallbackEvent()
846                if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
847                    struct sound_trigger_phrase_recognition_event event;
848                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
849                    event.num_phrases = model->mConfig.num_phrases;
850                    for (size_t i = 0; i < event.num_phrases; i++) {
851                        event.phrase_extras[i] = model->mConfig.phrases[i];
852                    }
853                    event.common.status = RECOGNITION_STATUS_ABORT;
854                    event.common.type = model->mType;
855                    event.common.model = model->mHandle;
856                    event.common.data_size = 0;
857                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
858                    if (eventMemory != 0) {
859                        events.add(eventMemory);
860                    }
861                } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
862                    struct sound_trigger_generic_recognition_event event;
863                    memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
864                    event.common.status = RECOGNITION_STATUS_ABORT;
865                    event.common.type = model->mType;
866                    event.common.model = model->mHandle;
867                    event.common.data_size = 0;
868                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
869                    if (eventMemory != 0) {
870                        events.add(eventMemory);
871                    }
872                } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
873                    struct sound_trigger_phrase_recognition_event event;
874                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
875                    event.common.status = RECOGNITION_STATUS_ABORT;
876                    event.common.type = model->mType;
877                    event.common.model = model->mHandle;
878                    event.common.data_size = 0;
879                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
880                    if (eventMemory != 0) {
881                        events.add(eventMemory);
882                    }
883                } else {
884                    goto exit;
885                }
886            }
887        }
888    }
889
890    for (size_t i = 0; i < events.size(); i++) {
891        sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
892                                                            events[i]);
893        callbackEvent->setModule(this);
894        service->sendCallbackEvent(callbackEvent);
895    }
896
897exit:
898    service->sendServiceStateEvent(state, this);
899}
900
901
902SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
903                                    audio_io_handle_t ioHandle, audio_devices_t device,
904                                    sound_trigger_sound_model_type_t type,
905                                    sp<ModuleClient>& moduleClient) :
906    mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
907    mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
908    mModuleClient(moduleClient)
909{
910}
911
912#undef LOG_TAG
913#define LOG_TAG "SoundTriggerHwService::ModuleClient"
914
915SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
916                                                  const sp<ISoundTriggerClient>& client)
917 : mModule(module), mClient(client)
918{
919}
920
921void SoundTriggerHwService::ModuleClient::onFirstRef()
922{
923    sp<IBinder> binder = IInterface::asBinder(mClient);
924    if (binder != 0) {
925        binder->linkToDeath(this);
926    }
927}
928
929SoundTriggerHwService::ModuleClient::~ModuleClient()
930{
931}
932
933status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
934                                                   const Vector<String16>& args __unused) {
935    String8 result;
936    return NO_ERROR;
937}
938
939void SoundTriggerHwService::ModuleClient::detach() {
940    ALOGV("detach()");
941    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
942                               IPCThreadState::self()->getCallingUid())) {
943        return;
944    }
945
946    {
947        AutoMutex lock(mLock);
948        if (mClient != 0) {
949            IInterface::asBinder(mClient)->unlinkToDeath(this);
950            mClient.clear();
951        }
952    }
953
954    sp<Module> module = mModule.promote();
955    if (module == 0) {
956        return;
957    }
958    module->detach(this);
959}
960
961status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
962                                sound_model_handle_t *handle)
963{
964    ALOGV("loadSoundModel() handle");
965    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
966                               IPCThreadState::self()->getCallingUid())) {
967        return PERMISSION_DENIED;
968    }
969
970    sp<Module> module = mModule.promote();
971    if (module == 0) {
972        return NO_INIT;
973    }
974    return module->loadSoundModel(modelMemory, this, handle);
975}
976
977status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
978{
979    ALOGV("unloadSoundModel() model handle %d", handle);
980    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
981                               IPCThreadState::self()->getCallingUid())) {
982        return PERMISSION_DENIED;
983    }
984
985    sp<Module> module = mModule.promote();
986    if (module == 0) {
987        return NO_INIT;
988    }
989    return module->unloadSoundModel(handle);
990}
991
992status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
993                                 const sp<IMemory>& dataMemory)
994{
995    ALOGV("startRecognition() model handle %d", handle);
996    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
997                               IPCThreadState::self()->getCallingUid())) {
998        return PERMISSION_DENIED;
999    }
1000
1001    sp<Module> module = mModule.promote();
1002    if (module == 0) {
1003        return NO_INIT;
1004    }
1005    return module->startRecognition(handle, dataMemory);
1006}
1007
1008status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1009{
1010    ALOGV("stopRecognition() model handle %d", handle);
1011    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1012                               IPCThreadState::self()->getCallingUid())) {
1013        return PERMISSION_DENIED;
1014    }
1015
1016    sp<Module> module = mModule.promote();
1017    if (module == 0) {
1018        return NO_INIT;
1019    }
1020    return module->stopRecognition(handle);
1021}
1022
1023void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1024{
1025    ALOGV("ModuleClient::setCaptureState_l %d", active);
1026    sp<SoundTriggerHwService> service;
1027    sound_trigger_service_state_t state;
1028
1029    sp<Module> module = mModule.promote();
1030    if (module == 0) {
1031        return;
1032    }
1033    {
1034        AutoMutex lock(mLock);
1035        state = (active && !module->isConcurrentCaptureAllowed()) ?
1036                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1037
1038        service = module->service().promote();
1039        if (service == 0) {
1040            return;
1041        }
1042    }
1043    service->sendServiceStateEvent(state, this);
1044}
1045
1046void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1047{
1048    ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1049
1050    sp<IMemory> eventMemory = event->mMemory;
1051
1052    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1053        return;
1054    }
1055
1056    sp<ISoundTriggerClient> client;
1057    {
1058        AutoMutex lock(mLock);
1059        client = mClient;
1060    }
1061
1062    if (client != 0) {
1063        switch (event->mType) {
1064        case CallbackEvent::TYPE_RECOGNITION: {
1065            client->onRecognitionEvent(eventMemory);
1066        } break;
1067        case CallbackEvent::TYPE_SOUNDMODEL: {
1068            client->onSoundModelEvent(eventMemory);
1069        } break;
1070        case CallbackEvent::TYPE_SERVICE_STATE: {
1071            client->onServiceStateChange(eventMemory);
1072        } break;
1073        default:
1074            LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1075        }
1076    }
1077}
1078
1079void SoundTriggerHwService::ModuleClient::binderDied(
1080    const wp<IBinder> &who __unused) {
1081    ALOGW("client binder died for client %p", this);
1082    detach();
1083}
1084
1085}; // namespace android
1086