blob: 4fca06acc65d764382692ce5e44184e93083aa52 [file] [log] [blame]
package com.android.tv;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import com.android.tv.receiver.AudioCapabilitiesReceiver;
import com.android.tv.ui.TunableTvView;
/**
* A helper class to help {@link MainActivity} to handle audio-related stuffs.
*/
class AudioManagerHelper implements AudioManager.OnAudioFocusChangeListener {
private static final float AUDIO_MAX_VOLUME = 1.0f;
private static final float AUDIO_MIN_VOLUME = 0.0f;
private static final float AUDIO_DUCKING_VOLUME = 0.3f;
private final Activity mActivity;
private final TunableTvView mTvView;
private final AudioManager mAudioManager;
private final AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
private boolean mAc3PassthroughSupported;
private int mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
AudioManagerHelper(Activity activity, TunableTvView tvView) {
mActivity = activity;
mTvView = tvView;
mAudioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(activity,
new AudioCapabilitiesReceiver.OnAc3PassthroughCapabilityChangeListener() {
@Override
public void onAc3PassthroughCapabilityChange(boolean capability) {
mAc3PassthroughSupported = capability;
}
});
mAudioCapabilitiesReceiver.register();
}
/**
* Sets suitable volume to {@link TunableTvView} according to the current audio focus.
* If the focus status is {@link AudioManager#AUDIOFOCUS_LOSS} and the activity is under PIP
* mode, this method will finish the activity.
*/
void setVolumeByAudioFocusStatus() {
if (mTvView.isPlaying()) {
switch (mAudioFocusStatus) {
case AudioManager.AUDIOFOCUS_GAIN:
mTvView.setStreamVolume(AUDIO_MAX_VOLUME);
break;
case AudioManager.AUDIOFOCUS_LOSS:
if (Features.PICTURE_IN_PICTURE.isEnabled(mActivity)
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& mActivity.isInPictureInPictureMode()) {
mActivity.finish();
break;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
mTvView.setStreamVolume(AUDIO_MIN_VOLUME);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mTvView.setStreamVolume(AUDIO_DUCKING_VOLUME);
break;
}
}
}
/**
* Tries to request audio focus from {@link AudioManager} and set volume according to the
* returned result.
*/
void requestAudioFocus() {
int result = mAudioManager.requestAudioFocus(this,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
mAudioFocusStatus = (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) ?
AudioManager.AUDIOFOCUS_GAIN : AudioManager.AUDIOFOCUS_LOSS;
setVolumeByAudioFocusStatus();
}
/**
* Abandons audio focus.
*/
void abandonAudioFocus() {
mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
mAudioManager.abandonAudioFocus(this);
}
/**
* Returns {@code true} if the device supports AC3 pass-through.
*/
boolean isAc3PassthroughSupported() {
return mAc3PassthroughSupported;
}
/**
* Release the resources the helper class may occupied.
*/
void release() {
mAudioCapabilitiesReceiver.unregister();
}
@Override
public void onAudioFocusChange(int focusChange) {
mAudioFocusStatus = focusChange;
setVolumeByAudioFocusStatus();
}
}