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

Commit cee3bd4d authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Reset the speech synth singleton to null when the service is destroyed

so it can be recreated when the service is initialized.
In the interface with the native synthesizer library, close the lib
in the finalizer, delete the global ref to the SynthProxy java object.
parent db7db69a
Loading
Loading
Loading
Loading
+36 −28
Original line number Original line Diff line number Diff line
@@ -65,9 +65,9 @@ static Mutex engineMutex;
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
class SynthProxyJniStorage {
class SynthProxyJniStorage {
    public :
    public :
        //jclass                    tts_class;
        jobject                   tts_ref;
        jobject                   tts_ref;
        TtsEngine*                mNativeSynthInterface;
        TtsEngine*                mNativeSynthInterface;
        void*                     mEngineLibHandle;
        AudioTrack*               mAudioOut;
        AudioTrack*               mAudioOut;
        AudioSystem::stream_type  mStreamType;
        AudioSystem::stream_type  mStreamType;
        uint32_t                  mSampleRate;
        uint32_t                  mSampleRate;
@@ -77,9 +77,9 @@ class SynthProxyJniStorage {
        size_t                    mBufferSize;
        size_t                    mBufferSize;


        SynthProxyJniStorage() {
        SynthProxyJniStorage() {
            //tts_class = NULL;
            tts_ref = NULL;
            tts_ref = NULL;
            mNativeSynthInterface = NULL;
            mNativeSynthInterface = NULL;
            mEngineLibHandle = NULL;
            mAudioOut = NULL;
            mAudioOut = NULL;
            mStreamType = DEFAULT_TTS_STREAM_TYPE;
            mStreamType = DEFAULT_TTS_STREAM_TYPE;
            mSampleRate = DEFAULT_TTS_RATE;
            mSampleRate = DEFAULT_TTS_RATE;
@@ -91,11 +91,17 @@ class SynthProxyJniStorage {
        }
        }


        ~SynthProxyJniStorage() {
        ~SynthProxyJniStorage() {
            //LOGV("entering ~SynthProxyJniStorage()");
            killAudio();
            killAudio();
            if (mNativeSynthInterface) {
            if (mNativeSynthInterface) {
                mNativeSynthInterface->shutdown();
                mNativeSynthInterface->shutdown();
                mNativeSynthInterface = NULL;
                mNativeSynthInterface = NULL;
            }
            }
            if (mEngineLibHandle) {
                //LOGE("~SynthProxyJniStorage(): before close library");
                int res = dlclose(mEngineLibHandle);
                LOGE_IF( res != 0, "~SynthProxyJniStorage(): dlclose returned %d", res);
            }
            delete mBuffer;
            delete mBuffer;
        }
        }


@@ -138,13 +144,13 @@ class SynthProxyJniStorage {
                    0, 0, 0, 0); // not using an AudioTrack callback
                    0, 0, 0, 0); // not using an AudioTrack callback


            if (mAudioOut->initCheck() != NO_ERROR) {
            if (mAudioOut->initCheck() != NO_ERROR) {
              LOGI("AudioTrack error");
              LOGE("createAudioOut(): AudioTrack error");
              delete mAudioOut;
              delete mAudioOut;
              mAudioOut = NULL;
              mAudioOut = NULL;
            } else {
            } else {
              //LOGI("AudioTrack OK");
              //LOGI("AudioTrack OK");
              mAudioOut->start();
              mAudioOut->start();
              LOGI("AudioTrack started");
              LOGV("AudioTrack started");
            }
            }
        }
        }
};
};
@@ -260,15 +266,17 @@ android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz,
    void *engine_lib_handle = dlopen(nativeSoLibNativeString,
    void *engine_lib_handle = dlopen(nativeSoLibNativeString,
            RTLD_NOW | RTLD_LOCAL);
            RTLD_NOW | RTLD_LOCAL);
    if (engine_lib_handle == NULL) {
    if (engine_lib_handle == NULL) {
       LOGI("engine_lib_handle==NULL");
       LOGE("android_tts_SynthProxy_native_setup(): engine_lib_handle == NULL");
       // TODO report error so the TTS can't be used
       // TODO report error so the TTS can't be used
    } else {
    } else {
        TtsEngine *(*get_TtsEngine)() =
        TtsEngine *(*get_TtsEngine)() =
            reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine"));
            reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine"));


        pJniStorage->mNativeSynthInterface = (*get_TtsEngine)();
        pJniStorage->mNativeSynthInterface = (*get_TtsEngine)();
        pJniStorage->mEngineLibHandle = engine_lib_handle;


        if (pJniStorage->mNativeSynthInterface) {
        if (pJniStorage->mNativeSynthInterface) {
            Mutex::Autolock l(engineMutex);
            pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
            pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
        }
        }
    }
    }
@@ -287,11 +295,29 @@ android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz,
static void
static void
android_tts_SynthProxy_native_finalize(JNIEnv *env, jobject thiz, jint jniData)
android_tts_SynthProxy_native_finalize(JNIEnv *env, jobject thiz, jint jniData)
{
{
    if (jniData) {
    //LOGV("entering android_tts_SynthProxy_finalize()");
    if (jniData == 0) {
        //LOGE("android_tts_SynthProxy_native_finalize(): invalid JNI data");
        return;
    }

    Mutex::Autolock l(engineMutex);

    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
    env->DeleteGlobalRef(pSynthData->tts_ref);
    env->DeleteGlobalRef(pSynthData->tts_ref);
    delete pSynthData;
    delete pSynthData;

    env->SetIntField(thiz, javaTTSFields.synthProxyFieldJniData, 0);
}
}


static void
android_tts_SynthProxy_shutdown(JNIEnv *env, jobject thiz, jint jniData)
{
    //LOGV("entering android_tts_SynthProxy_shutdown()");

    // do everything a call to finalize would
    android_tts_SynthProxy_native_finalize(env, thiz, jniData);
}
}




@@ -604,24 +630,6 @@ android_tts_SynthProxy_stop(JNIEnv *env, jobject thiz, jint jniData)
}
}




static void
android_tts_SynthProxy_shutdown(JNIEnv *env, jobject thiz, jint jniData)
{
    if (jniData == 0) {
        LOGE("android_tts_SynthProxy_shutdown(): invalid JNI data");
        return;
    }

    Mutex::Autolock l(engineMutex);

    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
    if (pSynthData->mNativeSynthInterface) {
        pSynthData->mNativeSynthInterface->shutdown();
        pSynthData->mNativeSynthInterface = NULL;
    }
}


static jobjectArray
static jobjectArray
android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
{
{
+1 −0
Original line number Original line Diff line number Diff line
@@ -174,6 +174,7 @@ public class TtsService extends Service implements OnCompletionListener {
        cleanUpPlayer();
        cleanUpPlayer();


        sNativeSynth.shutdown();
        sNativeSynth.shutdown();
        sNativeSynth = null;


        // Unregister all callbacks.
        // Unregister all callbacks.
        mCallbacks.kill();
        mCallbacks.kill();