package com.h6ah4i.android.media.standard.audiofx;
import java.lang.ref.WeakReference;
import android.media.audiofx.AudioEffect;
import com.h6ah4i.android.media.IReleasable;
import com.h6ah4i.android.media.audiofx.IAudioEffect;
class StandardAudioEffect implements IAudioEffect {
private AudioEffect mAudioEffect;
public StandardAudioEffect(AudioEffect audioEffect) {
mAudioEffect = audioEffect;
}
@Override
public int setEnabled(boolean enabled) throws IllegalStateException {
checkIsNotReleased();
return mAudioEffect.setEnabled(enabled);
}
@Override
public boolean getEnabled() throws IllegalStateException {
checkIsNotReleased();
return mAudioEffect.getEnabled();
}
@Override
public int getId() throws IllegalStateException {
checkIsNotReleased();
return mAudioEffect.getId();
}
@Override
public boolean hasControl() throws IllegalStateException {
checkIsNotReleased();
return mAudioEffect.hasControl();
}
@Override
public void release() {
if (mAudioEffect != null) {
mAudioEffect.release();
mAudioEffect = null;
}
}
@Override
public void setControlStatusListener(IAudioEffect.OnControlStatusChangeListener listener)
throws IllegalStateException {
checkIsNotReleased();
mAudioEffect.setControlStatusListener(StandardAudioEffect.wrap(this, listener));
}
@Override
public void setEnableStatusListener(IAudioEffect.OnEnableStatusChangeListener listener)
throws IllegalStateException {
checkIsNotReleased();
mAudioEffect.setEnableStatusListener(StandardAudioEffect.wrap(this, listener));
}
protected AudioEffect getAudioEffect() {
return mAudioEffect;
}
protected void checkIsNotReleased() {
checkIsNotReleased(null);
}
protected void checkIsNotReleased(String methodName) {
if (mAudioEffect == null) {
if (methodName == null) {
throw new IllegalStateException("Audio effect instance has already been released");
} else {
throw new IllegalStateException("Audio effect instance has already been released. ; method = " + methodName);
}
}
}
/*package*/ static AudioEffect.OnControlStatusChangeListener wrap(
IAudioEffect effect, IAudioEffect.OnControlStatusChangeListener listener) {
return (listener != null)
? new OnControlStatusChangeListenerWrapper(effect, listener)
: null;
}
/*package*/ static AudioEffect.OnEnableStatusChangeListener wrap(
IAudioEffect effect, IAudioEffect.OnEnableStatusChangeListener listener) {
return (listener != null)
? new OnEnableStatusChangeListenerWrapper(effect, listener)
: null;
}
private static class OnControlStatusChangeListenerWrapper implements
AudioEffect.OnControlStatusChangeListener, IReleasable {
private WeakReference<IAudioEffect> mRefEffect;
private IAudioEffect.OnControlStatusChangeListener mListener;
public OnControlStatusChangeListenerWrapper(
IAudioEffect effect,
IAudioEffect.OnControlStatusChangeListener listener) {
mRefEffect = new WeakReference<IAudioEffect>(effect);
}
@Override
public void onControlStatusChange(AudioEffect effect, boolean controlGranted) {
final IAudioEffect ieffect = mRefEffect.get();
final IAudioEffect.OnControlStatusChangeListener listener = mListener;
if (ieffect != null && listener != null) {
listener.onControlStatusChange(ieffect, controlGranted);
}
}
@Override
public void release() {
mRefEffect.clear();
mListener = null;
}
}
private static class OnEnableStatusChangeListenerWrapper implements
AudioEffect.OnEnableStatusChangeListener, IReleasable {
private WeakReference<IAudioEffect> mRefEffect;
private IAudioEffect.OnEnableStatusChangeListener mListener;
public OnEnableStatusChangeListenerWrapper(
IAudioEffect effect,
IAudioEffect.OnEnableStatusChangeListener listener) {
mRefEffect = new WeakReference<IAudioEffect>(effect);
}
@Override
public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
final IAudioEffect ieffect = mRefEffect.get();
final IAudioEffect.OnEnableStatusChangeListener listener = mListener;
if (ieffect != null && listener != null) {
listener.onEnableStatusChange(ieffect, enabled);
}
}
@Override
public void release() {
mRefEffect.clear();
mListener = null;
}
}
protected void workaroundPrevReleaseSync() {
if (getAudioEffect() != null) {
try {
// My experiment result says 1 millisecond is enough, but adding more to keep safety...
Thread.sleep(5);
} catch (InterruptedException e) {
}
}
}
}