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    Vector<audio_session_t> releasedSessions;
534
535    {
536        AutoMutex lock(mLock);
537        ssize_t index = -1;
538
539        for (size_t i = 0; i < mModuleClients.size(); i++) {
540            if (mModuleClients[i] == moduleClient) {
541                index = i;
542                break;
543            }
544        }
545        if (index == -1) {
546            return;
547        }
548
549        ALOGV("remove client %p", moduleClient.get());
550        mModuleClients.removeAt(index);
551
552        // Iterate in reverse order as models are removed from list inside the loop.
553        for (size_t i = mModels.size(); i > 0; i--) {
554            sp<Model> model = mModels.valueAt(i - 1);
555            if (moduleClient == model->mModuleClient) {
556                mModels.removeItemsAt(i - 1);
557                ALOGV("detach() unloading model %d", model->mHandle);
558                if (mHalInterface != 0) {
559                    if (model->mState == Model::STATE_ACTIVE) {
560                        mHalInterface->stopRecognition(model->mHandle);
561                    }
562                    mHalInterface->unloadSoundModel(model->mHandle);
563                }
564                releasedSessions.add(model->mCaptureSession);
565            }
566        }
567    }
568
569    for (size_t i = 0; i < releasedSessions.size(); i++) {
570        // do not call AudioSystem methods with mLock held
571        AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
572    }
573}
574
575status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
576                                                       sp<ModuleClient> moduleClient,
577                                                       sound_model_handle_t *handle)
578{
579    ALOGV("loadSoundModel() handle");
580    if (mHalInterface == 0) {
581        return NO_INIT;
582    }
583    if (modelMemory == 0 || modelMemory->pointer() == NULL) {
584        ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
585        return BAD_VALUE;
586    }
587    struct sound_trigger_sound_model *sound_model =
588            (struct sound_trigger_sound_model *)modelMemory->pointer();
589
590    size_t structSize;
591    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
592        structSize = sizeof(struct sound_trigger_phrase_sound_model);
593    } else {
594        structSize = sizeof(struct sound_trigger_sound_model);
595    }
596
597    if (sound_model->data_offset < structSize ||
598           sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
599           modelMemory->size() < sound_model->data_offset ||
600           sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
601        android_errorWriteLog(0x534e4554, "30148546");
602        ALOGE("loadSoundModel() data_size is too big");
603        return BAD_VALUE;
604    }
605
606    audio_session_t session;
607    audio_io_handle_t ioHandle;
608    audio_devices_t device;
609    // do not call AudioSystem methods with mLock held
610    status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
611    if (status != NO_ERROR) {
612        return status;
613    }
614
615    {
616        AutoMutex lock(mLock);
617
618        if (mModels.size() >= mDescriptor.properties.max_sound_models) {
619            ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
620                  mDescriptor.properties.max_sound_models);
621            status = INVALID_OPERATION;
622            goto exit;
623        }
624
625        status = mHalInterface->loadSoundModel(sound_model,
626                                                      SoundTriggerHwService::soundModelCallback,
627                                                      this, handle);
628        if (status != NO_ERROR) {
629            goto exit;
630        }
631
632        sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
633                                    moduleClient);
634        mModels.replaceValueFor(*handle, model);
635    }
636exit:
637    if (status != NO_ERROR) {
638        // do not call AudioSystem methods with mLock held
639        AudioSystem::releaseSoundTriggerSession(session);
640    }
641    return status;
642}
643
644status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
645{
646    ALOGV("unloadSoundModel() model handle %d", handle);
647    status_t status;
648    audio_session_t session;
649
650    {
651        AutoMutex lock(mLock);
652        if (mHalInterface == 0) {
653            return NO_INIT;
654        }
655        ssize_t index = mModels.indexOfKey(handle);
656        if (index < 0) {
657            return BAD_VALUE;
658        }
659        sp<Model> model = mModels.valueAt(index);
660        mModels.removeItem(handle);
661        if (model->mState == Model::STATE_ACTIVE) {
662            mHalInterface->stopRecognition(model->mHandle);
663            model->mState = Model::STATE_IDLE;
664        }
665        status = mHalInterface->unloadSoundModel(handle);
666        session = model->mCaptureSession;
667    }
668    // do not call AudioSystem methods with mLock held
669    AudioSystem::releaseSoundTriggerSession(session);
670    return status;
671}
672
673status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
674                                 const sp<IMemory>& dataMemory)
675{
676    ALOGV("startRecognition() model handle %d", handle);
677    if (mHalInterface == 0) {
678        return NO_INIT;
679    }
680    if (dataMemory == 0 || dataMemory->pointer() == NULL) {
681        ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
682        return BAD_VALUE;
683
684    }
685
686    struct sound_trigger_recognition_config *config =
687            (struct sound_trigger_recognition_config *)dataMemory->pointer();
688
689    if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
690            config->data_size > (UINT_MAX - config->data_offset) ||
691            dataMemory->size() < config->data_offset ||
692            config->data_size > (dataMemory->size() - config->data_offset)) {
693        ALOGE("startRecognition() data_size is too big");
694        return BAD_VALUE;
695    }
696
697    AutoMutex lock(mLock);
698    if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
699        return INVALID_OPERATION;
700    }
701    sp<Model> model = getModel(handle);
702    if (model == 0) {
703        return BAD_VALUE;
704    }
705
706    if (model->mState == Model::STATE_ACTIVE) {
707        return INVALID_OPERATION;
708    }
709
710
711    //TODO: get capture handle and device from audio policy service
712    config->capture_handle = model->mCaptureIOHandle;
713    config->capture_device = model->mCaptureDevice;
714    status_t status = mHalInterface->startRecognition(handle, config,
715                                        SoundTriggerHwService::recognitionCallback,
716                                        this);
717
718    if (status == NO_ERROR) {
719        model->mState = Model::STATE_ACTIVE;
720        model->mConfig = *config;
721    }
722
723    return status;
724}
725
726status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
727{
728    ALOGV("stopRecognition() model handle %d", handle);
729    if (mHalInterface == 0) {
730        return NO_INIT;
731    }
732    AutoMutex lock(mLock);
733    sp<Model> model = getModel(handle);
734    if (model == 0) {
735        return BAD_VALUE;
736    }
737
738    if (model->mState != Model::STATE_ACTIVE) {
739        return INVALID_OPERATION;
740    }
741    mHalInterface->stopRecognition(handle);
742    model->mState = Model::STATE_IDLE;
743    return NO_ERROR;
744}
745
746void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
747{
748    ALOGV("onCallbackEvent type %d", event->mType);
749
750    sp<IMemory> eventMemory = event->mMemory;
751
752    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
753        return;
754    }
755    if (mModuleClients.isEmpty()) {
756        ALOGI("%s no clients", __func__);
757        return;
758    }
759
760    switch (event->mType) {
761    case CallbackEvent::TYPE_RECOGNITION: {
762        struct sound_trigger_recognition_event *recognitionEvent =
763                (struct sound_trigger_recognition_event *)eventMemory->pointer();
764        sp<ISoundTriggerClient> client;
765        {
766            AutoMutex lock(mLock);
767            sp<Model> model = getModel(recognitionEvent->model);
768            if (model == 0) {
769                ALOGW("%s model == 0", __func__);
770                return;
771            }
772            if (model->mState != Model::STATE_ACTIVE) {
773                ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
774                return;
775            }
776
777            recognitionEvent->capture_session = model->mCaptureSession;
778            model->mState = Model::STATE_IDLE;
779            client = model->mModuleClient->client();
780        }
781        if (client != 0) {
782            client->onRecognitionEvent(eventMemory);
783        }
784    } break;
785    case CallbackEvent::TYPE_SOUNDMODEL: {
786        struct sound_trigger_model_event *soundmodelEvent =
787                (struct sound_trigger_model_event *)eventMemory->pointer();
788        sp<ISoundTriggerClient> client;
789        {
790            AutoMutex lock(mLock);
791            sp<Model> model = getModel(soundmodelEvent->model);
792            if (model == 0) {
793                ALOGW("%s model == 0", __func__);
794                return;
795            }
796            client = model->mModuleClient->client();
797        }
798        if (client != 0) {
799            client->onSoundModelEvent(eventMemory);
800        }
801    } break;
802    case CallbackEvent::TYPE_SERVICE_STATE: {
803        Vector< sp<ISoundTriggerClient> > clients;
804        {
805            AutoMutex lock(mLock);
806            for (size_t i = 0; i < mModuleClients.size(); i++) {
807                if (mModuleClients[i] != 0) {
808                    clients.add(mModuleClients[i]->client());
809                }
810            }
811        }
812        for (size_t i = 0; i < clients.size(); i++) {
813            clients[i]->onServiceStateChange(eventMemory);
814        }
815    } break;
816    default:
817        LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
818    }
819}
820
821sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
822        sound_model_handle_t handle)
823{
824    sp<Model> model;
825    ssize_t index = mModels.indexOfKey(handle);
826    if (index >= 0) {
827        model = mModels.valueAt(index);
828    }
829    return model;
830}
831
832// Called with mServiceLock held
833void SoundTriggerHwService::Module::setCaptureState_l(bool active)
834{
835    ALOGV("Module::setCaptureState_l %d", active);
836    sp<SoundTriggerHwService> service;
837    sound_trigger_service_state_t state;
838
839    Vector< sp<IMemory> > events;
840    {
841        AutoMutex lock(mLock);
842        state = (active && !mDescriptor.properties.concurrent_capture) ?
843                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
844
845        if (state == mServiceState) {
846            return;
847        }
848
849        mServiceState = state;
850
851        service = mService.promote();
852        if (service == 0) {
853            return;
854        }
855
856        if (state == SOUND_TRIGGER_STATE_ENABLED) {
857            goto exit;
858        }
859
860        const bool supports_stop_all =
861                (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
862
863        for (size_t i = 0; i < mModels.size(); i++) {
864            sp<Model> model = mModels.valueAt(i);
865            if (model->mState == Model::STATE_ACTIVE) {
866                if (mHalInterface != 0 && !supports_stop_all) {
867                    mHalInterface->stopRecognition(model->mHandle);
868                }
869                // keep model in ACTIVE state so that event is processed by onCallbackEvent()
870                if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
871                    struct sound_trigger_phrase_recognition_event event;
872                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
873                    event.num_phrases = model->mConfig.num_phrases;
874                    for (size_t i = 0; i < event.num_phrases; i++) {
875                        event.phrase_extras[i] = model->mConfig.phrases[i];
876                    }
877                    event.common.status = RECOGNITION_STATUS_ABORT;
878                    event.common.type = model->mType;
879                    event.common.model = model->mHandle;
880                    event.common.data_size = 0;
881                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
882                    if (eventMemory != 0) {
883                        events.add(eventMemory);
884                    }
885                } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
886                    struct sound_trigger_generic_recognition_event event;
887                    memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
888                    event.common.status = RECOGNITION_STATUS_ABORT;
889                    event.common.type = model->mType;
890                    event.common.model = model->mHandle;
891                    event.common.data_size = 0;
892                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
893                    if (eventMemory != 0) {
894                        events.add(eventMemory);
895                    }
896                } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
897                    struct sound_trigger_phrase_recognition_event event;
898                    memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
899                    event.common.status = RECOGNITION_STATUS_ABORT;
900                    event.common.type = model->mType;
901                    event.common.model = model->mHandle;
902                    event.common.data_size = 0;
903                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
904                    if (eventMemory != 0) {
905                        events.add(eventMemory);
906                    }
907                } else {
908                    goto exit;
909                }
910            }
911        }
912    }
913
914    for (size_t i = 0; i < events.size(); i++) {
915        sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
916                                                            events[i]);
917        callbackEvent->setModule(this);
918        service->sendCallbackEvent_l(callbackEvent);
919    }
920
921exit:
922    service->sendServiceStateEvent_l(state, this);
923}
924
925
926SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
927                                    audio_io_handle_t ioHandle, audio_devices_t device,
928                                    sound_trigger_sound_model_type_t type,
929                                    sp<ModuleClient>& moduleClient) :
930    mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
931    mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
932    mModuleClient(moduleClient)
933{
934}
935
936#undef LOG_TAG
937#define LOG_TAG "SoundTriggerHwService::ModuleClient"
938
939SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
940                                                  const sp<ISoundTriggerClient>& client)
941 : mModule(module), mClient(client)
942{
943}
944
945void SoundTriggerHwService::ModuleClient::onFirstRef()
946{
947    sp<IBinder> binder = IInterface::asBinder(mClient);
948    if (binder != 0) {
949        binder->linkToDeath(this);
950    }
951}
952
953SoundTriggerHwService::ModuleClient::~ModuleClient()
954{
955}
956
957status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
958                                                   const Vector<String16>& args __unused) {
959    String8 result;
960    return NO_ERROR;
961}
962
963void SoundTriggerHwService::ModuleClient::detach() {
964    ALOGV("detach()");
965    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
966                               IPCThreadState::self()->getCallingUid())) {
967        return;
968    }
969
970    {
971        AutoMutex lock(mLock);
972        if (mClient != 0) {
973            IInterface::asBinder(mClient)->unlinkToDeath(this);
974            mClient.clear();
975        }
976    }
977
978    sp<Module> module = mModule.promote();
979    if (module == 0) {
980        return;
981    }
982    module->detach(this);
983}
984
985status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
986                                sound_model_handle_t *handle)
987{
988    ALOGV("loadSoundModel() handle");
989    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
990                               IPCThreadState::self()->getCallingUid())) {
991        return PERMISSION_DENIED;
992    }
993
994    sp<Module> module = mModule.promote();
995    if (module == 0) {
996        return NO_INIT;
997    }
998    return module->loadSoundModel(modelMemory, this, handle);
999}
1000
1001status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
1002{
1003    ALOGV("unloadSoundModel() model handle %d", handle);
1004    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1005                               IPCThreadState::self()->getCallingUid())) {
1006        return PERMISSION_DENIED;
1007    }
1008
1009    sp<Module> module = mModule.promote();
1010    if (module == 0) {
1011        return NO_INIT;
1012    }
1013    return module->unloadSoundModel(handle);
1014}
1015
1016status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1017                                 const sp<IMemory>& dataMemory)
1018{
1019    ALOGV("startRecognition() model handle %d", handle);
1020    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1021                               IPCThreadState::self()->getCallingUid())) {
1022        return PERMISSION_DENIED;
1023    }
1024
1025    sp<Module> module = mModule.promote();
1026    if (module == 0) {
1027        return NO_INIT;
1028    }
1029    return module->startRecognition(handle, dataMemory);
1030}
1031
1032status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1033{
1034    ALOGV("stopRecognition() model handle %d", handle);
1035    if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1036                               IPCThreadState::self()->getCallingUid())) {
1037        return PERMISSION_DENIED;
1038    }
1039
1040    sp<Module> module = mModule.promote();
1041    if (module == 0) {
1042        return NO_INIT;
1043    }
1044    return module->stopRecognition(handle);
1045}
1046
1047void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1048{
1049    ALOGV("ModuleClient::setCaptureState_l %d", active);
1050    sp<SoundTriggerHwService> service;
1051    sound_trigger_service_state_t state;
1052
1053    sp<Module> module = mModule.promote();
1054    if (module == 0) {
1055        return;
1056    }
1057    {
1058        AutoMutex lock(mLock);
1059        state = (active && !module->isConcurrentCaptureAllowed()) ?
1060                                        SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1061
1062        service = module->service().promote();
1063        if (service == 0) {
1064            return;
1065        }
1066    }
1067    service->sendServiceStateEvent_l(state, this);
1068}
1069
1070void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1071{
1072    ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1073
1074    sp<IMemory> eventMemory = event->mMemory;
1075
1076    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1077        return;
1078    }
1079
1080    switch (event->mType) {
1081    case CallbackEvent::TYPE_SERVICE_STATE: {
1082        sp<ISoundTriggerClient> client;
1083        {
1084            AutoMutex lock(mLock);
1085            client = mClient;
1086        }
1087        if (client !=0 ) {
1088            client->onServiceStateChange(eventMemory);
1089        }
1090    } break;
1091    default:
1092        LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1093    }
1094}
1095
1096void SoundTriggerHwService::ModuleClient::binderDied(
1097    const wp<IBinder> &who __unused) {
1098    ALOGW("client binder died for client %p", this);
1099    detach();
1100}
1101
1102}; // namespace android
1103