Merge "VideoView: option for audio focus, support for AudioAttributes"

This commit is contained in:
TreeHugger Robot
2017-02-23 04:37:50 +00:00
committed by Android (Google) Code Review
7 changed files with 87 additions and 14 deletions

View File

@@ -20798,6 +20798,7 @@ package android.media {
field public static final int AUDIOFOCUS_LOSS = -1; // 0xffffffff
field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
field public static final int AUDIOFOCUS_NONE = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -50825,6 +50826,8 @@ package android.widget {
method public int resolveAdjustedSize(int, int);
method public void resume();
method public void seekTo(int);
method public void setAudioAttributes(android.media.AudioAttributes);
method public void setAudioFocusRequest(int);
method public void setMediaController(android.widget.MediaController);
method public void setOnCompletionListener(android.media.MediaPlayer.OnCompletionListener);
method public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener);

View File

@@ -22465,6 +22465,7 @@ package android.media {
field public static final int AUDIOFOCUS_LOSS = -1; // 0xffffffff
field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
field public static final int AUDIOFOCUS_NONE = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -54734,6 +54735,8 @@ package android.widget {
method public int resolveAdjustedSize(int, int);
method public void resume();
method public void seekTo(int);
method public void setAudioAttributes(android.media.AudioAttributes);
method public void setAudioFocusRequest(int);
method public void setMediaController(android.widget.MediaController);
method public void setOnCompletionListener(android.media.MediaPlayer.OnCompletionListener);
method public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener);

View File

@@ -20894,6 +20894,7 @@ package android.media {
field public static final int AUDIOFOCUS_LOSS = -1; // 0xffffffff
field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
field public static final int AUDIOFOCUS_NONE = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -51204,6 +51205,8 @@ package android.widget {
method public int resolveAdjustedSize(int, int);
method public void resume();
method public void seekTo(int);
method public void setAudioAttributes(android.media.AudioAttributes);
method public void setAudioFocusRequest(int);
method public void setMediaController(android.widget.MediaController);
method public void setOnCompletionListener(android.media.MediaPlayer.OnCompletionListener);
method public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener);

View File

@@ -16,11 +16,13 @@
package android.widget;
import android.annotation.NonNull;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.Cea708CaptionRenderer;
import android.media.ClosedCaptionRenderer;
@@ -67,6 +69,14 @@ import java.util.Vector;
* {@link android.app.Activity#onRestoreInstanceState}.<p>
* Also note that the audio session id (from {@link #getAudioSessionId}) may
* change from its previously returned value when the VideoView is restored.
* <p>
* By default, VideoView requests audio focus with {@link AudioManager#AUDIOFOCUS_GAIN}. Use
* {@link #setAudioFocusRequest(int)} to change this behavior.
* <p>
* The default {@link AudioAttributes} used during playback have a usage of
* {@link AudioAttributes#USAGE_MEDIA} and a content type of
* {@link AudioAttributes#CONTENT_TYPE_MOVIE}, use {@link #setAudioAttributes(AudioAttributes)} to
* modify them.
*/
public class VideoView extends SurfaceView
implements MediaPlayerControl, SubtitleController.Anchor {
@@ -113,6 +123,9 @@ public class VideoView extends SurfaceView
private boolean mCanPause;
private boolean mCanSeekBack;
private boolean mCanSeekForward;
private AudioManager mAudioManager;
private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
private AudioAttributes mAudioAttributes;
/** Subtitle rendering widget overlaid on top of the video. */
private RenderingWidget mSubtitleWidget;
@@ -138,6 +151,10 @@ public class VideoView extends SurfaceView
mVideoWidth = 0;
mVideoHeight = 0;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mAudioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
getHolder().addCallback(mSHCallback);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@@ -259,6 +276,41 @@ public class VideoView extends SurfaceView
invalidate();
}
/**
* Sets which type of audio focus will be requested during the playback, or configures playback
* to not request audio focus. Valid values for focus requests are
* {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
* {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
* {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
* {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
* requested when playback starts. You can for instance use this when playing a silent animation
* through this class, and you don't want to affect other audio applications playing in the
* background.
* @param focusGain the type of audio focus gain that will be requested, or
* {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during playback.
*/
public void setAudioFocusRequest(int focusGain) {
if (focusGain != AudioManager.AUDIOFOCUS_NONE
&& focusGain != AudioManager.AUDIOFOCUS_GAIN
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
}
mAudioFocusType = focusGain;
}
/**
* Sets the {@link AudioAttributes} to be used during the playback of the video.
* @param attributes non-null <code>AudioAttributes</code>.
*/
public void setAudioAttributes(@NonNull AudioAttributes attributes) {
if (attributes == null) {
throw new IllegalArgumentException("Illegal null AudioAttributes");
}
mAudioAttributes = attributes;
}
/**
* Adds an external subtitle source file (from the provided input stream.)
*
@@ -301,8 +353,7 @@ public class VideoView extends SurfaceView
mMediaPlayer = null;
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(null);
mAudioManager.abandonAudioFocus(null);
}
}
@@ -315,8 +366,10 @@ public class VideoView extends SurfaceView
// called start() previously
release(false);
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
// TODO this should have a focus listener
mAudioManager.requestAudioFocus(null, mAudioAttributes, mAudioFocusType, 0 /*flags*/);
}
try {
mMediaPlayer = new MediaPlayer();
@@ -345,7 +398,7 @@ public class VideoView extends SurfaceView
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setAudioAttributes(mAudioAttributes);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
@@ -482,6 +535,9 @@ public class VideoView extends SurfaceView
if (mOnCompletionListener != null) {
mOnCompletionListener.onCompletion(mMediaPlayer);
}
if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
mAudioManager.abandonAudioFocus(null);
}
}
};
@@ -644,8 +700,9 @@ public class VideoView extends SurfaceView
if (cleartargetstate) {
mTargetState = STATE_IDLE;
}
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(null);
if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
mAudioManager.abandonAudioFocus(null);
}
}
}

View File

@@ -1981,8 +1981,7 @@ public class AudioManager {
}
/**
* @hide
* Used to indicate no audio focus has been gained or lost.
* Used to indicate no audio focus has been gained or lost, or requested.
*/
public static final int AUDIOFOCUS_NONE = 0;

View File

@@ -366,11 +366,18 @@ public final class AudioPlaybackConfiguration implements Parcelable {
* @param pw
*/
public void dump(PrintWriter pw) {
pw.println(" ID:" + mPlayerIId
+ " -- type:" + toLogFriendlyPlayerType(mPlayerType)
+ " -- u/pid:" + mClientUid +"/" + mClientPid
+ " -- state:" + toLogFriendlyPlayerState(mPlayerState)
+ " -- attr:" + mPlayerAttr);
pw.println(" " + toLogFriendlyString(this));
}
/**
* @hide
*/
public static String toLogFriendlyString(AudioPlaybackConfiguration apc) {
return new String("ID:" + apc.mPlayerIId
+ " -- type:" + toLogFriendlyPlayerType(apc.mPlayerType)
+ " -- u/pid:" + apc.mClientUid +"/" + apc.mClientPid
+ " -- state:" + toLogFriendlyPlayerState(apc.mPlayerState)
+ " -- attr:" + apc.mPlayerAttr);
}
public static final Parcelable.Creator<AudioPlaybackConfiguration> CREATOR

View File

@@ -47,6 +47,7 @@ public final class PlaybackActivityMonitor
implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer {
public final static String TAG = "AudioService.PlaybackActivityMonitor";
private final static boolean DEBUG = false;
private final static int VOLUME_SHAPER_SYSTEM_DUCK_ID = 1;