Android Audio程式碼分析22
阿新 • • 發佈:2019-02-14
今天來看看AudioEffect中enable相關的介面。
*****************************************原始碼*************************************************
**********************************************************************************************
原始碼路徑:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioEffectTest.java
#######################說明################################
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&總結&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
release時會刪除native中建立的AudioEffectJniStorage物件和AudioEffect物件。
getEnabled是根據EffectModule的狀態返回的。
release之後,再呼叫getEnabled函式,由於AudioEffect物件已被刪除,所以會產生異常。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
*****************************************原始碼*************************************************
//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物件已被刪除,所以會產生異常。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&