2025-03-25

 

今天來看看AudioEffect中enable相關的接口。

 

 

*****************************************源碼*************************************************

    //Test case 1.3: test getEnabled() failure when called on released effect

    @LargeTest

    public void test1_3GetEnabledAfterRelease() throws Exception {

        boolean result = false;

        String msg = "test1_3GetEnabledAfterRelease()";

 

 

        try {

            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,

                    AudioEffect.EFFECT_TYPE_NULL,

                    0,

                    0);

            assertNotNull(msg + ": could not create AudioEffect", effect);

            effect.release();

            try {

                effect.getEnabled();

            } catch (IllegalStateException e) {

                result = true;

            }

        } catch (IllegalArgumentException e) {

            msg = msg.concat(": Equalizer not found");

        } catch (UnsupportedOperationException e) {

            msg = msg.concat(": Effect library not loaded");

        }

        assertTrue(msg, result);

    }

**********************************************************************************************

源碼路徑:

frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioEffectTest.java

 

 

#######################說明################################

    //Test case 1.3: test getEnabled() failure when called on released effect

    @LargeTest

    public void test1_3GetEnabledAfterRelease() throws Exception {

        boolean result = false;

        String msg = "test1_3GetEnabledAfterRelease()";

 

 

        try {

            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,

                    AudioEffect.EFFECT_TYPE_NULL,

                    0,

                    0);

            assertNotNull(msg + ": could not create AudioEffect", effect);

            effect.release();

++++++++++++++++++++++++++++++release++++++++++++++++++++++++++++++++++

    /**

     * Releases the native AudioEffect resources. It is a good practice to

     * release the effect engine when not in use as control can be returned to

     * other applications or the native resources released.

     */

    public void release() {

        synchronized (mStateLock) {

            native_release();

++++++++++++++++++++++++++++++android_media_AudioEffect_native_release++++++++++++++++++++++++++++++++++

static void android_media_AudioEffect_native_release(JNIEnv *env,  jobject thiz) {

 

 

    // do everything a call to finalize would

// 刪除創建AudioEffect時,創建的對象

    android_media_AudioEffect_native_finalize(env, thiz);

++++++++++++++++++++++++++++++android_media_AudioEffect_native_finalize++++++++++++++++++++++++++++++++++

static void android_media_AudioEffect_native_finalize(JNIEnv *env,  jobject thiz) {

    LOGV("android_media_AudioEffect_native_finalize jobject: %x\n", (int)thiz);

 

 

    // delete the AudioEffect object

    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(

        thiz, fields.fidNativeAudioEffect);

// 此處刪除瞭lpAudioEffect

// getEnabled的時候會調用lpAudioEffect的接口,所以release後再getEnabled會產生異常

    if (lpAudioEffect) {

        LOGV("deleting AudioEffect: %x\n", (int)lpAudioEffect);

        delete lpAudioEffect;

    }

 

 

    // delete the JNI data

    AudioEffectJniStorage* lpJniStorage = (AudioEffectJniStorage *)env->GetIntField(

        thiz, fields.fidJniData);

    if (lpJniStorage) {

        LOGV("deleting pJniStorage: %x\n", (int)lpJniStorage);

        delete lpJniStorage;

    }

}

——————————android_media_AudioEffect_native_finalize———————————-

    // + reset the native resources in the Java object so any attempt to access

    // them after a call to release fails.

    env->SetIntField(thiz, fields.fidNativeAudioEffect, 0);

    env->SetIntField(thiz, fields.fidJniData, 0);

}

——————————android_media_AudioEffect_native_release———————————-

            mState = STATE_UNINITIALIZED;

        }

    }

——————————release———————————-

            try {

                effect.getEnabled();

++++++++++++++++++++++++++++++++getEnabled++++++++++++++++++++++++++++++++

    /**

     * Returns effect enabled state

     *

     * @return true if the effect is enabled, false otherwise.

     * @throws IllegalStateException

     */

    public boolean getEnabled() throws IllegalStateException {

        checkState("getEnabled()");

        return native_getEnabled();

++++++++++++++++++++++++++++++android_media_AudioEffect_native_getEnabled++++++++++++++++++++++++++++++++++

static jboolean

android_media_AudioEffect_native_getEnabled(JNIEnv *env, jobject thiz)

{

    // retrieve the AudioEffect object

    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(

        thiz, fields.fidNativeAudioEffect);

 

 

    if (lpAudioEffect == NULL) {

        jniThrowException(env, "java/lang/IllegalStateException",

            "Unable to retrieve AudioEffect pointer for getEnabled()");

        return false;

    }

 

 

    return (jboolean)lpAudioEffect->getEnabled();

++++++++++++++++++++++++++++AudioEffect::getEnabled++++++++++++++++++++++++++++++++++++

bool AudioEffect::getEnabled() const

{

// mEnabled在函數AudioEffect::set中被賦值:mEnabled = (volatile int32_t)enabled;

 

 

// enabled產生於對函數AudioFlinger::createEffect的調用

//    iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor,

//            mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled);

 

 

// 又將地址傳給瞭函數AudioFlinger::PlaybackThread::createEffect_l

        // create effect on selected output trhead

//        handle = thread->createEffect_l(client, effectClient, priority, sessionId,

//                &desc, enabled, &lStatus);

 

 

// 調用函數AudioFlinger::EffectModule::isEnabled

//            *enabled = (int)effect->isEnabled();

++++++++++++++++++++++++++++AudioFlinger::EffectModule::isEnabled++++++++++++++++++++++++++++++++++++

bool AudioFlinger::EffectModule::isEnabled()

{

// EffectModule構造函數中會將mState設為IDLE

// 函數updateState和函數setEnabled都會改變mState。

// 函數AudioFlinger::EffectChain::process_l會調用函數updateState來更新狀態

    switch (mState) {

    case RESTART:

    case STARTING:

    case ACTIVE:

        return true;

    case IDLE:

    case STOPPING:

    case STOPPED:

    default:

        return false;

    }

}

—————————-AudioFlinger::EffectModule::isEnabled————————————

    return (mEnabled != 0);

}

—————————-AudioEffect::getEnabled————————————

}

——————————android_media_AudioEffect_native_getEnabled———————————-

    }

——————————–getEnabled——————————–

            } catch (IllegalStateException e) {

                result = true;

            }

        } catch (IllegalArgumentException e) {

            msg = msg.concat(": Equalizer not found");

        } catch (UnsupportedOperationException e) {

            msg = msg.concat(": Effect library not loaded");

        }

        assertTrue(msg, result);

    }

###########################################################

 

 

&&&&&&&&&&&&&&&&&&&&&&&總結&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

release時會刪除native中創建的AudioEffectJniStorage對象和AudioEffect對象。

getEnabled是根據EffectModule的狀態返回的。

release之後,再調用getEnabled函數,由於AudioEffect對象已被刪除,所以會產生異常。

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

摘自:江風的專欄

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *