Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c297fb28 authored by Chris Thornton's avatar Chris Thornton Committed by Android (Google) Code Review
Browse files

Merge "Avoid deadlock between recognition events and SoundTriggerHwService."

parents 43b0d00c 79c5661c
Loading
Loading
Loading
Loading
+41 −48
Original line number Diff line number Diff line
@@ -206,9 +206,10 @@ void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition
    service->sendRecognitionEvent(event, module);
}

sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
                                                    struct sound_trigger_recognition_event *event)
{
    AutoMutex lock(mMemoryDealerLock);
    sp<IMemory> eventMemory;

    //sanitize event
@@ -216,21 +217,21 @@ sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
    case SOUND_MODEL_TYPE_KEYPHRASE:
        ALOGW_IF(event->data_size != 0 && event->data_offset !=
                    sizeof(struct sound_trigger_phrase_recognition_event),
                    "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
                    "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
                    event->data_offset);
        event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
        break;
    case SOUND_MODEL_TYPE_GENERIC:
        ALOGW_IF(event->data_size != 0 && event->data_offset !=
                    sizeof(struct sound_trigger_generic_recognition_event),
                    "prepareRecognitionEvent_l(): invalid data offset %u for generic event type",
                    "prepareRecognitionEvent(): invalid data offset %u for generic event type",
                    event->data_offset);
        event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
        break;
    case SOUND_MODEL_TYPE_UNKNOWN:
        ALOGW_IF(event->data_size != 0 && event->data_offset !=
                    sizeof(struct sound_trigger_recognition_event),
                    "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
                    "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
                    event->data_offset);
        event->data_offset = sizeof(struct sound_trigger_recognition_event);
        break;
@@ -252,29 +253,18 @@ sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
                                                 Module *module)
{
     AutoMutex lock(mServiceLock);
    if (module == NULL) {
        return;
    }
     sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
    sp<IMemory> eventMemory = prepareRecognitionEvent(event);
    if (eventMemory == 0) {
        return;
    }
     sp<Module> strongModule;
     for (size_t i = 0; i < mModules.size(); i++) {
         if (mModules.valueAt(i).get() == module) {
             strongModule = mModules.valueAt(i);
             break;
         }
     }
     if (strongModule == 0) {
         return;
     }

    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
                                                        eventMemory);
    callbackEvent->setModule(strongModule);
    sendCallbackEvent_l(callbackEvent);
    callbackEvent->setModule(module);
    sendCallbackEvent(callbackEvent);
}

// static
@@ -293,8 +283,9 @@ void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event
    service->sendSoundModelEvent(event, module);
}

sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
{
    AutoMutex lock(mMemoryDealerLock);
    sp<IMemory> eventMemory;

    size_t size = event->data_offset + event->data_size;
@@ -311,30 +302,20 @@ sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger
void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
                                                Module *module)
{
    AutoMutex lock(mServiceLock);
    sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
    sp<IMemory> eventMemory = prepareSoundModelEvent(event);
    if (eventMemory == 0) {
        return;
    }
    sp<Module> strongModule;
    for (size_t i = 0; i < mModules.size(); i++) {
        if (mModules.valueAt(i).get() == module) {
            strongModule = mModules.valueAt(i);
            break;
        }
    }
    if (strongModule == 0) {
        return;
    }
    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
                                                        eventMemory);
    callbackEvent->setModule(strongModule);
    sendCallbackEvent_l(callbackEvent);
    callbackEvent->setModule(module);
    sendCallbackEvent(callbackEvent);
}


sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
{
    AutoMutex lock(mMemoryDealerLock);
    sp<IMemory> eventMemory;

    size_t size = sizeof(sound_trigger_service_state_t);
@@ -368,7 +349,7 @@ void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_
    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
                                                        eventMemory);
    callbackEvent->setModule(strongModule);
    sendCallbackEvent_l(callbackEvent);
    sendCallbackEvent(callbackEvent);
}

void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
@@ -381,11 +362,10 @@ void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_
    sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
                                                        eventMemory);
    callbackEvent->setModuleClient(moduleClient);
    sendCallbackEvent_l(callbackEvent);
    sendCallbackEvent(callbackEvent);
}

// call with mServiceLock held
void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
{
    mCallbackThread->sendCallbackEvent(event);
}
@@ -404,6 +384,19 @@ void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
            if (moduleClient == 0) {
                return;
            }
        } else {
            // Sanity check on this being a Module we know about.
            bool foundModule = false;
            for (size_t i = 0; i < mModules.size(); i++) {
                if (mModules.valueAt(i).get() == module.get()) {
                    foundModule = true;
                    break;
                }
            }
            if (!foundModule) {
                ALOGE("onCallbackEvent for unknown module");
                return;
            }
        }
    }
    if (module != 0) {
@@ -878,7 +871,7 @@ void SoundTriggerHwService::Module::setCaptureState_l(bool active)
                    event.common.type = model->mType;
                    event.common.model = model->mHandle;
                    event.common.data_size = 0;
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
                    if (eventMemory != 0) {
                        events.add(eventMemory);
                    }
@@ -889,7 +882,7 @@ void SoundTriggerHwService::Module::setCaptureState_l(bool active)
                    event.common.type = model->mType;
                    event.common.model = model->mHandle;
                    event.common.data_size = 0;
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
                    if (eventMemory != 0) {
                        events.add(eventMemory);
                    }
@@ -900,7 +893,7 @@ void SoundTriggerHwService::Module::setCaptureState_l(bool active)
                    event.common.type = model->mType;
                    event.common.model = model->mHandle;
                    event.common.data_size = 0;
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
                    sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
                    if (eventMemory != 0) {
                        events.add(eventMemory);
                    }
@@ -915,7 +908,7 @@ void SoundTriggerHwService::Module::setCaptureState_l(bool active)
        sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
                                                            events[i]);
        callbackEvent->setModule(this);
        service->sendCallbackEvent_l(callbackEvent);
        service->sendCallbackEvent(callbackEvent);
    }

exit:
+4 −3
Original line number Diff line number Diff line
@@ -214,11 +214,11 @@ public:
    };

    static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
           sp<IMemory> prepareRecognitionEvent_l(struct sound_trigger_recognition_event *event);
           sp<IMemory> prepareRecognitionEvent(struct sound_trigger_recognition_event *event);
           void sendRecognitionEvent(struct sound_trigger_recognition_event *event, Module *module);

    static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
           sp<IMemory> prepareSoundModelEvent_l(struct sound_trigger_model_event *event);
           sp<IMemory> prepareSoundModelEvent(struct sound_trigger_model_event *event);
           void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);

           sp<IMemory> prepareServiceStateEvent_l(sound_trigger_service_state_t state);
@@ -226,7 +226,7 @@ public:
           void sendServiceStateEvent_l(sound_trigger_service_state_t state,
                                        ModuleClient *moduleClient);

           void sendCallbackEvent_l(const sp<CallbackEvent>& event);
           void sendCallbackEvent(const sp<CallbackEvent>& event);
           void onCallbackEvent(const sp<CallbackEvent>& event);

private:
@@ -238,6 +238,7 @@ private:
    DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> >     mModules;
    sp<CallbackThread>  mCallbackThread;
    sp<MemoryDealer>    mMemoryDealer;
    Mutex               mMemoryDealerLock;
    bool                mCaptureState;
};