diff options
Diffstat (limited to 'src/com/android/tv/AudioManagerHelper.java')
-rw-r--r-- | src/com/android/tv/AudioManagerHelper.java | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/com/android/tv/AudioManagerHelper.java b/src/com/android/tv/AudioManagerHelper.java new file mode 100644 index 00000000..4fca06ac --- /dev/null +++ b/src/com/android/tv/AudioManagerHelper.java @@ -0,0 +1,108 @@ +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(); + } +} |